Commit 83af74f5 by Dian Xiang

Using dirty bit notification for D3D11 depth stencil state

BUG=angleproject:1161 This is a continuation of the dirty bit refactor Change-Id: If7d523e6200fef631051cab0bde47fdec8385c17 Reviewed-on: https://chromium-review.googlesource.com/312722Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarDian Xiang <dianx@google.com>
parent 5111a062
...@@ -470,7 +470,6 @@ void Renderer11::SRVCache::clear() ...@@ -470,7 +470,6 @@ void Renderer11::SRVCache::clear()
Renderer11::Renderer11(egl::Display *display) Renderer11::Renderer11(egl::Display *display)
: RendererD3D(display), : RendererD3D(display),
mStateCache(this), mStateCache(this),
mCurStencilSize(0),
mStateManager(this), mStateManager(this),
mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime()), mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime()),
mDebug(nullptr) mDebug(nullptr)
...@@ -1395,47 +1394,7 @@ gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer, ...@@ -1395,47 +1394,7 @@ gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer,
gl::Error Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, gl::Error Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW) int stencilBackRef, bool frontFaceCCW)
{ {
if (mForceSetDepthStencilState || return mStateManager.setDepthStencilState(depthStencilState, stencilRef, stencilBackRef);
memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
{
// 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, &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);
mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
mCurDepthStencilState = depthStencilState;
mCurStencilRef = stencilRef;
mCurStencilBackRef = stencilBackRef;
}
mForceSetDepthStencilState = false;
return gl::Error(GL_NO_ERROR);
} }
void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
...@@ -1712,11 +1671,7 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer) ...@@ -1712,11 +1671,7 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
} }
unsigned int stencilSize = depthStencil->getStencilSize(); unsigned int stencilSize = depthStencil->getStencilSize();
if (!mDepthStencilInitialized || stencilSize != mCurStencilSize) mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize);
{
mCurStencilSize = stencilSize;
mForceSetDepthStencilState = true;
}
} }
// Apply the render target and depth stencil // Apply the render target and depth stencil
...@@ -2525,8 +2480,8 @@ void Renderer11::markAllStateDirty() ...@@ -2525,8 +2480,8 @@ void Renderer11::markAllStateDirty()
} }
mStateManager.forceSetBlendState(); mStateManager.forceSetBlendState();
mStateManager.forceSetDepthStencilState();
mForceSetRasterState = true; mForceSetRasterState = true;
mForceSetDepthStencilState = true;
mForceSetScissor = true; mForceSetScissor = true;
mForceSetViewport = true; mForceSetViewport = true;
......
...@@ -127,8 +127,10 @@ class Renderer11 : public RendererD3D ...@@ -127,8 +127,10 @@ class Renderer11 : public RendererD3D
const gl::ColorF &blendColor, const gl::ColorF &blendColor,
unsigned int sampleMask) override; unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState,
int stencilBackRef, bool frontFaceCCW); int stencilRef,
int stencilBackRef,
bool frontFaceCCW) override;
virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
...@@ -350,7 +352,6 @@ class Renderer11 : public RendererD3D ...@@ -350,7 +352,6 @@ class Renderer11 : public RendererD3D
uintptr_t mAppliedDSV; uintptr_t mAppliedDSV;
bool mDepthStencilInitialized; bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized; bool mRenderTargetDescInitialized;
unsigned int mCurStencilSize;
struct RenderTargetDesc struct RenderTargetDesc
{ {
...@@ -416,12 +417,6 @@ class Renderer11 : public RendererD3D ...@@ -416,12 +417,6 @@ class Renderer11 : public RendererD3D
bool mForceSetRasterState; bool mForceSetRasterState;
gl::RasterizerState mCurRasterState; gl::RasterizerState mCurRasterState;
// Currently applied depth stencil state
bool mForceSetDepthStencilState;
gl::DepthStencilState mCurDepthStencilState;
int mCurStencilRef;
int mCurStencilBackRef;
// Currently applied scissor rectangle // Currently applied scissor rectangle
bool mForceSetScissor; bool mForceSetScissor;
bool mScissorEnabled; bool mScissorEnabled;
......
...@@ -18,6 +18,10 @@ StateManager11::StateManager11(Renderer11 *renderer11) ...@@ -18,6 +18,10 @@ StateManager11::StateManager11(Renderer11 *renderer11)
: mBlendStateIsDirty(false), : mBlendStateIsDirty(false),
mCurBlendColor(0, 0, 0, 0), mCurBlendColor(0, 0, 0, 0),
mCurSampleMask(0), mCurSampleMask(0),
mDepthStencilStateIsDirty(false),
mCurStencilRef(0),
mCurStencilBackRef(0),
mCurStencilSize(0),
mRenderer11(renderer11) mRenderer11(renderer11)
{ {
mCurBlendState.blend = false; mCurBlendState.blend = false;
...@@ -33,12 +37,38 @@ StateManager11::StateManager11(Renderer11 *renderer11) ...@@ -33,12 +37,38 @@ StateManager11::StateManager11(Renderer11 *renderer11)
mCurBlendState.colorMaskAlpha = true; mCurBlendState.colorMaskAlpha = true;
mCurBlendState.sampleAlphaToCoverage = false; mCurBlendState.sampleAlphaToCoverage = false;
mCurBlendState.dither = false; mCurBlendState.dither = false;
mCurDepthStencilState.depthTest = false;
mCurDepthStencilState.depthFunc = GL_LESS;
mCurDepthStencilState.depthMask = true;
mCurDepthStencilState.stencilTest = false;
mCurDepthStencilState.stencilMask = true;
mCurDepthStencilState.stencilFail = GL_KEEP;
mCurDepthStencilState.stencilPassDepthFail = GL_KEEP;
mCurDepthStencilState.stencilPassDepthPass = GL_KEEP;
mCurDepthStencilState.stencilWritemask = static_cast<GLuint>(-1);
mCurDepthStencilState.stencilBackFunc = GL_ALWAYS;
mCurDepthStencilState.stencilBackMask = static_cast<GLuint>(-1);
mCurDepthStencilState.stencilBackFail = GL_KEEP;
mCurDepthStencilState.stencilBackPassDepthFail = GL_KEEP;
mCurDepthStencilState.stencilBackPassDepthPass = GL_KEEP;
mCurDepthStencilState.stencilBackWritemask = static_cast<GLuint>(-1);
} }
StateManager11::~StateManager11() StateManager11::~StateManager11()
{ {
} }
void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
unsigned int stencilSize)
{
if (!depthStencilInitialized || stencilSize != mCurStencilSize)
{
mCurStencilSize = stencilSize;
mDepthStencilStateIsDirty = true;
}
}
void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
{ {
for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits)) for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits))
...@@ -104,6 +134,91 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit ...@@ -104,6 +134,91 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit
mBlendStateIsDirty = true; mBlendStateIsDirty = true;
} }
break; 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;
}
default: default:
break; break;
} }
...@@ -158,4 +273,54 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, ...@@ -158,4 +273,54 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error StateManager11::setDepthStencilState(const gl::DepthStencilState &depthStencilState,
int stencilRef,
int stencilBackRef)
{
if (mDepthStencilStateIsDirty)
{
// 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 = mRenderer11->getStateCache().getDepthStencilState(depthStencilState,
&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);
mRenderer11->getDeviceContext()->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
mCurDepthStencilState = depthStencilState;
mCurStencilRef = stencilRef;
mCurStencilBackRef = stencilBackRef;
mDepthStencilStateIsDirty = false;
}
return gl::Error(GL_NO_ERROR);
}
} // namespace rx } // namespace rx
...@@ -33,7 +33,14 @@ class StateManager11 final : angle::NonCopyable ...@@ -33,7 +33,14 @@ class StateManager11 final : angle::NonCopyable
const gl::ColorF &blendColor, const gl::ColorF &blendColor,
unsigned int sampleMask); unsigned int sampleMask);
gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState,
int stencilRef,
int stencilBackRef);
void forceSetBlendState() { mBlendStateIsDirty = true; } void forceSetBlendState() { mBlendStateIsDirty = true; }
void forceSetDepthStencilState() { mDepthStencilStateIsDirty = true; }
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
private: private:
// Blend State // Blend State
...@@ -44,6 +51,13 @@ class StateManager11 final : angle::NonCopyable ...@@ -44,6 +51,13 @@ class StateManager11 final : angle::NonCopyable
gl::ColorF mCurBlendColor; gl::ColorF mCurBlendColor;
unsigned int mCurSampleMask; unsigned int mCurSampleMask;
// Currently applied depth stencil state
bool mDepthStencilStateIsDirty;
gl::DepthStencilState mCurDepthStencilState;
int mCurStencilRef;
int mCurStencilBackRef;
unsigned int mCurStencilSize;
Renderer11 *mRenderer11; Renderer11 *mRenderer11;
}; };
......
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