Commit 6dd06eac by Jamie Madill Committed by Commit Bot

Give StateManager11 internal dirty bits.

Intead of checking a series of bools and special variables, organize the state application into a switch with internal dirty bits. This should be faster for no-op, and makes it clear where we have to further optimize the state update to pre-compute certain values. BUG=angleproject:1156 Change-Id: I8eca8716340499085afa170ff45f7788e84fecab Reviewed-on: https://chromium-review.googlesource.com/531794 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 298a35f0
...@@ -622,6 +622,11 @@ const FramebufferAttachment *Framebuffer::getFirstColorbuffer() const ...@@ -622,6 +622,11 @@ const FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
return mState.getFirstColorAttachment(); return mState.getFirstColorAttachment();
} }
const FramebufferAttachment *Framebuffer::getFirstNonNullAttachment() const
{
return mState.getFirstNonNullAttachment();
}
const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
{ {
return mState.getAttachment(attachment); return mState.getAttachment(attachment);
......
...@@ -162,6 +162,7 @@ class Framebuffer final : public LabeledObject, public OnAttachmentDirtyReceiver ...@@ -162,6 +162,7 @@ class Framebuffer final : public LabeledObject, public OnAttachmentDirtyReceiver
const FramebufferAttachment *getReadColorbuffer() const; const FramebufferAttachment *getReadColorbuffer() const;
GLenum getReadColorbufferType() const; GLenum getReadColorbufferType() const;
const FramebufferAttachment *getFirstColorbuffer() const; const FramebufferAttachment *getFirstColorbuffer() const;
const FramebufferAttachment *getFirstNonNullAttachment() const;
const FramebufferAttachment *getAttachment(GLenum attachment) const; const FramebufferAttachment *getAttachment(GLenum attachment) const;
......
...@@ -142,25 +142,20 @@ static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED ...@@ -142,25 +142,20 @@ static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED
StateManager11::StateManager11(Renderer11 *renderer) StateManager11::StateManager11(Renderer11 *renderer)
: mRenderer(renderer), : mRenderer(renderer),
mBlendStateIsDirty(false), mInternalDirtyBits(),
mCurBlendColor(0, 0, 0, 0), mCurBlendColor(0, 0, 0, 0),
mCurSampleMask(0), mCurSampleMask(0),
mDepthStencilStateIsDirty(false),
mCurStencilRef(0), mCurStencilRef(0),
mCurStencilBackRef(0), mCurStencilBackRef(0),
mCurStencilSize(0), mCurStencilSize(0),
mRasterizerStateIsDirty(false),
mScissorStateIsDirty(false),
mCurScissorEnabled(false), mCurScissorEnabled(false),
mCurScissorRect(), mCurScissorRect(),
mViewportStateIsDirty(false),
mCurViewport(), mCurViewport(),
mCurNear(0.0f), mCurNear(0.0f),
mCurFar(0.0f), mCurFar(0.0f),
mViewportBounds(), mViewportBounds(),
mCurPresentPathFastEnabled(false), mCurPresentPathFastEnabled(false),
mCurPresentPathFastColorBufferHeight(0), mCurPresentPathFastColorBufferHeight(0),
mRenderTargetIsDirty(false),
mDirtyCurrentValueAttribs(), mDirtyCurrentValueAttribs(),
mCurrentValueAttribs(), mCurrentValueAttribs(),
mCurrentInputLayout(), mCurrentInputLayout(),
...@@ -223,18 +218,8 @@ void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized, ...@@ -223,18 +218,8 @@ void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
{ {
if (!depthStencilInitialized || stencilSize != mCurStencilSize) if (!depthStencilInitialized || stencilSize != mCurStencilSize)
{ {
mCurStencilSize = stencilSize; mCurStencilSize = stencilSize;
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
}
}
void StateManager11::setViewportBounds(const int width, const int height)
{
if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 &&
(mViewportBounds.width != width || mViewportBounds.height != height))
{
mViewportBounds = gl::Extents(width, height, 1);
mViewportStateIsDirty = true;
} }
} }
...@@ -254,9 +239,15 @@ void StateManager11::checkPresentPath(const gl::Context *context) ...@@ -254,9 +239,15 @@ void StateManager11::checkPresentPath(const gl::Context *context)
{ {
mCurPresentPathFastEnabled = presentPathFastActive; mCurPresentPathFastEnabled = presentPathFastActive;
mCurPresentPathFastColorBufferHeight = colorBufferHeight; mCurPresentPathFastColorBufferHeight = colorBufferHeight;
mViewportStateIsDirty = true; // Viewport may need to be vertically inverted
mScissorStateIsDirty = true; // Scissor rect may need to be vertically inverted // Scissor rect may need to be vertically inverted
mRasterizerStateIsDirty = true; // Cull Mode may need to be inverted mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
// Cull Mode may need to be inverted
mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
// Viewport may need to be vertically inverted
mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
} }
} }
...@@ -286,7 +277,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -286,7 +277,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB || if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB ||
blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha)
{ {
mBlendStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
} }
break; break;
} }
...@@ -298,27 +289,27 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -298,27 +289,27 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha || blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha ||
blendState.destBlendAlpha != mCurBlendState.destBlendAlpha) blendState.destBlendAlpha != mCurBlendState.destBlendAlpha)
{ {
mBlendStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
} }
break; break;
} }
case gl::State::DIRTY_BIT_BLEND_ENABLED: case gl::State::DIRTY_BIT_BLEND_ENABLED:
if (state.getBlendState().blend != mCurBlendState.blend) if (state.getBlendState().blend != mCurBlendState.blend)
{ {
mBlendStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
if (state.getBlendState().sampleAlphaToCoverage != if (state.getBlendState().sampleAlphaToCoverage !=
mCurBlendState.sampleAlphaToCoverage) mCurBlendState.sampleAlphaToCoverage)
{ {
mBlendStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_DITHER_ENABLED: case gl::State::DIRTY_BIT_DITHER_ENABLED:
if (state.getBlendState().dither != mCurBlendState.dither) if (state.getBlendState().dither != mCurBlendState.dither)
{ {
mBlendStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_COLOR_MASK: case gl::State::DIRTY_BIT_COLOR_MASK:
...@@ -329,38 +320,38 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -329,38 +320,38 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
blendState.colorMaskBlue != mCurBlendState.colorMaskBlue || blendState.colorMaskBlue != mCurBlendState.colorMaskBlue ||
blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha) blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha)
{ {
mBlendStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
} }
break; break;
} }
case gl::State::DIRTY_BIT_BLEND_COLOR: case gl::State::DIRTY_BIT_BLEND_COLOR:
if (state.getBlendColor() != mCurBlendColor) if (state.getBlendColor() != mCurBlendColor)
{ {
mBlendStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_DEPTH_MASK: case gl::State::DIRTY_BIT_DEPTH_MASK:
if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask) if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask)
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest) if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest)
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_DEPTH_FUNC: case gl::State::DIRTY_BIT_DEPTH_FUNC:
if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc) if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc)
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest) if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest)
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
...@@ -370,7 +361,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -370,7 +361,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
depthStencil.stencilMask != mCurDepthStencilState.stencilMask || depthStencil.stencilMask != mCurDepthStencilState.stencilMask ||
state.getStencilRef() != mCurStencilRef) state.getStencilRef() != mCurStencilRef)
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
} }
break; break;
} }
...@@ -381,7 +372,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -381,7 +372,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
depthStencil.stencilBackMask != mCurDepthStencilState.stencilBackMask || depthStencil.stencilBackMask != mCurDepthStencilState.stencilBackMask ||
state.getStencilBackRef() != mCurStencilBackRef) state.getStencilBackRef() != mCurStencilBackRef)
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
} }
break; break;
} }
...@@ -389,14 +380,14 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -389,14 +380,14 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
if (state.getDepthStencilState().stencilWritemask != if (state.getDepthStencilState().stencilWritemask !=
mCurDepthStencilState.stencilWritemask) mCurDepthStencilState.stencilWritemask)
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
if (state.getDepthStencilState().stencilBackWritemask != if (state.getDepthStencilState().stencilBackWritemask !=
mCurDepthStencilState.stencilBackWritemask) mCurDepthStencilState.stencilBackWritemask)
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
...@@ -407,7 +398,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -407,7 +398,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
mCurDepthStencilState.stencilPassDepthFail || mCurDepthStencilState.stencilPassDepthFail ||
depthStencil.stencilPassDepthPass != mCurDepthStencilState.stencilPassDepthPass) depthStencil.stencilPassDepthPass != mCurDepthStencilState.stencilPassDepthPass)
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
} }
break; break;
} }
...@@ -420,33 +411,33 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -420,33 +411,33 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
depthStencil.stencilBackPassDepthPass != depthStencil.stencilBackPassDepthPass !=
mCurDepthStencilState.stencilBackPassDepthPass) mCurDepthStencilState.stencilBackPassDepthPass)
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
} }
break; break;
} }
case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) if (state.getRasterizerState().cullFace != mCurRasterState.cullFace)
{ {
mRasterizerStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_CULL_FACE: case gl::State::DIRTY_BIT_CULL_FACE:
if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) if (state.getRasterizerState().cullMode != mCurRasterState.cullMode)
{ {
mRasterizerStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_FRONT_FACE: case gl::State::DIRTY_BIT_FRONT_FACE:
if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) if (state.getRasterizerState().frontFace != mCurRasterState.frontFace)
{ {
mRasterizerStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
if (state.getRasterizerState().polygonOffsetFill != if (state.getRasterizerState().polygonOffsetFill !=
mCurRasterState.polygonOffsetFill) mCurRasterState.polygonOffsetFill)
{ {
mRasterizerStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_POLYGON_OFFSET: case gl::State::DIRTY_BIT_POLYGON_OFFSET:
...@@ -455,7 +446,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -455,7 +446,7 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor || if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor ||
rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits) rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits)
{ {
mRasterizerStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
} }
break; break;
} }
...@@ -463,33 +454,33 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -463,33 +454,33 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
if (state.getRasterizerState().rasterizerDiscard != if (state.getRasterizerState().rasterizerDiscard !=
mCurRasterState.rasterizerDiscard) mCurRasterState.rasterizerDiscard)
{ {
mRasterizerStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_SCISSOR: case gl::State::DIRTY_BIT_SCISSOR:
if (state.getScissor() != mCurScissorRect) if (state.getScissor() != mCurScissorRect)
{ {
mScissorStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
if (state.isScissorTestEnabled() != mCurScissorEnabled) if (state.isScissorTestEnabled() != mCurScissorEnabled)
{ {
mScissorStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
// Rasterizer state update needs mCurScissorsEnabled and updates when it changes // Rasterizer state update needs mCurScissorsEnabled and updates when it changes
mRasterizerStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_DEPTH_RANGE: case gl::State::DIRTY_BIT_DEPTH_RANGE:
if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar) if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar)
{ {
mViewportStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_VIEWPORT: case gl::State::DIRTY_BIT_VIEWPORT:
if (state.getViewport() != mCurViewport) if (state.getViewport() != mCurViewport)
{ {
mViewportStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
} }
break; break;
case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING: case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
...@@ -516,11 +507,6 @@ gl::Error StateManager11::syncBlendState(const gl::Context *context, ...@@ -516,11 +507,6 @@ gl::Error StateManager11::syncBlendState(const gl::Context *context,
const gl::ColorF &blendColor, const gl::ColorF &blendColor,
unsigned int sampleMask) unsigned int sampleMask)
{ {
if (!mBlendStateIsDirty && sampleMask == mCurSampleMask)
{
return gl::NoError();
}
ID3D11BlendState *dxBlendState = nullptr; ID3D11BlendState *dxBlendState = nullptr;
const d3d11::BlendStateKey &key = const d3d11::BlendStateKey &key =
RenderStateCache::GetBlendStateKey(context, framebuffer, blendState); RenderStateCache::GetBlendStateKey(context, framebuffer, blendState);
...@@ -554,18 +540,11 @@ gl::Error StateManager11::syncBlendState(const gl::Context *context, ...@@ -554,18 +540,11 @@ gl::Error StateManager11::syncBlendState(const gl::Context *context,
mCurBlendColor = blendColor; mCurBlendColor = blendColor;
mCurSampleMask = sampleMask; mCurSampleMask = sampleMask;
mBlendStateIsDirty = false;
return gl::NoError(); return gl::NoError();
} }
gl::Error StateManager11::syncDepthStencilState(const gl::State &glState) gl::Error StateManager11::syncDepthStencilState(const gl::State &glState)
{ {
if (!mDepthStencilStateIsDirty)
{
return gl::NoError();
}
mCurDepthStencilState = glState.getDepthStencilState(); mCurDepthStencilState = glState.getDepthStencilState();
mCurStencilRef = glState.getStencilRef(); mCurStencilRef = glState.getStencilRef();
mCurStencilBackRef = glState.getStencilBackRef(); mCurStencilBackRef = glState.getStencilBackRef();
...@@ -615,25 +594,12 @@ gl::Error StateManager11::syncDepthStencilState(const gl::State &glState) ...@@ -615,25 +594,12 @@ gl::Error StateManager11::syncDepthStencilState(const gl::State &glState)
mRenderer->getDeviceContext()->OMSetDepthStencilState(d3dState, dxStencilRef); mRenderer->getDeviceContext()->OMSetDepthStencilState(d3dState, dxStencilRef);
mDepthStencilStateIsDirty = false;
return gl::NoError(); return gl::NoError();
} }
gl::Error StateManager11::syncRasterizerState(const gl::Context *context, GLenum drawMode) gl::Error StateManager11::syncRasterizerState(const gl::Context *context, bool pointDrawMode)
{ {
bool pointDrawMode = (drawMode == GL_POINTS);
if (pointDrawMode != mCurRasterState.pointDrawMode)
{
mRasterizerStateIsDirty = true;
}
// TODO: Remove pointDrawMode and multiSample from gl::RasterizerState. // TODO: Remove pointDrawMode and multiSample from gl::RasterizerState.
if (!mRasterizerStateIsDirty)
{
return gl::NoError();
}
gl::RasterizerState rasterState = context->getGLState().getRasterizerState(); gl::RasterizerState rasterState = context->getGLState().getRasterizerState();
rasterState.pointDrawMode = pointDrawMode; rasterState.pointDrawMode = pointDrawMode;
rasterState.multiSample = mCurRasterState.multiSample; rasterState.multiSample = mCurRasterState.multiSample;
...@@ -667,17 +633,13 @@ gl::Error StateManager11::syncRasterizerState(const gl::Context *context, GLenum ...@@ -667,17 +633,13 @@ gl::Error StateManager11::syncRasterizerState(const gl::Context *context, GLenum
mRenderer->getDeviceContext()->RSSetState(dxRasterState); mRenderer->getDeviceContext()->RSSetState(dxRasterState);
mCurRasterState = rasterState; mCurRasterState = rasterState;
mRasterizerStateIsDirty = false;
return gl::NoError(); return gl::NoError();
} }
void StateManager11::syncScissorRectangle(const gl::Rectangle &scissor, bool enabled) void StateManager11::syncScissorRectangle(const gl::Rectangle &scissor, bool enabled)
{ {
if (!mScissorStateIsDirty)
return;
int modifiedScissorY = scissor.y; int modifiedScissorY = scissor.y;
if (mCurPresentPathFastEnabled) if (mCurPresentPathFastEnabled)
{ {
...@@ -697,7 +659,6 @@ void StateManager11::syncScissorRectangle(const gl::Rectangle &scissor, bool ena ...@@ -697,7 +659,6 @@ void StateManager11::syncScissorRectangle(const gl::Rectangle &scissor, bool ena
mCurScissorRect = scissor; mCurScissorRect = scissor;
mCurScissorEnabled = enabled; mCurScissorEnabled = enabled;
mScissorStateIsDirty = false;
} }
void StateManager11::syncViewport(const gl::Caps *caps, void StateManager11::syncViewport(const gl::Caps *caps,
...@@ -705,9 +666,6 @@ void StateManager11::syncViewport(const gl::Caps *caps, ...@@ -705,9 +666,6 @@ void StateManager11::syncViewport(const gl::Caps *caps,
float zNear, float zNear,
float zFar) float zFar)
{ {
if (!mViewportStateIsDirty)
return;
float actualZNear = gl::clamp01(zNear); float actualZNear = gl::clamp01(zNear);
float actualZFar = gl::clamp01(zFar); float actualZFar = gl::clamp01(zFar);
...@@ -805,13 +763,14 @@ void StateManager11::syncViewport(const gl::Caps *caps, ...@@ -805,13 +763,14 @@ void StateManager11::syncViewport(const gl::Caps *caps,
mVertexConstants.viewScale[1] = mPixelConstants.viewScale[1]; mVertexConstants.viewScale[1] = mPixelConstants.viewScale[1];
mVertexConstants.viewScale[2] = mPixelConstants.viewScale[2]; mVertexConstants.viewScale[2] = mPixelConstants.viewScale[2];
mVertexConstants.viewScale[3] = mPixelConstants.viewScale[3]; mVertexConstants.viewScale[3] = mPixelConstants.viewScale[3];
mViewportStateIsDirty = false;
} }
void StateManager11::invalidateRenderTarget(const gl::Context *context) void StateManager11::invalidateRenderTarget(const gl::Context *context)
{ {
mRenderTargetIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
// The D3D11 blend state is heavily dependent on the current render target.
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
// nullptr only on display initialization. // nullptr only on display initialization.
if (!context) if (!context)
...@@ -821,6 +780,7 @@ void StateManager11::invalidateRenderTarget(const gl::Context *context) ...@@ -821,6 +780,7 @@ void StateManager11::invalidateRenderTarget(const gl::Context *context)
gl::Framebuffer *fbo = context->getGLState().getDrawFramebuffer(); gl::Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
// nullptr fbo can occur in some egl events like display initialization.
if (!fbo) if (!fbo)
{ {
return; return;
...@@ -837,19 +797,30 @@ void StateManager11::invalidateRenderTarget(const gl::Context *context) ...@@ -837,19 +797,30 @@ void StateManager11::invalidateRenderTarget(const gl::Context *context)
if (!mCurDisableDepth.valid() || disableDepth != mCurDisableDepth.value() || if (!mCurDisableDepth.valid() || disableDepth != mCurDisableDepth.value() ||
!mCurDisableStencil.valid() || disableStencil != mCurDisableStencil.value()) !mCurDisableStencil.valid() || disableStencil != mCurDisableStencil.value())
{ {
mDepthStencilStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
mCurDisableDepth = disableDepth; mCurDisableDepth = disableDepth;
mCurDisableStencil = disableStencil; mCurDisableStencil = disableStencil;
} }
bool multiSample = (fbo->getCachedSamples(context) != 0); bool multiSample = (fbo->getCachedSamples(context) != 0);
if (multiSample != mCurRasterState.multiSample) if (multiSample != mCurRasterState.multiSample)
{ {
mRasterizerStateIsDirty = true; mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
mCurRasterState.multiSample = multiSample; mCurRasterState.multiSample = multiSample;
} }
checkPresentPath(context); checkPresentPath(context);
if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
{
auto *firstAttachment = fbo->getFirstNonNullAttachment();
const auto &size = firstAttachment->getSize();
if (mViewportBounds.width != size.width || mViewportBounds.height != size.height)
{
mViewportBounds = gl::Extents(size.width, size.height, 1);
mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
}
}
} }
void StateManager11::invalidateBoundViews(const gl::Context *context) void StateManager11::invalidateBoundViews(const gl::Context *context)
...@@ -862,11 +833,7 @@ void StateManager11::invalidateBoundViews(const gl::Context *context) ...@@ -862,11 +833,7 @@ void StateManager11::invalidateBoundViews(const gl::Context *context)
void StateManager11::invalidateEverything(const gl::Context *context) void StateManager11::invalidateEverything(const gl::Context *context)
{ {
mBlendStateIsDirty = true; mInternalDirtyBits.set();
mDepthStencilStateIsDirty = true;
mRasterizerStateIsDirty = true;
mScissorStateIsDirty = true;
mViewportStateIsDirty = true;
// We reset the current SRV data because it might not be in sync with D3D's state // We reset the current SRV data because it might not be in sync with D3D's state
// anymore. For example when a currently used SRV is used as an RTV, D3D silently // anymore. For example when a currently used SRV is used as an RTV, D3D silently
...@@ -1055,20 +1022,10 @@ void StateManager11::deinitialize() ...@@ -1055,20 +1022,10 @@ void StateManager11::deinitialize()
gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer) gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer)
{ {
Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer); Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
ANGLE_TRY(framebuffer11->markAttachmentsDirty(context));
if (framebuffer11->hasAnyInternalDirtyBit())
{
ASSERT(framebuffer->id() != 0);
framebuffer11->syncInternalState(context);
}
if (!mRenderTargetIsDirty)
{
return gl::NoError();
}
mRenderTargetIsDirty = false; // Applies the render target surface, depth stencil surface, viewport rectangle and
// scissor rectangle to the renderer
ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit() && framebuffer->cachedComplete());
// Check for zero-sized default framebuffer, which is a special case. // Check for zero-sized default framebuffer, which is a special case.
// in this case we do not wish to modify any state and just silently return false. // in this case we do not wish to modify any state and just silently return false.
...@@ -1083,14 +1040,7 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb ...@@ -1083,14 +1040,7 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb
} }
} }
// Get the color render buffer and serial RTVArray framebufferRTVs = {{}};
// Also extract the render target dimensions and view
unsigned int renderTargetWidth = 0;
unsigned int renderTargetHeight = 0;
RTVArray framebufferRTVs;
bool missingColorRenderTarget = true;
framebufferRTVs.fill(nullptr);
const auto &colorRTs = framebuffer11->getCachedColorRenderTargets(); const auto &colorRTs = framebuffer11->getCachedColorRenderTargets();
...@@ -1117,13 +1067,6 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb ...@@ -1117,13 +1067,6 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb
framebufferRTVs[appliedRTIndex] = renderTarget->getRenderTargetView().get(); framebufferRTVs[appliedRTIndex] = renderTarget->getRenderTargetView().get();
ASSERT(framebufferRTVs[appliedRTIndex]); ASSERT(framebufferRTVs[appliedRTIndex]);
maxExistingRT = static_cast<UINT>(appliedRTIndex) + 1; maxExistingRT = static_cast<UINT>(appliedRTIndex) + 1;
if (missingColorRenderTarget)
{
renderTargetWidth = renderTarget->getWidth();
renderTargetHeight = renderTarget->getHeight();
missingColorRenderTarget = false;
}
} }
// Unset conflicting texture SRVs // Unset conflicting texture SRVs
...@@ -1142,14 +1085,6 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb ...@@ -1142,14 +1085,6 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb
framebufferDSV = depthStencilRenderTarget->getDepthStencilView().get(); framebufferDSV = depthStencilRenderTarget->getDepthStencilView().get();
ASSERT(framebufferDSV); ASSERT(framebufferDSV);
// If there is no render buffer, the width, height and format values come from
// the depth stencil
if (missingColorRenderTarget)
{
renderTargetWidth = depthStencilRenderTarget->getWidth();
renderTargetHeight = depthStencilRenderTarget->getHeight();
}
// Unset conflicting texture SRVs // Unset conflicting texture SRVs
const auto *attachment = framebuffer->getDepthOrStencilbuffer(); const auto *attachment = framebuffer->getDepthOrStencilbuffer();
ASSERT(attachment); ASSERT(attachment);
...@@ -1164,11 +1099,6 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb ...@@ -1164,11 +1099,6 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb
mRenderer->getDeviceContext()->OMSetRenderTargets(maxExistingRT, framebufferRTVs.data(), mRenderer->getDeviceContext()->OMSetRenderTargets(maxExistingRT, framebufferRTVs.data(),
framebufferDSV); framebufferDSV);
// The D3D11 blend state is heavily dependent on the current render target.
mBlendStateIsDirty = true;
setViewportBounds(renderTargetWidth, renderTargetHeight);
return gl::NoError(); return gl::NoError();
} }
...@@ -1288,32 +1218,66 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod ...@@ -1288,32 +1218,66 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod
const auto &data = context->getContextState(); const auto &data = context->getContextState();
const auto &glState = data.getState(); const auto &glState = data.getState();
// Applies the render target surface, depth stencil surface, viewport rectangle and
// scissor rectangle to the renderer
gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit() && framebuffer->cachedComplete()); Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
ANGLE_TRY(syncFramebuffer(context, framebuffer)); ANGLE_TRY(framebuffer11->markAttachmentsDirty(context));
// Setting viewport state
syncViewport(&data.getCaps(), glState.getViewport(), glState.getNearPlane(),
glState.getFarPlane());
// Setting scissor state if (framebuffer11->hasAnyInternalDirtyBit())
syncScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); {
ASSERT(framebuffer->id() != 0);
framebuffer11->syncInternalState(context);
}
// Applying rasterizer state to D3D11 device bool pointDrawMode = (drawMode == GL_POINTS);
ANGLE_TRY(syncRasterizerState(context, drawMode)); if (pointDrawMode != mCurRasterState.pointDrawMode)
{
mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
}
// Setting blend state // TODO(jmadill): This can be recomputed only on framebuffer changes.
Framebuffer11 *fbo11 = GetImplAs<Framebuffer11>(framebuffer); RenderTarget11 *firstRT = framebuffer11->getFirstRenderTarget();
RenderTarget11 *firstRT = fbo11->getFirstRenderTarget();
int samples = (firstRT ? firstRT->getSamples() : 0); int samples = (firstRT ? firstRT->getSamples() : 0);
unsigned int mask = GetBlendSampleMask(data, samples); unsigned int sampleMask = GetBlendSampleMask(data, samples);
ANGLE_TRY(syncBlendState(context, framebuffer, glState.getBlendState(), glState.getBlendColor(), if (sampleMask != mCurSampleMask)
mask)); {
mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
}
auto dirtyBitsCopy = mInternalDirtyBits;
mInternalDirtyBits.reset();
for (auto dirtyBit : dirtyBitsCopy)
{
switch (dirtyBit)
{
case DIRTY_BIT_RENDER_TARGET:
ANGLE_TRY(syncFramebuffer(context, framebuffer));
break;
case DIRTY_BIT_VIEWPORT_STATE:
syncViewport(&data.getCaps(), glState.getViewport(), glState.getNearPlane(),
glState.getFarPlane());
break;
case DIRTY_BIT_SCISSOR_STATE:
syncScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
break;
case DIRTY_BIT_RASTERIZER_STATE:
ANGLE_TRY(syncRasterizerState(context, pointDrawMode));
break;
case DIRTY_BIT_BLEND_STATE:
ANGLE_TRY(syncBlendState(context, framebuffer, glState.getBlendState(),
glState.getBlendColor(), sampleMask));
break;
case DIRTY_BIT_DEPTH_STENCIL_STATE:
ANGLE_TRY(syncDepthStencilState(glState));
break;
default:
UNREACHABLE();
break;
}
}
// Setting depth stencil state // Check that we haven't set any dirty bits in the flushing of the dirty bits loop.
ANGLE_TRY(syncDepthStencilState(glState)); ASSERT(mInternalDirtyBits.none());
return gl::NoError(); return gl::NoError();
} }
......
...@@ -110,7 +110,6 @@ class StateManager11 final : angle::NonCopyable ...@@ -110,7 +110,6 @@ class StateManager11 final : angle::NonCopyable
gl::Error updateState(const gl::Context *context, GLenum drawMode); gl::Error updateState(const gl::Context *context, GLenum drawMode);
private: private:
void setViewportBounds(const int width, const int height);
void unsetConflictingSRVs(gl::SamplerType shaderType, void unsetConflictingSRVs(gl::SamplerType shaderType,
uintptr_t resource, uintptr_t resource,
const gl::ImageIndex &index); const gl::ImageIndex &index);
...@@ -125,7 +124,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -125,7 +124,7 @@ class StateManager11 final : angle::NonCopyable
gl::Error syncDepthStencilState(const gl::State &glState); gl::Error syncDepthStencilState(const gl::State &glState);
gl::Error syncRasterizerState(const gl::Context *context, GLenum drawMode); gl::Error syncRasterizerState(const gl::Context *context, bool pointDrawMode);
void syncScissorRectangle(const gl::Rectangle &scissor, bool enabled); void syncScissorRectangle(const gl::Rectangle &scissor, bool enabled);
...@@ -135,18 +134,31 @@ class StateManager11 final : angle::NonCopyable ...@@ -135,18 +134,31 @@ class StateManager11 final : angle::NonCopyable
gl::Error syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer); gl::Error syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer);
enum DirtyBitType
{
DIRTY_BIT_RENDER_TARGET,
DIRTY_BIT_VIEWPORT_STATE,
DIRTY_BIT_SCISSOR_STATE,
DIRTY_BIT_RASTERIZER_STATE,
DIRTY_BIT_BLEND_STATE,
DIRTY_BIT_DEPTH_STENCIL_STATE,
DIRTY_BIT_INVALID,
DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
};
using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
Renderer11 *mRenderer; Renderer11 *mRenderer;
// Internal dirty bits.
DirtyBits mInternalDirtyBits;
// Blend State // Blend State
bool mBlendStateIsDirty;
// TODO(dianx) temporary representation of a dirty bit. once we move enough states in,
// try experimenting with dirty bit instead of a bool
gl::BlendState mCurBlendState; gl::BlendState mCurBlendState;
gl::ColorF mCurBlendColor; gl::ColorF mCurBlendColor;
unsigned int mCurSampleMask; unsigned int mCurSampleMask;
// Currently applied depth stencil state // Currently applied depth stencil state
bool mDepthStencilStateIsDirty;
gl::DepthStencilState mCurDepthStencilState; gl::DepthStencilState mCurDepthStencilState;
int mCurStencilRef; int mCurStencilRef;
int mCurStencilBackRef; int mCurStencilBackRef;
...@@ -155,16 +167,13 @@ class StateManager11 final : angle::NonCopyable ...@@ -155,16 +167,13 @@ class StateManager11 final : angle::NonCopyable
Optional<bool> mCurDisableStencil; Optional<bool> mCurDisableStencil;
// Currently applied rasterizer state // Currently applied rasterizer state
bool mRasterizerStateIsDirty;
gl::RasterizerState mCurRasterState; gl::RasterizerState mCurRasterState;
// Currently applied scissor rectangle state // Currently applied scissor rectangle state
bool mScissorStateIsDirty;
bool mCurScissorEnabled; bool mCurScissorEnabled;
gl::Rectangle mCurScissorRect; gl::Rectangle mCurScissorRect;
// Currently applied viewport state // Currently applied viewport state
bool mViewportStateIsDirty;
gl::Rectangle mCurViewport; gl::Rectangle mCurViewport;
float mCurNear; float mCurNear;
float mCurFar; float mCurFar;
...@@ -182,9 +191,6 @@ class StateManager11 final : angle::NonCopyable ...@@ -182,9 +191,6 @@ class StateManager11 final : angle::NonCopyable
bool mCurPresentPathFastEnabled; bool mCurPresentPathFastEnabled;
int mCurPresentPathFastColorBufferHeight; int mCurPresentPathFastColorBufferHeight;
// Current RenderTarget state
bool mRenderTargetIsDirty;
// Queries that are currently active in this state // Queries that are currently active in this state
std::set<Query11 *> mCurrentQueries; std::set<Query11 *> mCurrentQueries;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment