Commit a8893120 by Dian Xiang

Using dirty bit notification for D3D9 scissor state

BUG=angleproject:1249 This is a continuation of D3D dirty bit refactor for D3D9 performance enhancements Change-Id: I480bb95414a1baf71e7768a1704b34ae55244ed1 Reviewed-on: https://chromium-review.googlesource.com/316917Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarDian Xiang <dianx@google.com>
parent 160d9ab7
...@@ -932,6 +932,11 @@ gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode) ...@@ -932,6 +932,11 @@ gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode)
return error; return error;
} }
void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
{
mStateManager.setScissorState(scissor, enabled);
}
gl::Error Renderer9::setBlendDepthRasterStates(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);
...@@ -943,33 +948,6 @@ gl::Error Renderer9::setBlendDepthRasterStates(const gl::Data &glData, GLenum dr ...@@ -943,33 +948,6 @@ gl::Error Renderer9::setBlendDepthRasterStates(const gl::Data &glData, GLenum dr
return mStateManager.setBlendDepthRasterStates(*glData.state, mask); return mStateManager.setBlendDepthRasterStates(*glData.state, mask);
} }
void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
{
bool scissorChanged = mForceSetScissor ||
memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
enabled != mScissorEnabled;
if (scissorChanged)
{
if (enabled)
{
RECT rect;
rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetDesc.width));
rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetDesc.height));
rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetDesc.width));
rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetDesc.height));
mDevice->SetScissorRect(&rect);
}
mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, enabled ? TRUE : FALSE);
mScissorEnabled = enabled;
mCurScissor = scissor;
}
mForceSetScissor = false;
}
void Renderer9::setViewport(const gl::Caps *caps, void Renderer9::setViewport(const gl::Caps *caps,
const gl::Rectangle &viewport, const gl::Rectangle &viewport,
float zNear, float zNear,
...@@ -978,6 +956,9 @@ void Renderer9::setViewport(const gl::Caps *caps, ...@@ -978,6 +956,9 @@ void Renderer9::setViewport(const gl::Caps *caps,
GLenum frontFace, GLenum frontFace,
bool ignoreViewport) bool ignoreViewport)
{ {
int renderTargetWidth = mStateManager.getRenderTargetWidth();
int renderTargetHeight = mStateManager.getRenderTargetHeight();
gl::Rectangle actualViewport = viewport; gl::Rectangle actualViewport = viewport;
float actualZNear = gl::clamp01(zNear); float actualZNear = gl::clamp01(zNear);
float actualZFar = gl::clamp01(zFar); float actualZFar = gl::clamp01(zFar);
...@@ -985,17 +966,19 @@ void Renderer9::setViewport(const gl::Caps *caps, ...@@ -985,17 +966,19 @@ void Renderer9::setViewport(const gl::Caps *caps,
{ {
actualViewport.x = 0; actualViewport.x = 0;
actualViewport.y = 0; actualViewport.y = 0;
actualViewport.width = static_cast<int>(mRenderTargetDesc.width); actualViewport.width = static_cast<int>(renderTargetWidth);
actualViewport.height = static_cast<int>(mRenderTargetDesc.height); actualViewport.height = static_cast<int>(renderTargetHeight);
actualZNear = 0.0f; actualZNear = 0.0f;
actualZFar = 1.0f; actualZFar = 1.0f;
} }
D3DVIEWPORT9 dxViewport; D3DVIEWPORT9 dxViewport;
dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width)); dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast<int>(renderTargetWidth));
dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height)); dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast<int>(renderTargetHeight));
dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.X)); dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(renderTargetWidth) -
dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.Y)); static_cast<int>(dxViewport.X));
dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(renderTargetHeight) -
static_cast<int>(dxViewport.Y));
dxViewport.MinZ = actualZNear; dxViewport.MinZ = actualZNear;
dxViewport.MaxZ = actualZFar; dxViewport.MaxZ = actualZFar;
...@@ -1230,7 +1213,6 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt ...@@ -1230,7 +1213,6 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt
} }
mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize); mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize);
mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize); mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize);
mAppliedDepthStencilSerial = depthStencilSerial; mAppliedDepthStencilSerial = depthStencilSerial;
...@@ -1239,13 +1221,10 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt ...@@ -1239,13 +1221,10 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt
if (renderTargetChanged || !mRenderTargetDescInitialized) if (renderTargetChanged || !mRenderTargetDescInitialized)
{ {
mForceSetScissor = true;
mForceSetViewport = true; mForceSetViewport = true;
mStateManager.forceSetBlendState(); mStateManager.forceSetBlendState();
mStateManager.forceSetScissorState();
mRenderTargetDesc.width = renderTargetWidth; mStateManager.setRenderTargetBounds(renderTargetWidth, renderTargetHeight);
mRenderTargetDesc.height = renderTargetHeight;
mRenderTargetDesc.format = renderTargetFormat;
mRenderTargetDescInitialized = true; mRenderTargetDescInitialized = true;
} }
...@@ -2020,14 +1999,17 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, ...@@ -2020,14 +1999,17 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams,
mDevice->SetStreamSourceFreq(i, 1); mDevice->SetStreamSourceFreq(i, 1);
} }
int renderTargetWidth = mStateManager.getRenderTargetWidth();
int renderTargetHeight = mStateManager.getRenderTargetHeight();
float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges
quad[0][0] = -0.5f; quad[0][0] = -0.5f;
quad[0][1] = mRenderTargetDesc.height - 0.5f; quad[0][1] = renderTargetHeight - 0.5f;
quad[0][2] = 0.0f; quad[0][2] = 0.0f;
quad[0][3] = 1.0f; quad[0][3] = 1.0f;
quad[1][0] = mRenderTargetDesc.width - 0.5f; quad[1][0] = renderTargetWidth - 0.5f;
quad[1][1] = mRenderTargetDesc.height - 0.5f; quad[1][1] = renderTargetHeight - 0.5f;
quad[1][2] = 0.0f; quad[1][2] = 0.0f;
quad[1][3] = 1.0f; quad[1][3] = 1.0f;
...@@ -2036,7 +2018,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, ...@@ -2036,7 +2018,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams,
quad[2][2] = 0.0f; quad[2][2] = 0.0f;
quad[2][3] = 1.0f; quad[2][3] = 1.0f;
quad[3][0] = mRenderTargetDesc.width - 0.5f; quad[3][0] = renderTargetWidth - 0.5f;
quad[3][1] = -0.5f; quad[3][1] = -0.5f;
quad[3][2] = 0.0f; quad[3][2] = 0.0f;
quad[3][3] = 1.0f; quad[3][3] = 1.0f;
...@@ -2085,11 +2067,11 @@ void Renderer9::markAllStateDirty() ...@@ -2085,11 +2067,11 @@ void Renderer9::markAllStateDirty()
mDepthStencilInitialized = false; mDepthStencilInitialized = false;
mRenderTargetDescInitialized = false; mRenderTargetDescInitialized = false;
mForceSetScissor = true;
mForceSetViewport = true; mForceSetViewport = true;
mStateManager.forceSetRasterState(); mStateManager.forceSetRasterState();
mStateManager.forceSetDepthStencilState(); mStateManager.forceSetDepthStencilState();
mStateManager.forceSetBlendState(); mStateManager.forceSetBlendState();
mStateManager.forceSetScissorState();
ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size()); ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size());
for (unsigned int i = 0; i < mCurVertexTextures.size(); i++) for (unsigned int i = 0; i < mCurVertexTextures.size(); i++)
......
...@@ -332,22 +332,10 @@ class Renderer9 : public RendererD3D ...@@ -332,22 +332,10 @@ class Renderer9 : public RendererD3D
bool mDepthStencilInitialized; bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized; bool mRenderTargetDescInitialized;
struct RenderTargetDesc
{
size_t width;
size_t height;
D3DFORMAT format;
};
RenderTargetDesc mRenderTargetDesc;
IDirect3DStateBlock9 *mMaskedClearSavedState; IDirect3DStateBlock9 *mMaskedClearSavedState;
StateManager9 mStateManager; StateManager9 mStateManager;
bool mForceSetScissor;
gl::Rectangle mCurScissor;
bool mScissorEnabled;
bool mForceSetViewport; bool mForceSetViewport;
gl::Rectangle mCurViewport; gl::Rectangle mCurViewport;
float mCurNear; float mCurNear;
......
...@@ -27,6 +27,8 @@ StateManager9::StateManager9(Renderer9 *renderer9) ...@@ -27,6 +27,8 @@ StateManager9::StateManager9(Renderer9 *renderer9)
mCurStencilBackRef(0), mCurStencilBackRef(0),
mCurFrontFaceCCW(0), mCurFrontFaceCCW(0),
mCurStencilSize(0), mCurStencilSize(0),
mCurScissorRect(),
mCurScissorEnabled(false),
mRenderer9(renderer9), mRenderer9(renderer9),
mDirtyBits() mDirtyBits()
{ {
...@@ -50,6 +52,9 @@ StateManager9::StateManager9(Renderer9 *renderer9) ...@@ -50,6 +52,9 @@ StateManager9::StateManager9(Renderer9 *renderer9)
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
mScissorStateDirtyBits.set(DIRTY_BIT_SCISSOR_ENABLED);
mScissorStateDirtyBits.set(DIRTY_BIT_SCISSOR_RECT);
} }
StateManager9::~StateManager9() StateManager9::~StateManager9()
...@@ -71,6 +76,11 @@ void StateManager9::forceSetDepthStencilState() ...@@ -71,6 +76,11 @@ void StateManager9::forceSetDepthStencilState()
mDirtyBits |= mDepthStencilStateDirtyBits; mDirtyBits |= mDepthStencilStateDirtyBits;
} }
void StateManager9::forceSetScissorState()
{
mDirtyBits |= mScissorStateDirtyBits;
}
void StateManager9::updateStencilSizeIfChanged(bool depthStencilInitialized, void StateManager9::updateStencilSizeIfChanged(bool depthStencilInitialized,
unsigned int stencilSize) unsigned int stencilSize)
{ {
...@@ -278,6 +288,20 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits ...@@ -278,6 +288,20 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits
} }
break; break;
} }
case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
if (state.isScissorTestEnabled() != mCurScissorEnabled)
{
mDirtyBits.set(DIRTY_BIT_SCISSOR_ENABLED);
// If scissor is enabled, we have to set the scissor rect
mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT);
}
break;
case gl::State::DIRTY_BIT_SCISSOR:
if (state.getScissor() != mCurScissorRect)
{
mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT);
}
break;
default: default:
break; break;
} }
...@@ -381,6 +405,44 @@ gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState, ...@@ -381,6 +405,44 @@ gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
// This is separate from the main state loop because other functions
// outside call only setScissorState to update scissor state
void StateManager9::setScissorState(const gl::Rectangle &scissor, bool enabled)
{
if (mDirtyBits.test(DIRTY_BIT_SCISSOR_ENABLED))
setScissorEnabled(enabled);
if (mDirtyBits.test(DIRTY_BIT_SCISSOR_RECT))
setScissorRect(scissor, enabled);
}
void StateManager9::setRenderTargetBounds(size_t width, size_t height)
{
mRenderTargetBounds.width = (int)width;
mRenderTargetBounds.height = (int)height;
}
void StateManager9::setScissorEnabled(bool scissorEnabled)
{
mRenderer9->getDevice()->SetRenderState(D3DRS_SCISSORTESTENABLE, scissorEnabled ? TRUE : FALSE);
mCurScissorEnabled = scissorEnabled;
}
void StateManager9::setScissorRect(const gl::Rectangle &scissor, bool enabled)
{
if (!enabled)
return;
RECT rect;
rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetBounds.width));
rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetBounds.height));
rect.right =
gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetBounds.width));
rect.bottom =
gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetBounds.height));
mRenderer9->getDevice()->SetScissorRect(&rect);
}
void StateManager9::setDepthFunc(bool depthTest, GLenum depthFunc) void StateManager9::setDepthFunc(bool depthTest, GLenum depthFunc)
{ {
if (depthTest) if (depthTest)
......
...@@ -27,13 +27,19 @@ class StateManager9 final : angle::NonCopyable ...@@ -27,13 +27,19 @@ 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 setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask); gl::Error setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask);
void setScissorState(const gl::Rectangle &scissor, bool enabled);
void forceSetBlendState(); void forceSetBlendState();
void forceSetRasterState(); void forceSetRasterState();
void forceSetDepthStencilState(); void forceSetDepthStencilState();
void forceSetScissorState();
void updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize); void updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize);
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize); void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
void setRenderTargetBounds(size_t width, size_t height);
int getRenderTargetWidth() const { return mRenderTargetBounds.width; }
int getRenderTargetHeight() const { return mRenderTargetBounds.height; }
void resetDirtyBits() { mDirtyBits.reset(); } void resetDirtyBits() { mDirtyBits.reset(); }
...@@ -82,6 +88,9 @@ class StateManager9 final : angle::NonCopyable ...@@ -82,6 +88,9 @@ class StateManager9 final : angle::NonCopyable
unsigned int maxStencil); unsigned int maxStencil);
void setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW); void setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW);
void setScissorEnabled(bool scissorEnabled);
void setScissorRect(const gl::Rectangle &scissor, bool enabled);
enum DirtyBitType enum DirtyBitType
{ {
// Blend dirty bits // Blend dirty bits
...@@ -108,6 +117,10 @@ class StateManager9 final : angle::NonCopyable ...@@ -108,6 +117,10 @@ class StateManager9 final : angle::NonCopyable
DIRTY_BIT_STENCIL_OPS_FRONT, DIRTY_BIT_STENCIL_OPS_FRONT,
DIRTY_BIT_STENCIL_OPS_BACK, DIRTY_BIT_STENCIL_OPS_BACK,
// Scissor dirty bits
DIRTY_BIT_SCISSOR_ENABLED,
DIRTY_BIT_SCISSOR_RECT,
DIRTY_BIT_MAX DIRTY_BIT_MAX
}; };
...@@ -132,6 +145,12 @@ class StateManager9 final : angle::NonCopyable ...@@ -132,6 +145,12 @@ class StateManager9 final : angle::NonCopyable
unsigned int mCurStencilSize; unsigned int mCurStencilSize;
DirtyBits mDepthStencilStateDirtyBits; DirtyBits mDepthStencilStateDirtyBits;
// Currently applied scissor states
gl::Rectangle mCurScissorRect;
bool mCurScissorEnabled;
gl::Extents mRenderTargetBounds;
DirtyBits mScissorStateDirtyBits;
// FIXME: Unsupported by D3D9 // FIXME: Unsupported by D3D9
static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF; static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK; static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
......
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