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()
Renderer11::Renderer11(egl::Display *display)
: RendererD3D(display),
mStateCache(this),
mCurStencilSize(0),
mStateManager(this),
mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime()),
mDebug(nullptr)
......@@ -1395,47 +1394,7 @@ gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer,
gl::Error Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW)
{
if (mForceSetDepthStencilState ||
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);
return mStateManager.setDepthStencilState(depthStencilState, stencilRef, stencilBackRef);
}
void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
......@@ -1712,11 +1671,7 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
}
unsigned int stencilSize = depthStencil->getStencilSize();
if (!mDepthStencilInitialized || stencilSize != mCurStencilSize)
{
mCurStencilSize = stencilSize;
mForceSetDepthStencilState = true;
}
mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize);
}
// Apply the render target and depth stencil
......@@ -2525,8 +2480,8 @@ void Renderer11::markAllStateDirty()
}
mStateManager.forceSetBlendState();
mStateManager.forceSetDepthStencilState();
mForceSetRasterState = true;
mForceSetDepthStencilState = true;
mForceSetScissor = true;
mForceSetViewport = true;
......
......@@ -127,8 +127,10 @@ class Renderer11 : public RendererD3D
const gl::ColorF &blendColor,
unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW);
gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState,
int stencilRef,
int stencilBackRef,
bool frontFaceCCW) override;
virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
......@@ -350,7 +352,6 @@ class Renderer11 : public RendererD3D
uintptr_t mAppliedDSV;
bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized;
unsigned int mCurStencilSize;
struct RenderTargetDesc
{
......@@ -416,12 +417,6 @@ class Renderer11 : public RendererD3D
bool mForceSetRasterState;
gl::RasterizerState mCurRasterState;
// Currently applied depth stencil state
bool mForceSetDepthStencilState;
gl::DepthStencilState mCurDepthStencilState;
int mCurStencilRef;
int mCurStencilBackRef;
// Currently applied scissor rectangle
bool mForceSetScissor;
bool mScissorEnabled;
......
......@@ -18,6 +18,10 @@ StateManager11::StateManager11(Renderer11 *renderer11)
: mBlendStateIsDirty(false),
mCurBlendColor(0, 0, 0, 0),
mCurSampleMask(0),
mDepthStencilStateIsDirty(false),
mCurStencilRef(0),
mCurStencilBackRef(0),
mCurStencilSize(0),
mRenderer11(renderer11)
{
mCurBlendState.blend = false;
......@@ -33,12 +37,38 @@ StateManager11::StateManager11(Renderer11 *renderer11)
mCurBlendState.colorMaskAlpha = true;
mCurBlendState.sampleAlphaToCoverage = 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()
{
}
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)
{
for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits))
......@@ -104,6 +134,91 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit
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;
}
default:
break;
}
......@@ -158,4 +273,54 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer,
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
......@@ -33,7 +33,14 @@ class StateManager11 final : angle::NonCopyable
const gl::ColorF &blendColor,
unsigned int sampleMask);
gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState,
int stencilRef,
int stencilBackRef);
void forceSetBlendState() { mBlendStateIsDirty = true; }
void forceSetDepthStencilState() { mDepthStencilStateIsDirty = true; }
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
private:
// Blend State
......@@ -44,6 +51,13 @@ class StateManager11 final : angle::NonCopyable
gl::ColorF mCurBlendColor;
unsigned int mCurSampleMask;
// Currently applied depth stencil state
bool mDepthStencilStateIsDirty;
gl::DepthStencilState mCurDepthStencilState;
int mCurStencilRef;
int mCurStencilBackRef;
unsigned int mCurStencilSize;
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