Commit 6ae40ea5 by Dian Xiang

Using dirty bits notification for D3D9 depth stencil state

BUG=angleproject:1249 This is a continuation of the D3D dirty bit refactor for D3D9 for performance enhancements Change-Id: I8690d47999b73483c47f4994dc46cd97f4ced63d Reviewed-on: https://chromium-review.googlesource.com/316449 Tryjob-Request: Dian Xiang <dianx@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarDian Xiang <dianx@google.com>
parent c660ba8e
...@@ -913,29 +913,26 @@ gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode) ...@@ -913,29 +913,26 @@ gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode)
// Setting scissors state // Setting scissors state
setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled());
// Setting rasterizer state // Setting blend, depth stencil, and rasterizer states
int samples = framebufferObject->getSamples(data); int samples = framebufferObject->getSamples(data);
gl::RasterizerState rasterizer = data.state->getRasterizerState(); gl::RasterizerState rasterizer = data.state->getRasterizerState();
rasterizer.pointDrawMode = (drawMode == GL_POINTS); rasterizer.pointDrawMode = (drawMode == GL_POINTS);
rasterizer.multiSample = (samples != 0); rasterizer.multiSample = (samples != 0);
unsigned int mask = GetBlendSampleMask(data, samples); unsigned int mask = GetBlendSampleMask(data, samples);
error = setBlendAndRasterizerState(data, mask); error = setBlendDepthRasterStates(data, mask);
if (error.isError()) if (error.isError())
{ {
return error; return error;
} }
// Setting depth stencil state
error = setDepthStencilState(*data.state);
mStateManager.resetDirtyBits(); mStateManager.resetDirtyBits();
return error; return error;
} }
gl::Error Renderer9::setBlendAndRasterizerState(const gl::Data &glData, GLenum drawMode) gl::Error Renderer9::setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode)
{ {
int samples = glData.state->getDrawFramebuffer()->getSamples(glData); int samples = glData.state->getDrawFramebuffer()->getSamples(glData);
gl::RasterizerState rasterizer = glData.state->getRasterizerState(); gl::RasterizerState rasterizer = glData.state->getRasterizerState();
...@@ -943,107 +940,7 @@ gl::Error Renderer9::setBlendAndRasterizerState(const gl::Data &glData, GLenum d ...@@ -943,107 +940,7 @@ gl::Error Renderer9::setBlendAndRasterizerState(const gl::Data &glData, GLenum d
rasterizer.multiSample = (samples != 0); rasterizer.multiSample = (samples != 0);
unsigned int mask = GetBlendSampleMask(glData, samples); unsigned int mask = GetBlendSampleMask(glData, samples);
return mStateManager.setBlendAndRasterizerState(*glData.state, mask); return mStateManager.setBlendDepthRasterStates(*glData.state, mask);
}
gl::Error Renderer9::setDepthStencilState(const gl::State &glState)
{
const auto &depthStencilState = glState.getDepthStencilState();
int stencilRef = glState.getStencilRef();
int stencilBackRef = glState.getStencilBackRef();
bool frontFaceCCW = (glState.getRasterizerState().frontFace == GL_CCW);
bool depthStencilStateChanged = mForceSetDepthStencilState ||
memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0;
bool stencilRefChanged = mForceSetDepthStencilState || stencilRef != mCurStencilRef ||
stencilBackRef != mCurStencilBackRef;
bool frontFaceCCWChanged = mForceSetDepthStencilState || frontFaceCCW != mCurFrontFaceCCW;
if (depthStencilStateChanged)
{
if (depthStencilState.depthTest)
{
mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
mDevice->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthStencilState.depthFunc));
}
else
{
mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
}
mCurDepthStencilState = depthStencilState;
}
if (depthStencilStateChanged || stencilRefChanged || frontFaceCCWChanged)
{
if (depthStencilState.stencilTest && mCurStencilSize > 0)
{
mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
// FIXME: Unsupported by D3D9
const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK;
// get the maximum size of the stencil ref
unsigned int maxStencil = (1 << mCurStencilSize) - 1;
ASSERT((depthStencilState.stencilWritemask & maxStencil) ==
(depthStencilState.stencilBackWritemask & maxStencil));
ASSERT(stencilRef == stencilBackRef);
ASSERT((depthStencilState.stencilMask & maxStencil) ==
(depthStencilState.stencilBackMask & maxStencil));
mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK,
depthStencilState.stencilWritemask);
mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
gl_d3d9::ConvertComparison(depthStencilState.stencilFunc));
mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF,
(stencilRef < (int)maxStencil) ? stencilRef : maxStencil);
mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK,
depthStencilState.stencilMask);
mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
gl_d3d9::ConvertStencilOp(depthStencilState.stencilFail));
mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthFail));
mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthPass));
mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK,
depthStencilState.stencilBackWritemask);
mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
gl_d3d9::ConvertComparison(depthStencilState.stencilBackFunc));
mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF,
(stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil);
mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK,
depthStencilState.stencilBackMask);
mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackFail));
mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthFail));
mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthPass));
}
else
{
mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
}
mDevice->SetRenderState(D3DRS_ZWRITEENABLE, depthStencilState.depthMask ? TRUE : FALSE);
mCurStencilRef = stencilRef;
mCurStencilBackRef = stencilBackRef;
mCurFrontFaceCCW = frontFaceCCW;
}
mForceSetDepthStencilState = false;
return gl::Error(GL_NO_ERROR);
} }
void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
...@@ -1334,11 +1231,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt ...@@ -1334,11 +1231,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt
mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize); mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize);
if (!mDepthStencilInitialized || stencilSize != mCurStencilSize) mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize);
{
mCurStencilSize = stencilSize;
mForceSetDepthStencilState = true;
}
mAppliedDepthStencilSerial = depthStencilSerial; mAppliedDepthStencilSerial = depthStencilSerial;
mDepthStencilInitialized = true; mDepthStencilInitialized = true;
...@@ -2192,10 +2085,10 @@ void Renderer9::markAllStateDirty() ...@@ -2192,10 +2085,10 @@ void Renderer9::markAllStateDirty()
mDepthStencilInitialized = false; mDepthStencilInitialized = false;
mRenderTargetDescInitialized = false; mRenderTargetDescInitialized = false;
mForceSetDepthStencilState = true;
mForceSetScissor = true; mForceSetScissor = true;
mForceSetViewport = true; mForceSetViewport = true;
mStateManager.forceSetRasterState(); mStateManager.forceSetRasterState();
mStateManager.forceSetDepthStencilState();
mStateManager.forceSetBlendState(); mStateManager.forceSetBlendState();
ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size()); ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size());
......
...@@ -275,8 +275,7 @@ class Renderer9 : public RendererD3D ...@@ -275,8 +275,7 @@ class Renderer9 : public RendererD3D
WorkaroundsD3D generateWorkarounds() const override; WorkaroundsD3D generateWorkarounds() const override;
gl::Error setBlendAndRasterizerState(const gl::Data &glData, GLenum drawMode); gl::Error setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode);
gl::Error setDepthStencilState(const gl::State &glState);
void release(); void release();
...@@ -332,7 +331,6 @@ class Renderer9 : public RendererD3D ...@@ -332,7 +331,6 @@ class Renderer9 : public RendererD3D
unsigned int mAppliedDepthStencilSerial; unsigned int mAppliedDepthStencilSerial;
bool mDepthStencilInitialized; bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized; bool mRenderTargetDescInitialized;
unsigned int mCurStencilSize;
struct RenderTargetDesc struct RenderTargetDesc
{ {
...@@ -346,13 +344,6 @@ class Renderer9 : public RendererD3D ...@@ -346,13 +344,6 @@ class Renderer9 : public RendererD3D
StateManager9 mStateManager; StateManager9 mStateManager;
// previously set render states
bool mForceSetDepthStencilState;
gl::DepthStencilState mCurDepthStencilState;
int mCurStencilRef;
int mCurStencilBackRef;
bool mCurFrontFaceCCW;
bool mForceSetScissor; bool mForceSetScissor;
gl::Rectangle mCurScissor; gl::Rectangle mCurScissor;
bool mScissorEnabled; bool mScissorEnabled;
......
...@@ -22,6 +22,11 @@ StateManager9::StateManager9(Renderer9 *renderer9) ...@@ -22,6 +22,11 @@ StateManager9::StateManager9(Renderer9 *renderer9)
mCurSampleMask(0), mCurSampleMask(0),
mCurRasterState(), mCurRasterState(),
mCurDepthSize(0), mCurDepthSize(0),
mCurDepthStencilState(),
mCurStencilRef(0),
mCurStencilBackRef(0),
mCurFrontFaceCCW(0),
mCurStencilSize(0),
mRenderer9(renderer9), mRenderer9(renderer9),
mDirtyBits() mDirtyBits()
{ {
...@@ -35,6 +40,16 @@ StateManager9::StateManager9(Renderer9 *renderer9) ...@@ -35,6 +40,16 @@ StateManager9::StateManager9(Renderer9 *renderer9)
mRasterizerStateDirtyBits.set(DIRTY_BIT_CULL_MODE); mRasterizerStateDirtyBits.set(DIRTY_BIT_CULL_MODE);
mRasterizerStateDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); mRasterizerStateDirtyBits.set(DIRTY_BIT_DEPTH_BIAS);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_MASK);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
} }
StateManager9::~StateManager9() StateManager9::~StateManager9()
...@@ -51,9 +66,24 @@ void StateManager9::forceSetRasterState() ...@@ -51,9 +66,24 @@ void StateManager9::forceSetRasterState()
mDirtyBits |= mRasterizerStateDirtyBits; mDirtyBits |= mRasterizerStateDirtyBits;
} }
void StateManager9::forceSetDepthStencilState()
{
mDirtyBits |= mDepthStencilStateDirtyBits;
}
void StateManager9::updateStencilSizeIfChanged(bool depthStencilInitialized,
unsigned int stencilSize)
{
if (!depthStencilInitialized || stencilSize != mCurStencilSize)
{
mCurStencilSize = stencilSize;
forceSetDepthStencilState();
}
}
void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
{ {
for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits)) for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
{ {
switch (dirtyBit) switch (dirtyBit)
{ {
...@@ -154,6 +184,98 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits ...@@ -154,6 +184,98 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits
{ {
mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS);
} }
}
case gl::State::DIRTY_BIT_DEPTH_MASK:
if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask)
{
mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_MASK);
}
break;
case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest)
{
mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC);
}
break;
case gl::State::DIRTY_BIT_DEPTH_FUNC:
if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc)
{
mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC);
}
break;
case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest)
{
mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
// If we enable the stencil test, all of these must be set
mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
}
break;
case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
{
const gl::DepthStencilState &depthStencilState = state.getDepthStencilState();
if (depthStencilState.stencilFunc != mCurDepthStencilState.stencilFunc ||
depthStencilState.stencilMask != mCurDepthStencilState.stencilMask ||
state.getStencilRef() != mCurStencilRef)
{
mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
}
break;
}
case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
{
const gl::DepthStencilState &depthStencilState = state.getDepthStencilState();
if (depthStencilState.stencilBackFunc != mCurDepthStencilState.stencilBackFunc ||
depthStencilState.stencilBackMask != mCurDepthStencilState.stencilBackMask ||
state.getStencilBackRef() != mCurStencilBackRef)
{
mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
}
break;
}
case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
if (state.getDepthStencilState().stencilWritemask !=
mCurDepthStencilState.stencilWritemask)
{
mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
}
break;
case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
if (state.getDepthStencilState().stencilBackWritemask !=
mCurDepthStencilState.stencilBackWritemask)
{
mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
}
break;
case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
{
const gl::DepthStencilState &depthStencilState = state.getDepthStencilState();
if (depthStencilState.stencilFail != mCurDepthStencilState.stencilFail ||
depthStencilState.stencilPassDepthFail !=
mCurDepthStencilState.stencilPassDepthFail ||
depthStencilState.stencilPassDepthPass !=
mCurDepthStencilState.stencilPassDepthPass)
{
mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
}
break;
}
case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
{
const gl::DepthStencilState &depthStencilState = state.getDepthStencilState();
if (depthStencilState.stencilBackFail != mCurDepthStencilState.stencilBackFail ||
depthStencilState.stencilBackPassDepthFail !=
mCurDepthStencilState.stencilBackPassDepthFail ||
depthStencilState.stencilBackPassDepthPass !=
mCurDepthStencilState.stencilBackPassDepthPass)
{
mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
}
break; break;
} }
default: default:
...@@ -162,14 +284,26 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits ...@@ -162,14 +284,26 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits
} }
} }
gl::Error StateManager9::setBlendAndRasterizerState(const gl::State &glState, gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState,
unsigned int sampleMask) unsigned int sampleMask)
{ {
const gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); const gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
const gl::BlendState &blendState = glState.getBlendState(); const gl::BlendState &blendState = glState.getBlendState();
const gl::ColorF &blendColor = glState.getBlendColor(); const gl::ColorF &blendColor = glState.getBlendColor();
const gl::RasterizerState &rasterState = glState.getRasterizerState(); const gl::RasterizerState &rasterState = glState.getRasterizerState();
const auto &depthStencilState = glState.getDepthStencilState();
bool frontFaceCCW = (glState.getRasterizerState().frontFace == GL_CCW);
unsigned int maxStencil = (1 << mCurStencilSize) - 1;
// All the depth stencil states depends on the front face ccw variable
if (frontFaceCCW != mCurFrontFaceCCW)
{
forceSetDepthStencilState();
mCurFrontFaceCCW = frontFaceCCW;
}
for (auto dirtyBit : angle::IterateBitSet(mDirtyBits)) for (auto dirtyBit : angle::IterateBitSet(mDirtyBits))
{ {
switch (dirtyBit) switch (dirtyBit)
...@@ -199,6 +333,41 @@ gl::Error StateManager9::setBlendAndRasterizerState(const gl::State &glState, ...@@ -199,6 +333,41 @@ gl::Error StateManager9::setBlendAndRasterizerState(const gl::State &glState,
case DIRTY_BIT_DEPTH_BIAS: case DIRTY_BIT_DEPTH_BIAS:
setDepthBias(rasterState.polygonOffsetFill, rasterState.polygonOffsetFactor, setDepthBias(rasterState.polygonOffsetFill, rasterState.polygonOffsetFactor,
rasterState.polygonOffsetUnits); rasterState.polygonOffsetUnits);
break;
case DIRTY_BIT_STENCIL_DEPTH_MASK:
setDepthMask(depthStencilState.depthMask);
break;
case DIRTY_BIT_STENCIL_DEPTH_FUNC:
setDepthFunc(depthStencilState.depthTest, depthStencilState.depthFunc);
break;
case DIRTY_BIT_STENCIL_TEST_ENABLED:
setStencilTestEnabled(depthStencilState.stencilTest);
break;
case DIRTY_BIT_STENCIL_FUNCS_FRONT:
setStencilFuncsFront(depthStencilState.stencilFunc, depthStencilState.stencilMask,
glState.getStencilRef(), frontFaceCCW, maxStencil);
break;
case DIRTY_BIT_STENCIL_FUNCS_BACK:
setStencilFuncsBack(depthStencilState.stencilBackFunc,
depthStencilState.stencilBackMask, glState.getStencilBackRef(),
frontFaceCCW, maxStencil);
break;
case DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
setStencilWriteMask(depthStencilState.stencilWritemask, frontFaceCCW);
break;
case DIRTY_BIT_STENCIL_WRITEMASK_BACK:
setStencilBackWriteMask(depthStencilState.stencilBackWritemask, frontFaceCCW);
break;
case DIRTY_BIT_STENCIL_OPS_FRONT:
setStencilOpsFront(depthStencilState.stencilFail,
depthStencilState.stencilPassDepthFail,
depthStencilState.stencilPassDepthPass, frontFaceCCW);
break;
case DIRTY_BIT_STENCIL_OPS_BACK:
setStencilOpsBack(depthStencilState.stencilBackFail,
depthStencilState.stencilBackPassDepthFail,
depthStencilState.stencilBackPassDepthPass, frontFaceCCW);
break;
default: default:
break; break;
} }
...@@ -212,6 +381,132 @@ gl::Error StateManager9::setBlendAndRasterizerState(const gl::State &glState, ...@@ -212,6 +381,132 @@ gl::Error StateManager9::setBlendAndRasterizerState(const gl::State &glState,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
void StateManager9::setDepthFunc(bool depthTest, GLenum depthFunc)
{
if (depthTest)
{
IDirect3DDevice9 *device = mRenderer9->getDevice();
device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
device->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthFunc));
}
else
{
mRenderer9->getDevice()->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
}
mCurDepthStencilState.depthTest = depthTest;
mCurDepthStencilState.depthFunc = depthFunc;
}
void StateManager9::setStencilOpsFront(GLenum stencilFail,
GLenum stencilPassDepthFail,
GLenum stencilPassDepthPass,
bool frontFaceCCW)
{
// TODO(dianx) It may be slightly more efficient todo these and other similar areas
// with separate dirty bits.
IDirect3DDevice9 *device = mRenderer9->getDevice();
device->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
gl_d3d9::ConvertStencilOp(stencilFail));
device->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
gl_d3d9::ConvertStencilOp(stencilPassDepthFail));
device->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
gl_d3d9::ConvertStencilOp(stencilPassDepthPass));
mCurDepthStencilState.stencilFail = stencilFail;
mCurDepthStencilState.stencilPassDepthFail = stencilPassDepthFail;
mCurDepthStencilState.stencilPassDepthPass = stencilPassDepthPass;
}
void StateManager9::setStencilOpsBack(GLenum stencilBackFail,
GLenum stencilBackPassDepthFail,
GLenum stencilBackPassDepthPass,
bool frontFaceCCW)
{
IDirect3DDevice9 *device = mRenderer9->getDevice();
device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
gl_d3d9::ConvertStencilOp(stencilBackFail));
device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
gl_d3d9::ConvertStencilOp(stencilBackPassDepthFail));
device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
gl_d3d9::ConvertStencilOp(stencilBackPassDepthPass));
mCurDepthStencilState.stencilBackFail = stencilBackFail;
mCurDepthStencilState.stencilBackPassDepthFail = stencilBackPassDepthFail;
mCurDepthStencilState.stencilBackPassDepthPass = stencilBackPassDepthPass;
}
void StateManager9::setStencilBackWriteMask(GLuint stencilBackWriteMask, bool frontFaceCCW)
{
mRenderer9->getDevice()->SetRenderState(
!frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, stencilBackWriteMask);
mCurDepthStencilState.stencilBackWritemask = stencilBackWriteMask;
}
void StateManager9::setStencilFuncsBack(GLenum stencilBackFunc,
GLuint stencilBackMask,
GLint stencilBackRef,
bool frontFaceCCW,
unsigned int maxStencil)
{
IDirect3DDevice9 *device = mRenderer9->getDevice();
device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
gl_d3d9::ConvertComparison(stencilBackFunc));
device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF,
(stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil);
device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK,
stencilBackMask);
mCurDepthStencilState.stencilBackFunc = stencilBackFunc;
mCurStencilBackRef = stencilBackRef;
mCurDepthStencilState.stencilBackMask = stencilBackMask;
}
void StateManager9::setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW)
{
mRenderer9->getDevice()->SetRenderState(
frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, stencilWriteMask);
mCurDepthStencilState.stencilWritemask = stencilWriteMask;
}
void StateManager9::setStencilFuncsFront(GLenum stencilFunc,
GLuint stencilMask,
GLint stencilRef,
bool frontFaceCCW,
unsigned int maxStencil)
{
IDirect3DDevice9 *device = mRenderer9->getDevice();
device->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
gl_d3d9::ConvertComparison(stencilFunc));
device->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF,
(stencilRef < static_cast<int>(maxStencil)) ? stencilRef : maxStencil);
device->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, stencilMask);
mCurDepthStencilState.stencilFunc = stencilFunc;
mCurStencilRef = stencilRef;
mCurDepthStencilState.stencilMask = stencilMask;
}
void StateManager9::setStencilTestEnabled(bool stencilTestEnabled)
{
if (stencilTestEnabled && mCurStencilSize > 0)
{
mRenderer9->getDevice()->SetRenderState(D3DRS_STENCILENABLE, TRUE);
}
else
{
mRenderer9->getDevice()->SetRenderState(D3DRS_STENCILENABLE, FALSE);
}
mCurDepthStencilState.stencilTest = stencilTestEnabled;
}
void StateManager9::setDepthMask(bool depthMask)
{
mRenderer9->getDevice()->SetRenderState(D3DRS_ZWRITEENABLE, depthMask ? TRUE : FALSE);
mCurDepthStencilState.depthMask = depthMask;
}
// TODO(dianx) one bit for sampleAlphaToCoverage // TODO(dianx) one bit for sampleAlphaToCoverage
void StateManager9::setSampleAlphaToCoverage(bool enabled) void StateManager9::setSampleAlphaToCoverage(bool enabled)
{ {
......
...@@ -26,29 +26,29 @@ class StateManager9 final : angle::NonCopyable ...@@ -26,29 +26,29 @@ class StateManager9 final : angle::NonCopyable
void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
gl::Error setBlendAndRasterizerState(const gl::State &glState, unsigned int sampleMask); gl::Error setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask);
void forceSetBlendState(); void forceSetBlendState();
void forceSetRasterState(); void forceSetRasterState();
void forceSetDepthStencilState();
void updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize); void updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize);
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
void resetDirtyBits() { mDirtyBits.reset(); } void resetDirtyBits() { mDirtyBits.reset(); }
private: private:
// Blend state functions
void setBlendEnabled(bool enabled); void setBlendEnabled(bool enabled);
void setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor); void setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor);
void setBlendFuncsEquations(const gl::BlendState &blendState); void setBlendFuncsEquations(const gl::BlendState &blendState);
void setColorMask(const gl::Framebuffer *framebuffer, void setColorMask(const gl::Framebuffer *framebuffer,
bool red, bool red,
bool blue, bool blue,
bool green, bool green,
bool alpha); bool alpha);
void setSampleAlphaToCoverage(bool enabled); void setSampleAlphaToCoverage(bool enabled);
void setDither(bool dither); void setDither(bool dither);
void setSampleMask(unsigned int sampleMask); void setSampleMask(unsigned int sampleMask);
// Current raster state functions // Current raster state functions
...@@ -57,8 +57,34 @@ class StateManager9 final : angle::NonCopyable ...@@ -57,8 +57,34 @@ class StateManager9 final : angle::NonCopyable
GLfloat polygonOffsetFactor, GLfloat polygonOffsetFactor,
GLfloat polygonOffsetUnits); GLfloat polygonOffsetUnits);
// Depth stencil state functions
void setStencilOpsFront(GLenum stencilFail,
GLenum stencilPassDepthFail,
GLenum stencilPassDepthPass,
bool frontFaceCCW);
void setStencilOpsBack(GLenum stencilBackFail,
GLenum stencilBackPassDepthFail,
GLenum stencilBackPassDepthPass,
bool frontFaceCCW);
void setStencilBackWriteMask(GLuint stencilBackWriteMask, bool frontFaceCCW);
void setDepthFunc(bool depthTest, GLenum depthFunc);
void setStencilTestEnabled(bool enabled);
void setDepthMask(bool depthMask);
void setStencilFuncsFront(GLenum stencilFunc,
GLuint stencilMask,
GLint stencilRef,
bool frontFaceCCW,
unsigned int maxStencil);
void setStencilFuncsBack(GLenum stencilBackFunc,
GLuint stencilBackMask,
GLint stencilBackRef,
bool frontFaceCCW,
unsigned int maxStencil);
void setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW);
enum DirtyBitType enum DirtyBitType
{ {
// Blend dirty bits
DIRTY_BIT_BLEND_ENABLED, DIRTY_BIT_BLEND_ENABLED,
DIRTY_BIT_BLEND_COLOR, DIRTY_BIT_BLEND_COLOR,
DIRTY_BIT_BLEND_FUNCS_EQUATIONS, DIRTY_BIT_BLEND_FUNCS_EQUATIONS,
...@@ -67,9 +93,21 @@ class StateManager9 final : angle::NonCopyable ...@@ -67,9 +93,21 @@ class StateManager9 final : angle::NonCopyable
DIRTY_BIT_DITHER, DIRTY_BIT_DITHER,
DIRTY_BIT_SAMPLE_MASK, DIRTY_BIT_SAMPLE_MASK,
// Rasterizer dirty bits
DIRTY_BIT_CULL_MODE, DIRTY_BIT_CULL_MODE,
DIRTY_BIT_DEPTH_BIAS, DIRTY_BIT_DEPTH_BIAS,
// Depth stencil dirty bits
DIRTY_BIT_STENCIL_DEPTH_MASK,
DIRTY_BIT_STENCIL_DEPTH_FUNC,
DIRTY_BIT_STENCIL_TEST_ENABLED,
DIRTY_BIT_STENCIL_FUNCS_FRONT,
DIRTY_BIT_STENCIL_FUNCS_BACK,
DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
DIRTY_BIT_STENCIL_WRITEMASK_BACK,
DIRTY_BIT_STENCIL_OPS_FRONT,
DIRTY_BIT_STENCIL_OPS_BACK,
DIRTY_BIT_MAX DIRTY_BIT_MAX
}; };
...@@ -86,6 +124,19 @@ class StateManager9 final : angle::NonCopyable ...@@ -86,6 +124,19 @@ class StateManager9 final : angle::NonCopyable
unsigned int mCurDepthSize; unsigned int mCurDepthSize;
DirtyBits mRasterizerStateDirtyBits; DirtyBits mRasterizerStateDirtyBits;
// Currently applied depth stencil state
gl::DepthStencilState mCurDepthStencilState;
int mCurStencilRef;
int mCurStencilBackRef;
bool mCurFrontFaceCCW;
unsigned int mCurStencilSize;
DirtyBits mDepthStencilStateDirtyBits;
// FIXME: Unsupported by D3D9
static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK;
Renderer9 *mRenderer9; Renderer9 *mRenderer9;
DirtyBits mDirtyBits; DirtyBits mDirtyBits;
}; };
......
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