Commit 0df8fe44 by Jamie Madill

D3D11: Don't read or write to the unused depth buffer.

When using STENCIL8, we emulate it on D3D11 with D24S8, since there is no native stencil-only format. However in many places we would write to the depth part of this format, and confuse the D3D runtime when it would use the depth test. Fix this by never modifying the depth portion of the buffer, or reading from it. BUG=angleproject:1232 Change-Id: Ifd2e54eceae84e8deea85f439c132d07981b2286 Reviewed-on: https://chromium-review.googlesource.com/313996 Tryjob-Request: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 40eefabd
......@@ -325,6 +325,11 @@ size_t Framebuffer::getNumColorBuffers() const
return mData.mColorAttachments.size();
}
bool Framebuffer::hasDepth() const
{
return (mData.mDepthAttachment.isAttached() && mData.mDepthAttachment.getDepthSize() > 0);
}
bool Framebuffer::hasStencil() const
{
return (mData.mStencilAttachment.isAttached() && mData.mStencilAttachment.getStencilSize() > 0);
......
......@@ -117,6 +117,7 @@ class Framebuffer
bool isEnabledColorAttachment(size_t colorAttachment) const;
bool hasEnabledColorAttachment() const;
size_t getNumColorBuffers() const;
bool hasDepth() const;
bool hasStencil() const;
int getSamples(const gl::Data &data) const;
bool usingExtendedDrawBuffers() const;
......
......@@ -422,8 +422,7 @@ gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode)
return error;
}
error = setDepthStencilState(data.state->getDepthStencilState(), data.state->getStencilRef(),
data.state->getStencilBackRef(), rasterizer.frontFace == GL_CCW);
error = setDepthStencilState(*data.state);
if (error.isError())
{
return error;
......
......@@ -159,8 +159,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
const gl::ColorF &blendColor,
unsigned int sampleMask) = 0;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW) = 0;
virtual gl::Error setDepthStencilState(const gl::State &glState) = 0;
virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0;
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
......
......@@ -21,6 +21,7 @@
namespace rx
{
using namespace gl_d3d11;
template <typename mapType>
static void ClearStateMap(mapType &map)
......@@ -297,14 +298,23 @@ bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &a,
return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0;
}
gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState)
gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &originalState,
bool disableDepth,
ID3D11DepthStencilState **outDSState)
{
if (!mDevice)
{
return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized.");
}
DepthStencilStateMap::iterator keyIter = mDepthStencilStateCache.find(dsState);
gl::DepthStencilState glState = originalState;
if (disableDepth)
{
glState.depthTest = false;
glState.depthMask = false;
}
auto keyIter = mDepthStencilStateCache.find(glState);
if (keyIter != mDepthStencilStateCache.end())
{
DepthStencilStateCounterPair &state = keyIter->second;
......@@ -312,53 +322,55 @@ gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &ds
*outDSState = state.first;
return gl::Error(GL_NO_ERROR);
}
else
if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates)
{
if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates)
{
TRACE("Overflowed the limit of %u depth stencil states, removing the least recently used "
"to make room.", kMaxDepthStencilStates);
TRACE(
"Overflowed the limit of %u depth stencil states, removing the least recently used "
"to make room.",
kMaxDepthStencilStates);
DepthStencilStateMap::iterator leastRecentlyUsed = mDepthStencilStateCache.begin();
for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
auto leastRecentlyUsed = mDepthStencilStateCache.begin();
for (auto i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
{
if (i->second.second < leastRecentlyUsed->second.second)
{
if (i->second.second < leastRecentlyUsed->second.second)
{
leastRecentlyUsed = i;
}
leastRecentlyUsed = i;
}
SafeRelease(leastRecentlyUsed->second.first);
mDepthStencilStateCache.erase(leastRecentlyUsed);
}
SafeRelease(leastRecentlyUsed->second.first);
mDepthStencilStateCache.erase(leastRecentlyUsed);
}
D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 };
dsDesc.DepthEnable = dsState.depthTest ? TRUE : FALSE;
dsDesc.DepthWriteMask = gl_d3d11::ConvertDepthMask(dsState.depthMask);
dsDesc.DepthFunc = gl_d3d11::ConvertComparison(dsState.depthFunc);
dsDesc.StencilEnable = dsState.stencilTest ? TRUE : FALSE;
dsDesc.StencilReadMask = gl_d3d11::ConvertStencilMask(dsState.stencilMask);
dsDesc.StencilWriteMask = gl_d3d11::ConvertStencilMask(dsState.stencilWritemask);
dsDesc.FrontFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilFail);
dsDesc.FrontFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthFail);
dsDesc.FrontFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthPass);
dsDesc.FrontFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilFunc);
dsDesc.BackFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackFail);
dsDesc.BackFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthFail);
dsDesc.BackFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthPass);
dsDesc.BackFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilBackFunc);
ID3D11DepthStencilState *dx11DepthStencilState = NULL;
HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState);
if (FAILED(result) || !dx11DepthStencilState)
{
return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
}
D3D11_DEPTH_STENCIL_DESC dsDesc = {0};
dsDesc.DepthEnable = glState.depthTest ? TRUE : FALSE;
dsDesc.DepthWriteMask = ConvertDepthMask(glState.depthMask);
dsDesc.DepthFunc = ConvertComparison(glState.depthFunc);
dsDesc.StencilEnable = glState.stencilTest ? TRUE : FALSE;
dsDesc.StencilReadMask = ConvertStencilMask(glState.stencilMask);
dsDesc.StencilWriteMask = ConvertStencilMask(glState.stencilWritemask);
dsDesc.FrontFace.StencilFailOp = ConvertStencilOp(glState.stencilFail);
dsDesc.FrontFace.StencilDepthFailOp = ConvertStencilOp(glState.stencilPassDepthFail);
dsDesc.FrontFace.StencilPassOp = ConvertStencilOp(glState.stencilPassDepthPass);
dsDesc.FrontFace.StencilFunc = ConvertComparison(glState.stencilFunc);
dsDesc.BackFace.StencilFailOp = ConvertStencilOp(glState.stencilBackFail);
dsDesc.BackFace.StencilDepthFailOp = ConvertStencilOp(glState.stencilBackPassDepthFail);
dsDesc.BackFace.StencilPassOp = ConvertStencilOp(glState.stencilBackPassDepthPass);
dsDesc.BackFace.StencilFunc = ConvertComparison(glState.stencilBackFunc);
ID3D11DepthStencilState *dx11DepthStencilState = NULL;
HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState);
if (FAILED(result) || !dx11DepthStencilState)
{
return gl::Error(GL_OUT_OF_MEMORY,
"Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
}
mDepthStencilStateCache.insert(std::make_pair(dsState, std::make_pair(dx11DepthStencilState, mCounter++)));
mDepthStencilStateCache.insert(
std::make_pair(glState, std::make_pair(dx11DepthStencilState, mCounter++)));
*outDSState = dx11DepthStencilState;
return gl::Error(GL_NO_ERROR);
}
*outDSState = dx11DepthStencilState;
return gl::Error(GL_NO_ERROR);
}
std::size_t RenderStateCache::hashSamplerState(const gl::SamplerState &samplerState)
......
......@@ -36,7 +36,9 @@ class RenderStateCache : angle::NonCopyable
gl::Error getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, ID3D11BlendState **outBlendState);
gl::Error getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, ID3D11RasterizerState **outRasterizerState);
gl::Error getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState);
gl::Error getDepthStencilState(const gl::DepthStencilState &dsState,
bool disableDepth,
ID3D11DepthStencilState **outDSState);
gl::Error getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState);
private:
......
......@@ -1377,10 +1377,9 @@ gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer,
return mStateManager.setBlendState(framebuffer, blendState, blendColor, sampleMask);
}
gl::Error Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW)
gl::Error Renderer11::setDepthStencilState(const gl::State &glState)
{
return mStateManager.setDepthStencilState(depthStencilState, stencilRef, stencilBackRef);
return mStateManager.setDepthStencilState(glState);
}
void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
......
......@@ -127,10 +127,7 @@ class Renderer11 : public RendererD3D
const gl::ColorF &blendColor,
unsigned int sampleMask) override;
gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState,
int stencilRef,
int stencilBackRef,
bool frontFaceCCW) override;
gl::Error setDepthStencilState(const gl::State &glState) 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,
......
......@@ -333,12 +333,23 @@ 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)
gl::Error StateManager11::setDepthStencilState(const gl::State &glState)
{
if (mDepthStencilStateIsDirty)
const auto &fbo = *glState.getDrawFramebuffer();
// Disable the depth test/depth write if we are using a stencil-only attachment.
// This is because ANGLE emulates stencil-only with D24S8 on D3D11 - we should neither read
// nor write to the unused depth part of this emulated texture.
bool disableDepth = (!fbo.hasDepth() && fbo.hasStencil());
// CurDisableDepth is reset automatically here if we call forceSetDepthStencilState.
if (mDepthStencilStateIsDirty || !mCurDisableDepth.valid() ||
disableDepth != mCurDisableDepth.value())
{
const auto &depthStencilState = glState.getDepthStencilState();
int stencilRef = glState.getStencilRef();
int stencilBackRef = glState.getStencilBackRef();
// get the maximum size of the stencil ref
unsigned int maxStencil = 0;
if (depthStencilState.stencilTest && mCurStencilSize > 0)
......@@ -352,8 +363,8 @@ gl::Error StateManager11::setDepthStencilState(const gl::DepthStencilState &dept
(depthStencilState.stencilBackMask & maxStencil));
ID3D11DepthStencilState *dxDepthStencilState = NULL;
gl::Error error =
mStateCache->getDepthStencilState(depthStencilState, &dxDepthStencilState);
gl::Error error = mStateCache->getDepthStencilState(depthStencilState, disableDepth,
&dxDepthStencilState);
if (error.isError())
{
return error;
......@@ -376,6 +387,7 @@ gl::Error StateManager11::setDepthStencilState(const gl::DepthStencilState &dept
mCurDepthStencilState = depthStencilState;
mCurStencilRef = stencilRef;
mCurStencilBackRef = stencilBackRef;
mCurDisableDepth = disableDepth;
mDepthStencilStateIsDirty = false;
}
......
......@@ -34,9 +34,7 @@ class StateManager11 final : angle::NonCopyable
const gl::ColorF &blendColor,
unsigned int sampleMask);
gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState,
int stencilRef,
int stencilBackRef);
gl::Error setDepthStencilState(const gl::State &glState);
gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
......@@ -63,6 +61,7 @@ class StateManager11 final : angle::NonCopyable
int mCurStencilRef;
int mCurStencilBackRef;
unsigned int mCurStencilSize;
Optional<bool> mCurDisableDepth;
// Currenly applied rasterizer state
bool mRasterizerStateIsDirty;
......
......@@ -1031,9 +1031,13 @@ gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer,
return gl::Error(GL_NO_ERROR);
}
gl::Error Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW)
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 ||
......
......@@ -101,8 +101,7 @@ class Renderer9 : public RendererD3D
const gl::BlendState &blendState,
const gl::ColorF &blendColor,
unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW);
virtual gl::Error setDepthStencilState(const gl::State &glState);
virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
......
......@@ -387,9 +387,6 @@
1096 WIN : dEQP-GLES3.functional.fragment_ops.blend.fbo_srgb.equation_src_func_dst_func.reverse_subtract_one_minus_constant_alpha_one_minus_constant_color = FAIL
1096 WIN : dEQP-GLES3.functional.fragment_ops.random.* = FAIL
1096 WIN : dEQP-GLES3.functional.fragment_ops.interaction.basic_shader.* = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.render.resize.tex2d_rgba16f_stencil_rbo_stencil_index8 = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.render.resize.tex2d_rgba8_stencil_rbo_stencil_index8 = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.render.recreate_depth_stencil.tex2d_rgba8_stencil_rbo_stencil_index8 = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.color.tex3d.rgba32i = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.color.tex3d.rgba16ui = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.color.tex3d.rgba8i = FAIL
......@@ -417,11 +414,7 @@
1097 WIN : dEQP-GLES3.functional.fbo.color.repeated_clear.sample.tex2d.rg16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.color.repeated_clear.sample.tex2d.r32f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.color.repeated_clear.sample.tex2d.r16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.stencil.basic.depth32f_stencil8 = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.stencil.basic.depth24_stencil8 = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.stencil.basic.stencil_index8 = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.stencil.attach.depth_only = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.stencil.attach.stencil_only = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.rect.out_of_bounds_nearest = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.rect.out_of_bounds_reverse_src_x_nearest = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.rect.out_of_bounds_reverse_src_y_nearest = FAIL
......@@ -494,8 +487,6 @@
1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.r8_to_rg16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.r8_to_r32f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.conversion.r8_to_r16f = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.depth_stencil.stencil_index8_basic = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.depth_stencil.stencil_index8_scale = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba8_linear_out_of_bounds_blit_from_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.rgba8_linear_out_of_bounds_blit_to_default = FAIL
1097 WIN : dEQP-GLES3.functional.fbo.blit.default_framebuffer.srgb8_alpha8_linear_out_of_bounds_blit_from_default = FAIL
......
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