Scissor test state is set as part of the Renderer::setScissor method.
TRAC #22206
Moved scissorTest out of RasterizerState.
Fixes buffer-offscreen-test and buffer-preserve-test CTS regressions.
Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1549 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 2250b80..911a3ed 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -50,7 +50,7 @@
mState.rasterizer.polygonOffsetFill = false;
mState.rasterizer.polygonOffsetFactor = 0.0f;
mState.rasterizer.polygonOffsetUnits = 0.0f;
- mState.rasterizer.scissorTest = false;
+ mState.scissorTest = false;
mState.scissor.x = 0;
mState.scissor.y = 0;
mState.scissor.width = 0;
@@ -523,12 +523,12 @@
void Context::setScissorTest(bool enabled)
{
- mState.rasterizer.scissorTest = enabled;
+ mState.scissorTest = enabled;
}
bool Context::isScissorTestEnabled() const
{
- return mState.rasterizer.scissorTest;
+ return mState.scissorTest;
}
void Context::setDither(bool enabled)
@@ -1211,7 +1211,7 @@
case GL_POLYGON_OFFSET_FILL: *params = mState.rasterizer.polygonOffsetFill; break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.blend.sampleAlphaToCoverage; break;
case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break;
- case GL_SCISSOR_TEST: *params = mState.rasterizer.scissorTest; break;
+ case GL_SCISSOR_TEST: *params = mState.scissorTest; break;
case GL_STENCIL_TEST: *params = mState.depthStencil.stencilTest; break;
case GL_DEPTH_TEST: *params = mState.depthStencil.depthTest; break;
case GL_BLEND: *params = mState.blend.blend; break;
@@ -1723,7 +1723,7 @@
}
mDxUniformsDirty = false;
- mRenderer->setScissorRectangle(mState.scissor);
+ mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
return true;
}
@@ -2738,7 +2738,7 @@
Rectangle sourceScissoredRect = sourceRect;
Rectangle destScissoredRect = destRect;
- if (mState.rasterizer.scissorTest)
+ if (mState.scissorTest)
{
// Only write to parts of the destination framebuffer which pass the scissor test.
if (destRect.x < mState.scissor.x)
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index f6fbac2..16c4afc 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -145,6 +145,7 @@
int stencilClearValue;
RasterizerState rasterizer;
+ bool scissorTest;
Rectangle scissor;
BlendState blend;
diff --git a/src/libGLESv2/angletypes.h b/src/libGLESv2/angletypes.h
index 31ce78a..33a4ae5 100644
--- a/src/libGLESv2/angletypes.h
+++ b/src/libGLESv2/angletypes.h
@@ -55,8 +55,6 @@
bool polygonOffsetFill;
GLfloat polygonOffsetFactor;
GLfloat polygonOffsetUnits;
-
- bool scissorTest;
};
struct BlendState
diff --git a/src/libGLESv2/renderer/RenderStateCache.cpp b/src/libGLESv2/renderer/RenderStateCache.cpp
index 88add36..5c36fb8 100644
--- a/src/libGLESv2/renderer/RenderStateCache.cpp
+++ b/src/libGLESv2/renderer/RenderStateCache.cpp
@@ -168,7 +168,7 @@
}
ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState,
- unsigned int depthSize)
+ bool scissorEnabled, unsigned int depthSize)
{
if (!mDevice)
{
@@ -178,6 +178,7 @@
RasterizerStateKey key;
key.rasterizerState = rasterState;
+ key.scissorEnabled = scissorEnabled;
key.depthSize = depthSize;
RasterizerStateMap::iterator i = mRasterizerStateCache.find(key);
@@ -215,7 +216,7 @@
rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of zero will preform no clamping, must be tested though.
rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetUnits;
rasterDesc.DepthClipEnable = TRUE;
- rasterDesc.ScissorEnable = rasterState.scissorTest ? TRUE : FALSE;
+ rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE;
rasterDesc.MultisampleEnable = TRUE;
rasterDesc.AntialiasedLineEnable = FALSE;
diff --git a/src/libGLESv2/renderer/RenderStateCache.h b/src/libGLESv2/renderer/RenderStateCache.h
index 6c9e039..0fde432 100644
--- a/src/libGLESv2/renderer/RenderStateCache.h
+++ b/src/libGLESv2/renderer/RenderStateCache.h
@@ -31,7 +31,7 @@
// Increments refcount on the returned blend state, Release() must be called.
ID3D11BlendState *getBlendState(const gl::BlendState &blendState);
ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &rasterState,
- unsigned int depthSize);
+ bool scissorEnabled, unsigned int depthSize);
ID3D11DepthStencilState* getDepthStencilState(const gl::DepthStencilState &dsState);
private:
@@ -54,6 +54,7 @@
struct RasterizerStateKey
{
gl::RasterizerState rasterizerState;
+ bool scissorEnabled;
unsigned int depthSize;
};
static std::size_t hashRasterizerState(const RasterizerStateKey &rasterState);
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 08254f2..7e1b043 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -89,7 +89,7 @@
virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW) = 0;
- virtual void setScissorRectangle(const gl::Rectangle &scissor) = 0;
+ virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0;
virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, bool ignoreViewport,
gl::ProgramBinary *currentProgram, bool forceSetUniforms) = 0;
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index d1845b2..aa373ca 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -269,10 +269,11 @@
{
if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
{
- ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mCurDepthSize);
+ ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled,
+ mCurDepthSize);
if (!dxRasterState)
{
- ERR("NULL blend state returned by RenderStateCache::getRasterizerState, setting the "
+ ERR("NULL blend state returned by RenderStateCache::getRasterizerState, setting the default"
"rasterizer state.");
}
@@ -355,19 +356,29 @@
mForceSetDepthStencilState = false;
}
-void Renderer11::setScissorRectangle(const gl::Rectangle &scissor)
+void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
{
- if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0)
+ if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
+ enabled != mScissorEnabled)
{
- D3D11_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));
+ if (enabled)
+ {
+ D3D11_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));
- mDeviceContext->RSSetScissorRects(1, &rect);
+ mDeviceContext->RSSetScissorRects(1, &rect);
+ }
+
+ if (enabled != mScissorEnabled)
+ {
+ mForceSetRasterState = true;
+ }
mCurScissor = scissor;
+ mScissorEnabled = enabled;
}
mForceSetScissor = false;
@@ -720,9 +731,9 @@
return;
}
- if (mCurScissor.x > 0 || mCurScissor.y > 0 ||
- mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
- mCurScissor.y + mCurScissor.height < renderTarget->getHeight())
+ if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
+ mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
+ mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
{
// TODO: clearing of subregion of render target
UNIMPLEMENTED();
@@ -769,9 +780,9 @@
return;
}
- if (mCurScissor.x > 0 || mCurScissor.y > 0 ||
- mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
- mCurScissor.y + mCurScissor.height < renderTarget->getHeight())
+ if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
+ mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
+ mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
{
// TODO: clearing of subregion of depth stencil view
UNIMPLEMENTED();
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index 357bef2..877210f 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -55,7 +55,7 @@
virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW);
- virtual void setScissorRectangle(const gl::Rectangle &scissor);
+ virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, bool ignoreViewport,
gl::ProgramBinary *currentProgram, bool forceSetUniforms);
@@ -179,6 +179,7 @@
// Currently applied scissor rectangle
bool mForceSetScissor;
+ bool mScissorEnabled;
gl::Rectangle mCurScissor;
// Currently applied viewport
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index f4b9d4c..d2eac1c 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -644,8 +644,6 @@
mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
}
- mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, rasterState.scissorTest ? TRUE : FALSE);
-
if (rasterState.polygonOffsetFill)
{
if (mCurDepthSize > 0)
@@ -860,19 +858,27 @@
mForceSetDepthStencilState = false;
}
-void Renderer9::setScissorRectangle(const gl::Rectangle &scissor)
+void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
{
- bool scissorChanged = mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0;
+ bool scissorChanged = mForceSetScissor ||
+ memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
+ enabled != mScissorEnabled;
if (scissorChanged)
{
- 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);
+ 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;
}
diff --git a/src/libGLESv2/renderer/Renderer9.h b/src/libGLESv2/renderer/Renderer9.h
index eb79252..6420f0e 100644
--- a/src/libGLESv2/renderer/Renderer9.h
+++ b/src/libGLESv2/renderer/Renderer9.h
@@ -84,7 +84,7 @@
virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW);
- virtual void setScissorRectangle(const gl::Rectangle &scissor);
+ virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, bool ignoreViewport,
gl::ProgramBinary *currentProgram, bool forceSetUniforms);
@@ -241,6 +241,7 @@
bool mForceSetScissor;
gl::Rectangle mCurScissor;
+ bool mScissorEnabled;
unsigned int mCurRenderTargetWidth;
unsigned int mCurRenderTargetHeight;