Commit 29a65546 by Dian Xiang

Using dirty bit notification for D3D11 scissor rectangle state

BUG=angleproject:1161 This is a continuation of the dirty bit refactor Change-Id: I1a9f297835943eee5f756e4e4721b2db543184ec Reviewed-on: https://chromium-review.googlesource.com/312987Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarDian Xiang <dianx@google.com>
parent 2da819e1
...@@ -1441,31 +1441,7 @@ gl::Error Renderer11::setDepthStencilState(const gl::State &glState) ...@@ -1441,31 +1441,7 @@ gl::Error Renderer11::setDepthStencilState(const gl::State &glState)
void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
{ {
if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 || mStateManager.setScissorRectangle(scissor, enabled);
enabled != mScissorEnabled)
{
if (enabled)
{
D3D11_RECT rect;
rect.left = std::max(0, scissor.x);
rect.top = std::max(0, scissor.y);
rect.right = scissor.x + std::max(0, scissor.width);
rect.bottom = scissor.y + std::max(0, scissor.height);
mDeviceContext->RSSetScissorRects(1, &rect);
}
if (enabled != mScissorEnabled)
{
mStateManager.forceSetRasterState();
}
mCurScissor = scissor;
mScissorEnabled = enabled;
mStateManager.setCurScissorEnabled(mScissorEnabled);
}
mForceSetScissor = false;
} }
void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
...@@ -1728,7 +1704,6 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer) ...@@ -1728,7 +1704,6 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
mRenderTargetDesc.height = renderTargetHeight; mRenderTargetDesc.height = renderTargetHeight;
mRenderTargetDesc.format = renderTargetFormat; mRenderTargetDesc.format = renderTargetFormat;
mForceSetViewport = true; mForceSetViewport = true;
mForceSetScissor = true;
mStateManager.forceSetBlendState(); mStateManager.forceSetBlendState();
if (!mDepthStencilInitialized) if (!mDepthStencilInitialized)
...@@ -2525,7 +2500,7 @@ void Renderer11::markAllStateDirty() ...@@ -2525,7 +2500,7 @@ void Renderer11::markAllStateDirty()
mStateManager.forceSetBlendState(); mStateManager.forceSetBlendState();
mStateManager.forceSetDepthStencilState(); mStateManager.forceSetDepthStencilState();
mStateManager.forceSetRasterState(); mStateManager.forceSetRasterState();
mForceSetScissor = true; mStateManager.forceSetScissorState();
mForceSetViewport = true; mForceSetViewport = true;
mAppliedIB = NULL; mAppliedIB = NULL;
......
...@@ -413,11 +413,6 @@ class Renderer11 : public RendererD3D ...@@ -413,11 +413,6 @@ class Renderer11 : public RendererD3D
StateManager11 mStateManager; StateManager11 mStateManager;
// Currently applied scissor rectangle
bool mForceSetScissor;
bool mScissorEnabled;
gl::Rectangle mCurScissor;
// Currently applied viewport // Currently applied viewport
bool mForceSetViewport; bool mForceSetViewport;
gl::Rectangle mCurViewport; gl::Rectangle mCurViewport;
......
...@@ -23,7 +23,9 @@ StateManager11::StateManager11() ...@@ -23,7 +23,9 @@ StateManager11::StateManager11()
mCurStencilBackRef(0), mCurStencilBackRef(0),
mCurStencilSize(0), mCurStencilSize(0),
mRasterizerStateIsDirty(false), mRasterizerStateIsDirty(false),
mScissorStateIsDirty(false),
mCurScissorEnabled(false), mCurScissorEnabled(false),
mCurScissorRect(),
mDeviceContext(nullptr), mDeviceContext(nullptr),
mStateCache(nullptr) mStateCache(nullptr)
{ {
...@@ -280,6 +282,20 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit ...@@ -280,6 +282,20 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit
mRasterizerStateIsDirty = true; mRasterizerStateIsDirty = true;
} }
break; 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;
default: default:
break; break;
} }
...@@ -291,46 +307,48 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, ...@@ -291,46 +307,48 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer,
const gl::ColorF &blendColor, const gl::ColorF &blendColor,
unsigned int sampleMask) unsigned int sampleMask)
{ {
if (mBlendStateIsDirty || sampleMask != mCurSampleMask) if (!mBlendStateIsDirty && sampleMask == mCurSampleMask)
{ {
ID3D11BlendState *dxBlendState = nullptr; return gl::Error(GL_NO_ERROR);
gl::Error error = mStateCache->getBlendState(framebuffer, blendState, &dxBlendState); }
if (error.isError())
{ ID3D11BlendState *dxBlendState = nullptr;
return error; gl::Error error = mStateCache->getBlendState(framebuffer, blendState, &dxBlendState);
} if (error.isError())
{
return error;
}
ASSERT(dxBlendState != nullptr); ASSERT(dxBlendState != nullptr);
float blendColors[4] = {0.0f}; float blendColors[4] = {0.0f};
if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA &&
blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_CONSTANT_ALPHA &&
blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
{ {
blendColors[0] = blendColor.red; blendColors[0] = blendColor.red;
blendColors[1] = blendColor.green; blendColors[1] = blendColor.green;
blendColors[2] = blendColor.blue; blendColors[2] = blendColor.blue;
blendColors[3] = blendColor.alpha; blendColors[3] = blendColor.alpha;
} }
else else
{ {
blendColors[0] = blendColor.alpha; blendColors[0] = blendColor.alpha;
blendColors[1] = blendColor.alpha; blendColors[1] = blendColor.alpha;
blendColors[2] = blendColor.alpha; blendColors[2] = blendColor.alpha;
blendColors[3] = blendColor.alpha; blendColors[3] = blendColor.alpha;
} }
mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask); mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
mCurBlendState = blendState; mCurBlendState = blendState;
mCurBlendColor = blendColor; mCurBlendColor = blendColor;
mCurSampleMask = sampleMask; mCurSampleMask = sampleMask;
mBlendStateIsDirty = false; mBlendStateIsDirty = false;
}
return gl::Error(GL_NO_ERROR); return error;
} }
gl::Error StateManager11::setDepthStencilState(const gl::State &glState) gl::Error StateManager11::setDepthStencilState(const gl::State &glState)
...@@ -346,79 +364,104 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState) ...@@ -346,79 +364,104 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState)
bool disableStencil = (fbo.hasDepth() && !fbo.hasStencil()); bool disableStencil = (fbo.hasDepth() && !fbo.hasStencil());
// CurDisableDepth/Stencil are reset automatically after we call forceSetDepthStencilState. // CurDisableDepth/Stencil are reset automatically after we call forceSetDepthStencilState.
if (mDepthStencilStateIsDirty || !mCurDisableDepth.valid() || if (!mDepthStencilStateIsDirty && mCurDisableDepth.valid() &&
disableDepth != mCurDisableDepth.value() || !mCurDisableStencil.valid() || disableDepth == mCurDisableDepth.value() && mCurDisableStencil.valid() &&
disableStencil != mCurDisableStencil.value()) disableStencil == mCurDisableStencil.value())
{ {
const auto &depthStencilState = glState.getDepthStencilState(); return gl::Error(GL_NO_ERROR);
int stencilRef = glState.getStencilRef(); }
int stencilBackRef = glState.getStencilBackRef();
// get the maximum size of the stencil ref const auto &depthStencilState = glState.getDepthStencilState();
unsigned int maxStencil = 0; int stencilRef = glState.getStencilRef();
if (depthStencilState.stencilTest && mCurStencilSize > 0) int stencilBackRef = glState.getStencilBackRef();
{
maxStencil = (1 << mCurStencilSize) - 1; // get the maximum size of the stencil ref
} unsigned int maxStencil = 0;
ASSERT((depthStencilState.stencilWritemask & maxStencil) == if (depthStencilState.stencilTest && mCurStencilSize > 0)
(depthStencilState.stencilBackWritemask & maxStencil)); {
ASSERT(stencilRef == stencilBackRef); maxStencil = (1 << mCurStencilSize) - 1;
ASSERT((depthStencilState.stencilMask & maxStencil) == }
(depthStencilState.stencilBackMask & maxStencil)); ASSERT((depthStencilState.stencilWritemask & maxStencil) ==
(depthStencilState.stencilBackWritemask & maxStencil));
ID3D11DepthStencilState *dxDepthStencilState = NULL; ASSERT(stencilRef == stencilBackRef);
gl::Error error = mStateCache->getDepthStencilState(depthStencilState, disableDepth, ASSERT((depthStencilState.stencilMask & maxStencil) ==
disableStencil, &dxDepthStencilState); (depthStencilState.stencilBackMask & maxStencil));
if (error.isError())
{ ID3D11DepthStencilState *dxDepthStencilState = NULL;
return error; gl::Error error = mStateCache->getDepthStencilState(depthStencilState, disableDepth,
} disableStencil, &dxDepthStencilState);
if (error.isError())
{
return error;
}
ASSERT(dxDepthStencilState); ASSERT(dxDepthStencilState);
// Max D3D11 stencil reference value is 0xFF, // Max D3D11 stencil reference value is 0xFF,
// corresponding to the max 8 bits in a stencil buffer // corresponding to the max 8 bits in a stencil buffer
// GL specifies we should clamp the ref value to the // GL specifies we should clamp the ref value to the
// nearest bit depth when doing stencil ops // nearest bit depth when doing stencil ops
static_assert(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF, static_assert(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF,
"Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK"); "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK");
static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF, static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF,
"Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK"); "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK");
UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu); UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu);
mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef); mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
mCurDepthStencilState = depthStencilState; mCurDepthStencilState = depthStencilState;
mCurStencilRef = stencilRef; mCurStencilRef = stencilRef;
mCurStencilBackRef = stencilBackRef; mCurStencilBackRef = stencilBackRef;
mCurDisableDepth = disableDepth; mCurDisableDepth = disableDepth;
mCurDisableStencil = disableStencil; mCurDisableStencil = disableStencil;
mDepthStencilStateIsDirty = false; mDepthStencilStateIsDirty = false;
}
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterState) gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterState)
{ {
if (mRasterizerStateIsDirty) if (!mRasterizerStateIsDirty)
{ {
ID3D11RasterizerState *dxRasterState = nullptr; return gl::Error(GL_NO_ERROR);
gl::Error error = }
mStateCache->getRasterizerState(rasterState, mCurScissorEnabled, &dxRasterState);
if (error.isError()) ID3D11RasterizerState *dxRasterState = nullptr;
{ gl::Error error =
return error; mStateCache->getRasterizerState(rasterState, mCurScissorEnabled, &dxRasterState);
} if (error.isError())
{
return error;
}
mDeviceContext->RSSetState(dxRasterState);
mCurRasterState = rasterState;
mRasterizerStateIsDirty = false;
mDeviceContext->RSSetState(dxRasterState); return error;
}
void StateManager11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
{
if (!mScissorStateIsDirty)
return;
mCurRasterState = rasterState; if (enabled)
mRasterizerStateIsDirty = false; {
D3D11_RECT rect;
rect.left = std::max(0, scissor.x);
rect.top = std::max(0, scissor.y);
rect.right = scissor.x + std::max(0, scissor.width);
rect.bottom = scissor.y + std::max(0, scissor.height);
mDeviceContext->RSSetScissorRects(1, &rect);
} }
return gl::Error(GL_NO_ERROR); mCurScissorRect = scissor;
mCurScissorEnabled = enabled;
mScissorStateIsDirty = false;
} }
} // namespace rx } // namespace rx
...@@ -38,11 +38,12 @@ class StateManager11 final : angle::NonCopyable ...@@ -38,11 +38,12 @@ class StateManager11 final : angle::NonCopyable
gl::Error setRasterizerState(const gl::RasterizerState &rasterState); gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
void forceSetBlendState() { mBlendStateIsDirty = true; } void forceSetBlendState() { mBlendStateIsDirty = true; }
void forceSetDepthStencilState() { mDepthStencilStateIsDirty = true; } void forceSetDepthStencilState() { mDepthStencilStateIsDirty = true; }
void forceSetRasterState() { mRasterizerStateIsDirty = true; } void forceSetRasterState() { mRasterizerStateIsDirty = true; }
void forceSetScissorState() { mScissorStateIsDirty = true; }
void setCurScissorEnabled(bool enabled) { mCurScissorEnabled = enabled; }
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize); void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
...@@ -68,7 +69,10 @@ class StateManager11 final : angle::NonCopyable ...@@ -68,7 +69,10 @@ class StateManager11 final : angle::NonCopyable
bool mRasterizerStateIsDirty; bool mRasterizerStateIsDirty;
gl::RasterizerState mCurRasterState; gl::RasterizerState mCurRasterState;
// Currently applied scissor rectangle state
bool mScissorStateIsDirty;
bool mCurScissorEnabled; bool mCurScissorEnabled;
gl::Rectangle mCurScissorRect;
ID3D11DeviceContext *mDeviceContext; ID3D11DeviceContext *mDeviceContext;
RenderStateCache *mStateCache; RenderStateCache *mStateCache;
......
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