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)
// Setting scissors state
setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled());
// Setting rasterizer state
// Setting blend, depth stencil, and rasterizer states
int samples = framebufferObject->getSamples(data);
gl::RasterizerState rasterizer = data.state->getRasterizerState();
rasterizer.pointDrawMode = (drawMode == GL_POINTS);
rasterizer.multiSample = (samples != 0);
unsigned int mask = GetBlendSampleMask(data, samples);
error = setBlendAndRasterizerState(data, mask);
error = setBlendDepthRasterStates(data, mask);
if (error.isError())
{
return error;
}
// Setting depth stencil state
error = setDepthStencilState(*data.state);
mStateManager.resetDirtyBits();
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);
gl::RasterizerState rasterizer = glData.state->getRasterizerState();
......@@ -943,107 +940,7 @@ gl::Error Renderer9::setBlendAndRasterizerState(const gl::Data &glData, GLenum d
rasterizer.multiSample = (samples != 0);
unsigned int mask = GetBlendSampleMask(glData, samples);
return mStateManager.setBlendAndRasterizerState(*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);
return mStateManager.setBlendDepthRasterStates(*glData.state, mask);
}
void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
......@@ -1334,11 +1231,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt
mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize);
if (!mDepthStencilInitialized || stencilSize != mCurStencilSize)
{
mCurStencilSize = stencilSize;
mForceSetDepthStencilState = true;
}
mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize);
mAppliedDepthStencilSerial = depthStencilSerial;
mDepthStencilInitialized = true;
......@@ -2192,10 +2085,10 @@ void Renderer9::markAllStateDirty()
mDepthStencilInitialized = false;
mRenderTargetDescInitialized = false;
mForceSetDepthStencilState = true;
mForceSetScissor = true;
mForceSetViewport = true;
mStateManager.forceSetRasterState();
mStateManager.forceSetDepthStencilState();
mStateManager.forceSetBlendState();
ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size());
......
......@@ -275,8 +275,7 @@ class Renderer9 : public RendererD3D
WorkaroundsD3D generateWorkarounds() const override;
gl::Error setBlendAndRasterizerState(const gl::Data &glData, GLenum drawMode);
gl::Error setDepthStencilState(const gl::State &glState);
gl::Error setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode);
void release();
......@@ -332,7 +331,6 @@ class Renderer9 : public RendererD3D
unsigned int mAppliedDepthStencilSerial;
bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized;
unsigned int mCurStencilSize;
struct RenderTargetDesc
{
......@@ -346,13 +344,6 @@ class Renderer9 : public RendererD3D
StateManager9 mStateManager;
// previously set render states
bool mForceSetDepthStencilState;
gl::DepthStencilState mCurDepthStencilState;
int mCurStencilRef;
int mCurStencilBackRef;
bool mCurFrontFaceCCW;
bool mForceSetScissor;
gl::Rectangle mCurScissor;
bool mScissorEnabled;
......
......@@ -22,6 +22,11 @@ StateManager9::StateManager9(Renderer9 *renderer9)
mCurSampleMask(0),
mCurRasterState(),
mCurDepthSize(0),
mCurDepthStencilState(),
mCurStencilRef(0),
mCurStencilBackRef(0),
mCurFrontFaceCCW(0),
mCurStencilSize(0),
mRenderer9(renderer9),
mDirtyBits()
{
......@@ -35,6 +40,16 @@ StateManager9::StateManager9(Renderer9 *renderer9)
mRasterizerStateDirtyBits.set(DIRTY_BIT_CULL_MODE);
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()
......@@ -51,9 +66,24 @@ void StateManager9::forceSetRasterState()
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)
{
for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits))
for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
{
switch (dirtyBit)
{
......@@ -154,6 +184,98 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits
{
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;
}
default:
......@@ -162,14 +284,26 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits
}
}
gl::Error StateManager9::setBlendAndRasterizerState(const gl::State &glState,
unsigned int sampleMask)
gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState,
unsigned int sampleMask)
{
const gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
const gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
const gl::BlendState &blendState = glState.getBlendState();
const gl::ColorF &blendColor = glState.getBlendColor();
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))
{
switch (dirtyBit)
......@@ -199,6 +333,41 @@ gl::Error StateManager9::setBlendAndRasterizerState(const gl::State &glState,
case DIRTY_BIT_DEPTH_BIAS:
setDepthBias(rasterState.polygonOffsetFill, rasterState.polygonOffsetFactor,
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:
break;
}
......@@ -212,6 +381,132 @@ gl::Error StateManager9::setBlendAndRasterizerState(const gl::State &glState,
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
void StateManager9::setSampleAlphaToCoverage(bool enabled)
{
......
......@@ -26,29 +26,29 @@ class StateManager9 final : angle::NonCopyable
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 forceSetRasterState();
void forceSetDepthStencilState();
void updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize);
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
void resetDirtyBits() { mDirtyBits.reset(); }
private:
// Blend state functions
void setBlendEnabled(bool enabled);
void setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor);
void setBlendFuncsEquations(const gl::BlendState &blendState);
void setColorMask(const gl::Framebuffer *framebuffer,
bool red,
bool blue,
bool green,
bool alpha);
void setSampleAlphaToCoverage(bool enabled);
void setDither(bool dither);
void setSampleMask(unsigned int sampleMask);
// Current raster state functions
......@@ -57,8 +57,34 @@ class StateManager9 final : angle::NonCopyable
GLfloat polygonOffsetFactor,
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
{
// Blend dirty bits
DIRTY_BIT_BLEND_ENABLED,
DIRTY_BIT_BLEND_COLOR,
DIRTY_BIT_BLEND_FUNCS_EQUATIONS,
......@@ -67,9 +93,21 @@ class StateManager9 final : angle::NonCopyable
DIRTY_BIT_DITHER,
DIRTY_BIT_SAMPLE_MASK,
// Rasterizer dirty bits
DIRTY_BIT_CULL_MODE,
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
};
......@@ -86,6 +124,19 @@ class StateManager9 final : angle::NonCopyable
unsigned int mCurDepthSize;
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;
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