void StateManagerGL::setClearState(const gl::State &state, GLbitfield mask) { // Only apply the state required to do a clear setScissor(state.getScissor()); setViewport(state.getViewport()); if ((mask & GL_COLOR_BUFFER_BIT) != 0) { setClearColor(state.getColorClearValue()); const gl::BlendState &blendState = state.getBlendState(); setColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, blendState.colorMaskBlue, blendState.colorMaskAlpha); } if ((mask & GL_DEPTH_BUFFER_BIT) != 0) { setClearDepth(state.getDepthClearValue()); setDepthMask(state.getDepthStencilState().depthMask); } if ((mask & GL_STENCIL_BUFFER_BIT) != 0) { setClearStencil(state.getStencilClearValue()); setStencilMask(state.getDepthStencilState().stencilMask); } }
gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask) { const gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); const gl::BlendState &blendState = glState.getBlendState(); const gl::ColorF &blendColor = glState.getBlendColor(); const gl::RasterizerState &rasterState = glState.getRasterizerState(); const auto &depthStencilState = glState.getDepthStencilState(); bool frontFaceCCW = (glState.getRasterizerState().frontFace == GL_CCW); unsigned int maxStencil = (1 << mCurStencilSize) - 1; // All the depth stencil states depends on the front face ccw variable if (frontFaceCCW != mCurFrontFaceCCW) { forceSetDepthStencilState(); mCurFrontFaceCCW = frontFaceCCW; } for (auto dirtyBit : angle::IterateBitSet(mDirtyBits)) { switch (dirtyBit) { case DIRTY_BIT_BLEND_ENABLED: setBlendEnabled(blendState.blend); break; case DIRTY_BIT_BLEND_COLOR: setBlendColor(blendState, blendColor); break; case DIRTY_BIT_BLEND_FUNCS_EQUATIONS: setBlendFuncsEquations(blendState); break; case DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(blendState.sampleAlphaToCoverage); break; case DIRTY_BIT_COLOR_MASK: setColorMask(framebuffer, blendState.colorMaskRed, blendState.colorMaskBlue, blendState.colorMaskGreen, blendState.colorMaskAlpha); break; case DIRTY_BIT_DITHER: setDither(blendState.dither); break; case DIRTY_BIT_CULL_MODE: setCullMode(rasterState.cullFace, rasterState.cullMode, rasterState.frontFace); break; case DIRTY_BIT_DEPTH_BIAS: setDepthBias(rasterState.polygonOffsetFill, rasterState.polygonOffsetFactor, rasterState.polygonOffsetUnits); break; case DIRTY_BIT_STENCIL_DEPTH_MASK: setDepthMask(depthStencilState.depthMask); break; case DIRTY_BIT_STENCIL_DEPTH_FUNC: setDepthFunc(depthStencilState.depthTest, depthStencilState.depthFunc); break; case DIRTY_BIT_STENCIL_TEST_ENABLED: setStencilTestEnabled(depthStencilState.stencilTest); break; case DIRTY_BIT_STENCIL_FUNCS_FRONT: setStencilFuncsFront(depthStencilState.stencilFunc, depthStencilState.stencilMask, glState.getStencilRef(), frontFaceCCW, maxStencil); break; case DIRTY_BIT_STENCIL_FUNCS_BACK: setStencilFuncsBack(depthStencilState.stencilBackFunc, depthStencilState.stencilBackMask, glState.getStencilBackRef(), frontFaceCCW, maxStencil); break; case DIRTY_BIT_STENCIL_WRITEMASK_FRONT: setStencilWriteMask(depthStencilState.stencilWritemask, frontFaceCCW); break; case DIRTY_BIT_STENCIL_WRITEMASK_BACK: setStencilBackWriteMask(depthStencilState.stencilBackWritemask, frontFaceCCW); break; case DIRTY_BIT_STENCIL_OPS_FRONT: setStencilOpsFront(depthStencilState.stencilFail, depthStencilState.stencilPassDepthFail, depthStencilState.stencilPassDepthPass, frontFaceCCW); break; case DIRTY_BIT_STENCIL_OPS_BACK: setStencilOpsBack(depthStencilState.stencilBackFail, depthStencilState.stencilBackPassDepthFail, depthStencilState.stencilBackPassDepthPass, frontFaceCCW); break; default: break; } } if (sampleMask != mCurSampleMask) { setSampleMask(sampleMask); } return gl::Error(GL_NO_ERROR); }
void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) { for (auto dirtyBit : angle::IterateBitSet(dirtyBits)) { switch (dirtyBit) { case gl::State::DIRTY_BIT_BLEND_ENABLED: if (state.getBlendState().blend != mCurBlendState.blend) { mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); // BlendColor and funcs and equations has to be set if blend is enabled mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); } break; case gl::State::DIRTY_BIT_BLEND_FUNCS: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.sourceBlendRGB != mCurBlendState.sourceBlendRGB || blendState.destBlendRGB != mCurBlendState.destBlendRGB || blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha || blendState.destBlendAlpha != mCurBlendState.destBlendAlpha) { mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); // BlendColor depends on the values of blend funcs mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); } break; } case gl::State::DIRTY_BIT_BLEND_EQUATIONS: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB || blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) { mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); } break; } case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: if (state.getBlendState().sampleAlphaToCoverage != mCurBlendState.sampleAlphaToCoverage) { mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE); } break; case gl::State::DIRTY_BIT_COLOR_MASK: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.colorMaskRed != mCurBlendState.colorMaskRed || blendState.colorMaskGreen != mCurBlendState.colorMaskGreen || blendState.colorMaskBlue != mCurBlendState.colorMaskBlue || blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha) { mDirtyBits.set(DIRTY_BIT_COLOR_MASK); } break; } case gl::State::DIRTY_BIT_DITHER_ENABLED: if (state.getBlendState().dither != mCurBlendState.dither) { mDirtyBits.set(DIRTY_BIT_DITHER); } break; case gl::State::DIRTY_BIT_BLEND_COLOR: if (state.getBlendColor() != mCurBlendColor) { mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); } break; case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) { mDirtyBits.set(DIRTY_BIT_CULL_MODE); } break; case gl::State::DIRTY_BIT_CULL_FACE: if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) { mDirtyBits.set(DIRTY_BIT_CULL_MODE); } break; case gl::State::DIRTY_BIT_FRONT_FACE: if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) { mDirtyBits.set(DIRTY_BIT_CULL_MODE); // Viewport state depends on rasterizer.frontface mDirtyBits.set(DIRTY_BIT_VIEWPORT); } break; case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: if (state.getRasterizerState().polygonOffsetFill != mCurRasterState.polygonOffsetFill) { mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); } break; case gl::State::DIRTY_BIT_POLYGON_OFFSET: { const gl::RasterizerState &rasterizerState = state.getRasterizerState(); if (rasterizerState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor || rasterizerState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits) { mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); } } case gl::State::DIRTY_BIT_DEPTH_MASK: if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask) { mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_MASK); } break; case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest) { mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); } break; case gl::State::DIRTY_BIT_DEPTH_FUNC: if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc) { mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); } break; case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest) { mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED); // If we enable the stencil test, all of these must be set mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); } break; case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: { const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); if (depthStencilState.stencilFunc != mCurDepthStencilState.stencilFunc || depthStencilState.stencilMask != mCurDepthStencilState.stencilMask || state.getStencilRef() != mCurStencilRef) { mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); } break; } case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: { const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); if (depthStencilState.stencilBackFunc != mCurDepthStencilState.stencilBackFunc || depthStencilState.stencilBackMask != mCurDepthStencilState.stencilBackMask || state.getStencilBackRef() != mCurStencilBackRef) { mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); } break; } case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: if (state.getDepthStencilState().stencilWritemask != mCurDepthStencilState.stencilWritemask) { mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); } break; case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: if (state.getDepthStencilState().stencilBackWritemask != mCurDepthStencilState.stencilBackWritemask) { mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); } break; case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: { const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); if (depthStencilState.stencilFail != mCurDepthStencilState.stencilFail || depthStencilState.stencilPassDepthFail != mCurDepthStencilState.stencilPassDepthFail || depthStencilState.stencilPassDepthPass != mCurDepthStencilState.stencilPassDepthPass) { mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); } break; } case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: { const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); if (depthStencilState.stencilBackFail != mCurDepthStencilState.stencilBackFail || depthStencilState.stencilBackPassDepthFail != mCurDepthStencilState.stencilBackPassDepthFail || depthStencilState.stencilBackPassDepthPass != mCurDepthStencilState.stencilBackPassDepthPass) { mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); } break; } case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: if (state.isScissorTestEnabled() != mCurScissorEnabled) { mDirtyBits.set(DIRTY_BIT_SCISSOR_ENABLED); // If scissor is enabled, we have to set the scissor rect mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT); } break; case gl::State::DIRTY_BIT_SCISSOR: if (state.getScissor() != mCurScissorRect) { mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT); } break; case gl::State::DIRTY_BIT_DEPTH_RANGE: if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar) { mDirtyBits.set(DIRTY_BIT_VIEWPORT); } break; case gl::State::DIRTY_BIT_VIEWPORT: if (state.getViewport() != mCurViewport) { mDirtyBits.set(DIRTY_BIT_VIEWPORT); } break; default: break; } } }
void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) { // TODO(jmadill): Investigate only syncing vertex state for active attributes for (auto dirtyBit : angle::IterateBitSet(dirtyBits | mLocalDirtyBits)) { switch (dirtyBit) { case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: setScissorTestEnabled(state.isScissorTestEnabled()); break; case gl::State::DIRTY_BIT_SCISSOR: setScissor(state.getScissor()); break; case gl::State::DIRTY_BIT_VIEWPORT: setViewport(state.getViewport()); break; case gl::State::DIRTY_BIT_DEPTH_RANGE: setDepthRange(state.getNearPlane(), state.getFarPlane()); break; case gl::State::DIRTY_BIT_BLEND_ENABLED: setBlendEnabled(state.isBlendEnabled()); break; case gl::State::DIRTY_BIT_BLEND_COLOR: setBlendColor(state.getBlendColor()); break; case gl::State::DIRTY_BIT_BLEND_FUNCS: { const auto &blendState = state.getBlendState(); setBlendFuncs(blendState.sourceBlendRGB, blendState.destBlendRGB, blendState.sourceBlendAlpha, blendState.destBlendAlpha); break; } case gl::State::DIRTY_BIT_BLEND_EQUATIONS: { const auto &blendState = state.getBlendState(); setBlendEquations(blendState.blendEquationRGB, blendState.blendEquationAlpha); break; } case gl::State::DIRTY_BIT_COLOR_MASK: { const auto &blendState = state.getBlendState(); setColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, blendState.colorMaskBlue, blendState.colorMaskAlpha); break; } case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: setSampleAlphaToCoverageEnabled(state.isSampleAlphaToCoverageEnabled()); break; case gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED: setSampleCoverageEnabled(state.isSampleCoverageEnabled()); break; case gl::State::DIRTY_BIT_SAMPLE_COVERAGE: setSampleCoverage(state.getSampleCoverageValue(), state.getSampleCoverageInvert()); break; case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: setDepthTestEnabled(state.isDepthTestEnabled()); break; case gl::State::DIRTY_BIT_DEPTH_FUNC: setDepthFunc(state.getDepthStencilState().depthFunc); break; case gl::State::DIRTY_BIT_DEPTH_MASK: setDepthMask(state.getDepthStencilState().depthMask); break; case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: setStencilTestEnabled(state.isStencilTestEnabled()); break; case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: { const auto &depthStencilState = state.getDepthStencilState(); setStencilFrontFuncs(depthStencilState.stencilFunc, state.getStencilRef(), depthStencilState.stencilMask); break; } case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: { const auto &depthStencilState = state.getDepthStencilState(); setStencilBackFuncs(depthStencilState.stencilBackFunc, state.getStencilBackRef(), depthStencilState.stencilBackMask); break; } case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: { const auto &depthStencilState = state.getDepthStencilState(); setStencilFrontOps(depthStencilState.stencilFail, depthStencilState.stencilPassDepthFail, depthStencilState.stencilPassDepthPass); break; } case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: { const auto &depthStencilState = state.getDepthStencilState(); setStencilBackOps(depthStencilState.stencilBackFail, depthStencilState.stencilBackPassDepthFail, depthStencilState.stencilBackPassDepthPass); break; } case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask); break; case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask); break; case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: setCullFaceEnabled(state.isCullFaceEnabled()); break; case gl::State::DIRTY_BIT_CULL_FACE: setCullFace(state.getRasterizerState().cullMode); break; case gl::State::DIRTY_BIT_FRONT_FACE: setFrontFace(state.getRasterizerState().frontFace); break; case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: setPolygonOffsetFillEnabled(state.isPolygonOffsetFillEnabled()); break; case gl::State::DIRTY_BIT_POLYGON_OFFSET: { const auto &rasterizerState = state.getRasterizerState(); setPolygonOffset(rasterizerState.polygonOffsetFactor, rasterizerState.polygonOffsetUnits); break; } case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED: setRasterizerDiscardEnabled(state.isRasterizerDiscardEnabled()); break; case gl::State::DIRTY_BIT_LINE_WIDTH: setLineWidth(state.getLineWidth()); break; case gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED: setPrimitiveRestartEnabled(state.isPrimitiveRestartEnabled()); break; case gl::State::DIRTY_BIT_CLEAR_COLOR: setClearColor(state.getColorClearValue()); break; case gl::State::DIRTY_BIT_CLEAR_DEPTH: setClearDepth(state.getDepthClearValue()); break; case gl::State::DIRTY_BIT_CLEAR_STENCIL: setClearStencil(state.getStencilClearValue()); break; case gl::State::DIRTY_BIT_UNPACK_ALIGNMENT: // TODO(jmadill): split this setPixelUnpackState(state.getUnpackState()); break; case gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH: // TODO(jmadill): split this setPixelUnpackState(state.getUnpackState()); break; case gl::State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT: // TODO(jmadill): split this setPixelUnpackState(state.getUnpackState()); break; case gl::State::DIRTY_BIT_UNPACK_SKIP_IMAGES: // TODO(jmadill): split this setPixelUnpackState(state.getUnpackState()); break; case gl::State::DIRTY_BIT_UNPACK_SKIP_ROWS: // TODO(jmadill): split this setPixelUnpackState(state.getUnpackState()); break; case gl::State::DIRTY_BIT_UNPACK_SKIP_PIXELS: // TODO(jmadill): split this setPixelUnpackState(state.getUnpackState()); break; case gl::State::DIRTY_BIT_PACK_ALIGNMENT: // TODO(jmadill): split this setPixelPackState(state.getPackState()); break; case gl::State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER: // TODO(jmadill): split this setPixelPackState(state.getPackState()); break; case gl::State::DIRTY_BIT_PACK_ROW_LENGTH: // TODO(jmadill): split this setPixelPackState(state.getPackState()); break; case gl::State::DIRTY_BIT_PACK_SKIP_ROWS: // TODO(jmadill): split this setPixelPackState(state.getPackState()); break; case gl::State::DIRTY_BIT_PACK_SKIP_PIXELS: // TODO(jmadill): split this setPixelPackState(state.getPackState()); break; case gl::State::DIRTY_BIT_DITHER_ENABLED: // TODO(jmadill): implement this break; case gl::State::DIRTY_BIT_GENERATE_MIPMAP_HINT: // TODO(jmadill): implement this break; case gl::State::DIRTY_BIT_SHADER_DERIVATIVE_HINT: // TODO(jmadill): implement this break; case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING: // TODO(jmadill): implement this break; case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_OBJECT: // TODO(jmadill): implement this break; case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING: // TODO(jmadill): implement this break; case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_OBJECT: // TODO(jmadill): implement this break; case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING: // TODO(jmadill): implement this break; case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING: // TODO(jmadill): implement this break; case gl::State::DIRTY_BIT_VERTEX_ARRAY_OBJECT: state.getVertexArray()->syncImplState(); break; case gl::State::DIRTY_BIT_PROGRAM_BINDING: // TODO(jmadill): implement this break; case gl::State::DIRTY_BIT_PROGRAM_OBJECT: // TODO(jmadill): implement this break; default: { ASSERT(dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 && dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX); size_t attribIndex = static_cast<size_t>(dirtyBit) - gl::State::DIRTY_BIT_CURRENT_VALUE_0; setAttributeCurrentData(attribIndex, state.getVertexAttribCurrentValue( static_cast<unsigned int>(attribIndex))); break; } } mLocalDirtyBits.reset(); } }
gl::Error StateManager11::setDepthStencilState(const gl::State &glState) { const auto &fbo = *glState.getDrawFramebuffer(); // Disable the depth test/depth write if we are using a stencil-only attachment. // This is because ANGLE emulates stencil-only with D24S8 on D3D11 - we should neither read // nor write to the unused depth part of this emulated texture. bool disableDepth = (!fbo.hasDepth() && fbo.hasStencil()); // Similarly we disable the stencil portion of the DS attachment if the app only binds depth. bool disableStencil = (fbo.hasDepth() && !fbo.hasStencil()); // CurDisableDepth/Stencil are reset automatically after we call forceSetDepthStencilState. if (!mDepthStencilStateIsDirty && mCurDisableDepth.valid() && disableDepth == mCurDisableDepth.value() && mCurDisableStencil.valid() && disableStencil == mCurDisableStencil.value()) { return gl::Error(GL_NO_ERROR); } const auto &depthStencilState = glState.getDepthStencilState(); int stencilRef = glState.getStencilRef(); int stencilBackRef = glState.getStencilBackRef(); // get the maximum size of the stencil ref unsigned int maxStencil = 0; if (depthStencilState.stencilTest && mCurStencilSize > 0) { maxStencil = (1 << mCurStencilSize) - 1; } ASSERT((depthStencilState.stencilWritemask & maxStencil) == (depthStencilState.stencilBackWritemask & maxStencil)); ASSERT(stencilRef == stencilBackRef); ASSERT((depthStencilState.stencilMask & maxStencil) == (depthStencilState.stencilBackMask & maxStencil)); ID3D11DepthStencilState *dxDepthStencilState = NULL; gl::Error error = mRenderer->getStateCache().getDepthStencilState( depthStencilState, disableDepth, disableStencil, &dxDepthStencilState); if (error.isError()) { return error; } ASSERT(dxDepthStencilState); // Max D3D11 stencil reference value is 0xFF, // corresponding to the max 8 bits in a stencil buffer // GL specifies we should clamp the ref value to the // nearest bit depth when doing stencil ops static_assert(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF, "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK"); static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF, "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK"); UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu); mRenderer->getDeviceContext()->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef); mCurDepthStencilState = depthStencilState; mCurStencilRef = stencilRef; mCurStencilBackRef = stencilBackRef; mCurDisableDepth = disableDepth; mCurDisableStencil = disableStencil; mDepthStencilStateIsDirty = false; return gl::Error(GL_NO_ERROR); }
void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) { if (!dirtyBits.any()) { return; } for (auto dirtyBit : angle::IterateBitSet(dirtyBits)) { switch (dirtyBit) { case gl::State::DIRTY_BIT_BLEND_EQUATIONS: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB || blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) { mBlendStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_BLEND_FUNCS: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.sourceBlendRGB != mCurBlendState.sourceBlendRGB || blendState.destBlendRGB != mCurBlendState.destBlendRGB || blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha || blendState.destBlendAlpha != mCurBlendState.destBlendAlpha) { mBlendStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_BLEND_ENABLED: if (state.getBlendState().blend != mCurBlendState.blend) { mBlendStateIsDirty = true; } break; case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: if (state.getBlendState().sampleAlphaToCoverage != mCurBlendState.sampleAlphaToCoverage) { mBlendStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DITHER_ENABLED: if (state.getBlendState().dither != mCurBlendState.dither) { mBlendStateIsDirty = true; } break; case gl::State::DIRTY_BIT_COLOR_MASK: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.colorMaskRed != mCurBlendState.colorMaskRed || blendState.colorMaskGreen != mCurBlendState.colorMaskGreen || blendState.colorMaskBlue != mCurBlendState.colorMaskBlue || blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha) { mBlendStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_BLEND_COLOR: if (state.getBlendColor() != mCurBlendColor) { mBlendStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DEPTH_MASK: if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DEPTH_FUNC: if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: { const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); if (depthStencil.stencilFunc != mCurDepthStencilState.stencilFunc || depthStencil.stencilMask != mCurDepthStencilState.stencilMask || state.getStencilRef() != mCurStencilRef) { mDepthStencilStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: { const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); if (depthStencil.stencilBackFunc != mCurDepthStencilState.stencilBackFunc || depthStencil.stencilBackMask != mCurDepthStencilState.stencilBackMask || state.getStencilBackRef() != mCurStencilBackRef) { mDepthStencilStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: if (state.getDepthStencilState().stencilWritemask != mCurDepthStencilState.stencilWritemask) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: if (state.getDepthStencilState().stencilBackWritemask != mCurDepthStencilState.stencilBackWritemask) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: { const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); if (depthStencil.stencilFail != mCurDepthStencilState.stencilFail || depthStencil.stencilPassDepthFail != mCurDepthStencilState.stencilPassDepthFail || depthStencil.stencilPassDepthPass != mCurDepthStencilState.stencilPassDepthPass) { mDepthStencilStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: { const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); if (depthStencil.stencilBackFail != mCurDepthStencilState.stencilBackFail || depthStencil.stencilBackPassDepthFail != mCurDepthStencilState.stencilBackPassDepthFail || depthStencil.stencilBackPassDepthPass != mCurDepthStencilState.stencilBackPassDepthPass) { mDepthStencilStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) { mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_CULL_FACE: if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) { mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_FRONT_FACE: if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) { mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: if (state.getRasterizerState().polygonOffsetFill != mCurRasterState.polygonOffsetFill) { mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_POLYGON_OFFSET: { const gl::RasterizerState &rasterState = state.getRasterizerState(); if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor || rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits) { mRasterizerStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED: if (state.getRasterizerState().rasterizerDiscard != mCurRasterState.rasterizerDiscard) { mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_SCISSOR: if (state.getScissor() != mCurScissorRect) { mScissorStateIsDirty = true; } break; case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: if (state.isScissorTestEnabled() != mCurScissorEnabled) { mScissorStateIsDirty = true; // Rasterizer state update needs mCurScissorsEnabled and updates when it changes mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DEPTH_RANGE: if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar) { mViewportStateIsDirty = true; } break; case gl::State::DIRTY_BIT_VIEWPORT: if (state.getViewport() != mCurViewport) { mViewportStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING: mRenderTargetIsDirty = true; break; default: if (dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 && dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX) { size_t attribIndex = static_cast<size_t>(dirtyBit - gl::State::DIRTY_BIT_CURRENT_VALUE_0); mDirtyCurrentValueAttribs.set(attribIndex); } break; } } }