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)
void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
{
if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
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;
mStateManager.setScissorRectangle(scissor, enabled);
}
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)
mRenderTargetDesc.height = renderTargetHeight;
mRenderTargetDesc.format = renderTargetFormat;
mForceSetViewport = true;
mForceSetScissor = true;
mStateManager.forceSetBlendState();
if (!mDepthStencilInitialized)
......@@ -2525,7 +2500,7 @@ void Renderer11::markAllStateDirty()
mStateManager.forceSetBlendState();
mStateManager.forceSetDepthStencilState();
mStateManager.forceSetRasterState();
mForceSetScissor = true;
mStateManager.forceSetScissorState();
mForceSetViewport = true;
mAppliedIB = NULL;
......
......@@ -413,11 +413,6 @@ class Renderer11 : public RendererD3D
StateManager11 mStateManager;
// Currently applied scissor rectangle
bool mForceSetScissor;
bool mScissorEnabled;
gl::Rectangle mCurScissor;
// Currently applied viewport
bool mForceSetViewport;
gl::Rectangle mCurViewport;
......
......@@ -23,7 +23,9 @@ StateManager11::StateManager11()
mCurStencilBackRef(0),
mCurStencilSize(0),
mRasterizerStateIsDirty(false),
mScissorStateIsDirty(false),
mCurScissorEnabled(false),
mCurScissorRect(),
mDeviceContext(nullptr),
mStateCache(nullptr)
{
......@@ -280,6 +282,20 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit
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;
default:
break;
}
......@@ -291,46 +307,48 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer,
const gl::ColorF &blendColor,
unsigned int sampleMask)
{
if (mBlendStateIsDirty || sampleMask != mCurSampleMask)
if (!mBlendStateIsDirty && sampleMask == mCurSampleMask)
{
ID3D11BlendState *dxBlendState = nullptr;
gl::Error error = mStateCache->getBlendState(framebuffer, blendState, &dxBlendState);
if (error.isError())
{
return error;
}
return gl::Error(GL_NO_ERROR);
}
ID3D11BlendState *dxBlendState = nullptr;
gl::Error error = mStateCache->getBlendState(framebuffer, blendState, &dxBlendState);
if (error.isError())
{
return error;
}
ASSERT(dxBlendState != nullptr);
ASSERT(dxBlendState != nullptr);
float blendColors[4] = {0.0f};
if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA &&
blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
blendState.destBlendRGB != GL_CONSTANT_ALPHA &&
blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
{
blendColors[0] = blendColor.red;
blendColors[1] = blendColor.green;
blendColors[2] = blendColor.blue;
blendColors[3] = blendColor.alpha;
}
else
{
blendColors[0] = blendColor.alpha;
blendColors[1] = blendColor.alpha;
blendColors[2] = blendColor.alpha;
blendColors[3] = blendColor.alpha;
}
float blendColors[4] = {0.0f};
if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA &&
blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
blendState.destBlendRGB != GL_CONSTANT_ALPHA &&
blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
{
blendColors[0] = blendColor.red;
blendColors[1] = blendColor.green;
blendColors[2] = blendColor.blue;
blendColors[3] = blendColor.alpha;
}
else
{
blendColors[0] = blendColor.alpha;
blendColors[1] = blendColor.alpha;
blendColors[2] = blendColor.alpha;
blendColors[3] = blendColor.alpha;
}
mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
mCurBlendState = blendState;
mCurBlendColor = blendColor;
mCurSampleMask = sampleMask;
mCurBlendState = blendState;
mCurBlendColor = blendColor;
mCurSampleMask = sampleMask;
mBlendStateIsDirty = false;
}
mBlendStateIsDirty = false;
return gl::Error(GL_NO_ERROR);
return error;
}
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());
// CurDisableDepth/Stencil are reset automatically after we call forceSetDepthStencilState.
if (mDepthStencilStateIsDirty || !mCurDisableDepth.valid() ||
disableDepth != mCurDisableDepth.value() || !mCurDisableStencil.valid() ||
disableStencil != mCurDisableStencil.value())
if (!mDepthStencilStateIsDirty && mCurDisableDepth.valid() &&
disableDepth == mCurDisableDepth.value() && mCurDisableStencil.valid() &&
disableStencil == mCurDisableStencil.value())
{
const auto &depthStencilState = glState.getDepthStencilState();
int stencilRef = glState.getStencilRef();
int stencilBackRef = glState.getStencilBackRef();
return gl::Error(GL_NO_ERROR);
}
// 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 = mStateCache->getDepthStencilState(depthStencilState, disableDepth,
disableStencil, &dxDepthStencilState);
if (error.isError())
{
return 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 = mStateCache->getDepthStencilState(depthStencilState, disableDepth,
disableStencil, &dxDepthStencilState);
if (error.isError())
{
return error;
}
ASSERT(dxDepthStencilState);
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);
// 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);
mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
mCurDepthStencilState = depthStencilState;
mCurStencilRef = stencilRef;
mCurStencilBackRef = stencilBackRef;
mCurDisableDepth = disableDepth;
mCurDisableStencil = disableStencil;
mCurDepthStencilState = depthStencilState;
mCurStencilRef = stencilRef;
mCurStencilBackRef = stencilBackRef;
mCurDisableDepth = disableDepth;
mCurDisableStencil = disableStencil;
mDepthStencilStateIsDirty = false;
}
mDepthStencilStateIsDirty = false;
return gl::Error(GL_NO_ERROR);
}
gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterState)
{
if (mRasterizerStateIsDirty)
if (!mRasterizerStateIsDirty)
{
ID3D11RasterizerState *dxRasterState = nullptr;
gl::Error error =
mStateCache->getRasterizerState(rasterState, mCurScissorEnabled, &dxRasterState);
if (error.isError())
{
return error;
}
return gl::Error(GL_NO_ERROR);
}
ID3D11RasterizerState *dxRasterState = nullptr;
gl::Error 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;
mRasterizerStateIsDirty = false;
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);
}
return gl::Error(GL_NO_ERROR);
mCurScissorRect = scissor;
mCurScissorEnabled = enabled;
mScissorStateIsDirty = false;
}
} // namespace rx
......@@ -38,11 +38,12 @@ class StateManager11 final : angle::NonCopyable
gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
void forceSetBlendState() { mBlendStateIsDirty = true; }
void forceSetDepthStencilState() { mDepthStencilStateIsDirty = true; }
void forceSetRasterState() { mRasterizerStateIsDirty = true; }
void setCurScissorEnabled(bool enabled) { mCurScissorEnabled = enabled; }
void forceSetScissorState() { mScissorStateIsDirty = true; }
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
......@@ -68,7 +69,10 @@ class StateManager11 final : angle::NonCopyable
bool mRasterizerStateIsDirty;
gl::RasterizerState mCurRasterState;
// Currently applied scissor rectangle state
bool mScissorStateIsDirty;
bool mCurScissorEnabled;
gl::Rectangle mCurScissorRect;
ID3D11DeviceContext *mDeviceContext;
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