summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h
blob: 1c99413ecd6fac49f7d1789c14aed5a83a11d368 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//
// Copyright 2002 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Blit9.cpp: Surface copy utility class.

#ifndef LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_
#define LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_

#include "common/PackedEnums.h"
#include "common/angleutils.h"
#include "libANGLE/Error.h"

namespace gl
{
class Context;
class Framebuffer;
class Texture;
struct Extents;
struct Offset;
}  // namespace gl

namespace rx
{
class Context9;
class Renderer9;
class TextureStorage;

namespace d3d
{
class Context;
}  // namespace d3d

class Blit9 : angle::NonCopyable
{
  public:
    explicit Blit9(Renderer9 *renderer);
    ~Blit9();

    angle::Result initialize(Context9 *context9);

    // Copy from source surface to dest surface.
    // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
    angle::Result copy2D(const gl::Context *context,
                         const gl::Framebuffer *framebuffer,
                         const RECT &sourceRect,
                         GLenum destFormat,
                         const gl::Offset &destOffset,
                         TextureStorage *storage,
                         GLint level);
    angle::Result copyCube(const gl::Context *context,
                           const gl::Framebuffer *framebuffer,
                           const RECT &sourceRect,
                           GLenum destFormat,
                           const gl::Offset &destOffset,
                           TextureStorage *storage,
                           gl::TextureTarget target,
                           GLint level);
    angle::Result copyTexture(const gl::Context *context,
                              const gl::Texture *source,
                              GLint sourceLevel,
                              const RECT &sourceRect,
                              GLenum destFormat,
                              const gl::Offset &destOffset,
                              TextureStorage *storage,
                              gl::TextureTarget destTarget,
                              GLint destLevel,
                              bool flipY,
                              bool premultiplyAlpha,
                              bool unmultiplyAlpha);

    // 2x2 box filter sample from source to dest.
    // Requires that source is RGB(A) and dest has the same format as source.
    angle::Result boxFilter(Context9 *context9, IDirect3DSurface9 *source, IDirect3DSurface9 *dest);

  private:
    Renderer9 *mRenderer;

    bool mGeometryLoaded;
    IDirect3DVertexBuffer9 *mQuadVertexBuffer;
    IDirect3DVertexDeclaration9 *mQuadVertexDeclaration;

    // Copy from source texture to dest surface.
    // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
    // source is interpreted as RGBA and destFormat specifies the desired result format. For
    // example, if destFormat = GL_RGB, the alpha channel will be forced to 0.
    angle::Result formatConvert(Context9 *context9,
                                IDirect3DBaseTexture9 *source,
                                const RECT &sourceRect,
                                const gl::Extents &sourceSize,
                                GLenum destFormat,
                                const gl::Offset &destOffset,
                                IDirect3DSurface9 *dest,
                                bool flipY,
                                bool premultiplyAlpha,
                                bool unmultiplyAlpha);
    angle::Result setFormatConvertShaders(Context9 *context9,
                                          GLenum destFormat,
                                          bool flipY,
                                          bool premultiplyAlpha,
                                          bool unmultiplyAlpha);

    angle::Result copy(Context9 *context9,
                       IDirect3DSurface9 *source,
                       IDirect3DBaseTexture9 *sourceTexture,
                       const RECT &sourceRect,
                       GLenum destFormat,
                       const gl::Offset &destOffset,
                       IDirect3DSurface9 *dest,
                       bool flipY,
                       bool premultiplyAlpha,
                       bool unmultiplyAlpha);
    angle::Result copySurfaceToTexture(Context9 *context9,
                                       IDirect3DSurface9 *surface,
                                       const RECT &sourceRect,
                                       angle::ComPtr<IDirect3DBaseTexture9> *outTexture);
    void setViewportAndShaderConstants(const RECT &sourceRect,
                                       const gl::Extents &sourceSize,
                                       const RECT &destRect,
                                       bool flipY);
    void setCommonBlitState();
    RECT getSurfaceRect(IDirect3DSurface9 *surface) const;
    gl::Extents getSurfaceSize(IDirect3DSurface9 *surface) const;

    // This enum is used to index mCompiledShaders and mShaderSource.
    enum ShaderId
    {
        SHADER_VS_STANDARD,
        SHADER_PS_PASSTHROUGH,
        SHADER_PS_LUMINANCE,
        SHADER_PS_LUMINANCE_PREMULTIPLY_ALPHA,
        SHADER_PS_LUMINANCE_UNMULTIPLY_ALPHA,
        SHADER_PS_COMPONENTMASK,
        SHADER_PS_COMPONENTMASK_PREMULTIPLY_ALPHA,
        SHADER_PS_COMPONENTMASK_UNMULTIPLY_ALPHA,
        SHADER_COUNT,
    };

    // This actually contains IDirect3DVertexShader9 or IDirect3DPixelShader9 casted to IUnknown.
    IUnknown *mCompiledShaders[SHADER_COUNT];

    template <class D3DShaderType>
    angle::Result setShader(Context9 *,
                            ShaderId source,
                            const char *profile,
                            angle::Result (Renderer9::*createShader)(d3d::Context *context,
                                                                     const DWORD *,
                                                                     size_t length,
                                                                     D3DShaderType **outShader),
                            HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType *));

    angle::Result setVertexShader(Context9 *context9, ShaderId shader);
    angle::Result setPixelShader(Context9 *context9, ShaderId shader);
    void render();

    void saveState();
    void restoreState();
    IDirect3DStateBlock9 *mSavedStateBlock;
    IDirect3DSurface9 *mSavedRenderTarget;
    IDirect3DSurface9 *mSavedDepthStencil;
};
}  // namespace rx

#endif  // LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_