1 //
2 // Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // StateManager9.h: Defines a class for caching D3D9 state
8 
9 #ifndef LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_
10 #define LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_
11 
12 #include "libANGLE/angletypes.h"
13 #include "libANGLE/ContextState.h"
14 #include "libANGLE/State.h"
15 #include "libANGLE/renderer/d3d/RendererD3D.h"
16 
17 namespace rx
18 {
19 
20 class Renderer9;
21 
22 struct dx_VertexConstants9
23 {
24     float depthRange[4];
25     float viewAdjust[4];
26     float viewCoords[4];
27 };
28 
29 struct dx_PixelConstants9
30 {
31     float depthRange[4];
32     float viewCoords[4];
33     float depthFront[4];
34 };
35 
36 class StateManager9 final : angle::NonCopyable
37 {
38   public:
39     StateManager9(Renderer9 *renderer9);
40     ~StateManager9();
41 
42     void initialize();
43 
44     void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
45 
46     gl::Error setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask);
47     void setScissorState(const gl::Rectangle &scissor, bool enabled);
48     void setViewportState(const gl::Rectangle &viewport,
49                           float zNear,
50                           float zFar,
51                           GLenum drawMode,
52                           GLenum frontFace,
53                           bool ignoreViewport);
54 
55     void setShaderConstants();
56 
57     void forceSetBlendState();
58     void forceSetRasterState();
59     void forceSetDepthStencilState();
60     void forceSetScissorState();
61     void forceSetViewportState();
62     void forceSetDXUniformsState();
63 
64     void updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize);
65     void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
66 
67     void setRenderTargetBounds(size_t width, size_t height);
68 
getRenderTargetWidth()69     int getRenderTargetWidth() const { return mRenderTargetBounds.width; }
getRenderTargetHeight()70     int getRenderTargetHeight() const { return mRenderTargetBounds.height; }
71 
resetDirtyBits()72     void resetDirtyBits() { mDirtyBits.reset(); }
73 
74   private:
75     // Blend state functions
76     void setBlendEnabled(bool enabled);
77     void setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor);
78     void setBlendFuncsEquations(const gl::BlendState &blendState);
79     void setColorMask(const gl::Framebuffer *framebuffer,
80                       bool red,
81                       bool blue,
82                       bool green,
83                       bool alpha);
84     void setSampleAlphaToCoverage(bool enabled);
85     void setDither(bool dither);
86     void setSampleMask(unsigned int sampleMask);
87 
88     // Current raster state functions
89     void setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace);
90     void setDepthBias(bool polygonOffsetFill,
91                       GLfloat polygonOffsetFactor,
92                       GLfloat polygonOffsetUnits);
93 
94     // Depth stencil state functions
95     void setStencilOpsFront(GLenum stencilFail,
96                             GLenum stencilPassDepthFail,
97                             GLenum stencilPassDepthPass,
98                             bool frontFaceCCW);
99     void setStencilOpsBack(GLenum stencilBackFail,
100                            GLenum stencilBackPassDepthFail,
101                            GLenum stencilBackPassDepthPass,
102                            bool frontFaceCCW);
103     void setStencilBackWriteMask(GLuint stencilBackWriteMask, bool frontFaceCCW);
104     void setDepthFunc(bool depthTest, GLenum depthFunc);
105     void setStencilTestEnabled(bool enabled);
106     void setDepthMask(bool depthMask);
107     void setStencilFuncsFront(GLenum stencilFunc,
108                               GLuint stencilMask,
109                               GLint stencilRef,
110                               bool frontFaceCCW,
111                               unsigned int maxStencil);
112     void setStencilFuncsBack(GLenum stencilBackFunc,
113                              GLuint stencilBackMask,
114                              GLint stencilBackRef,
115                              bool frontFaceCCW,
116                              unsigned int maxStencil);
117     void setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW);
118 
119     void setScissorEnabled(bool scissorEnabled);
120     void setScissorRect(const gl::Rectangle &scissor, bool enabled);
121 
122     enum DirtyBitType
123     {
124         // Blend dirty bits
125         DIRTY_BIT_BLEND_ENABLED,
126         DIRTY_BIT_BLEND_COLOR,
127         DIRTY_BIT_BLEND_FUNCS_EQUATIONS,
128         DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE,
129         DIRTY_BIT_COLOR_MASK,
130         DIRTY_BIT_DITHER,
131         DIRTY_BIT_SAMPLE_MASK,
132 
133         // Rasterizer dirty bits
134         DIRTY_BIT_CULL_MODE,
135         DIRTY_BIT_DEPTH_BIAS,
136 
137         // Depth stencil dirty bits
138         DIRTY_BIT_STENCIL_DEPTH_MASK,
139         DIRTY_BIT_STENCIL_DEPTH_FUNC,
140         DIRTY_BIT_STENCIL_TEST_ENABLED,
141         DIRTY_BIT_STENCIL_FUNCS_FRONT,
142         DIRTY_BIT_STENCIL_FUNCS_BACK,
143         DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
144         DIRTY_BIT_STENCIL_WRITEMASK_BACK,
145         DIRTY_BIT_STENCIL_OPS_FRONT,
146         DIRTY_BIT_STENCIL_OPS_BACK,
147 
148         // Scissor dirty bits
149         DIRTY_BIT_SCISSOR_ENABLED,
150         DIRTY_BIT_SCISSOR_RECT,
151 
152         // Viewport dirty bits
153         DIRTY_BIT_VIEWPORT,
154 
155         DIRTY_BIT_MAX
156     };
157 
158     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
159 
160     bool mUsingZeroColorMaskWorkaround;
161 
162     // Currently applied blend state
163     gl::BlendState mCurBlendState;
164     gl::ColorF mCurBlendColor;
165     unsigned int mCurSampleMask;
166     DirtyBits mBlendStateDirtyBits;
167 
168     // Currently applied raster state
169     gl::RasterizerState mCurRasterState;
170     unsigned int mCurDepthSize;
171     DirtyBits mRasterizerStateDirtyBits;
172 
173     // Currently applied depth stencil state
174     gl::DepthStencilState mCurDepthStencilState;
175     int mCurStencilRef;
176     int mCurStencilBackRef;
177     bool mCurFrontFaceCCW;
178     unsigned int mCurStencilSize;
179     DirtyBits mDepthStencilStateDirtyBits;
180 
181     // Currently applied scissor states
182     gl::Rectangle mCurScissorRect;
183     bool mCurScissorEnabled;
184     gl::Extents mRenderTargetBounds;
185     DirtyBits mScissorStateDirtyBits;
186 
187     // Currently applied viewport states
188     bool mForceSetViewport;
189     gl::Rectangle mCurViewport;
190     float mCurNear;
191     float mCurFar;
192     float mCurDepthFront;
193     bool mCurIgnoreViewport;
194 
195     dx_VertexConstants9 mVertexConstants;
196     dx_PixelConstants9 mPixelConstants;
197     bool mDxUniformsDirty;
198 
199     // FIXME: Unsupported by D3D9
200     static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF       = D3DRS_STENCILREF;
201     static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK      = D3DRS_STENCILMASK;
202     static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK;
203 
204     Renderer9 *mRenderer9;
205     DirtyBits mDirtyBits;
206 };
207 
208 }  // namespace rx
209 #endif  // LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_
210