Commit 38d92b59 by JiangYizhou Committed by Commit Bot

Workaround Intel driver bug on D3D when renderering with no render target

When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel drivers < 4815. The rendering samples always pass neglecting discard statement in pixel shader. Two bugs are listed bellow, 1. When a framebuffer has no attachments, the pixel shader will be recompiled to drop 'SV_TARGET'. On Intel drivers, when using a pixel shader with no 'SV_TARGET' in a draw, pixels are always generated even if they should be discard by 'discard' statements. 2. When a framebuffer has no attachments, ID3D11BlendState.RenderTarget [].RenderTargetWriteMask were set to 0 in angle. If RenderTargetWriteMask is 0 and rendertarget is not set, then rendering samples also pass neglecting discard statement in pixel shader on Intel. So we add a dummy texture as render target to workaround this issue. BUG=angleproject:2152 TEST=FramebufferTest_ES31.RenderingLimitToDefaultFBOSizeWithNoAttachments/ES3_1_D3D11 TEST=dEQP-GLES31.functional.fbo.no_attachments.* TEST=dEQP-GLES31.functional.state_query.integer.max_framebuffer* TEST=dEQP-GLES31.functional.state_query.integer.max_color_texture_samples_* TEST=dEQP-GLES31.functional.state_query.integer.max_depth_texture_samples_* TEST=dEQP-GLES31.functional.state_query.integer.max_integer_samples_* Change-Id: I1cb974703b6c05c39b731d147f7c8c4fb7b5fe68 Reviewed-on: https://chromium-review.googlesource.com/741544Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 3a9090fa
......@@ -112,6 +112,17 @@ struct WorkaroundsD3D
// target slice will be selected in the geometry shader stage. The workaround flag is added to
// make it possible to select the code path in end2end and performance tests.
bool selectViewInGeometryShader = false;
// When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel
// drivers < 4815. The rendering samples always pass neglecting discard statements in pixel
// shader.
// 1. If rendertarget is not set, the pixel shader will be recompiled to drop 'SV_TARGET'.
// When using a pixel shader with no 'SV_TARGET' in a draw, the pixels are always generated even
// if they should be discard by 'discard' statements.
// 2. If ID3D11BlendState.RenderTarget[].RenderTargetWriteMask is 0 and rendertarget is not set,
// then rendering samples also pass neglecting discard statements in pixel shader.
// So we add a dummy texture as render target in such case. See http://anglebug.com/2152
bool addDummyTextureNoRenderTarget = false;
};
} // namespace angle
......
......@@ -369,6 +369,29 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl:
}
}
// When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel
// drivers < 4815. The rendering samples always pass neglecting discard statements in pixel
// shader. We add a dummy texture as render target in such case.
if (mRenderer->getWorkarounds().addDummyTextureNoRenderTarget &&
colorAttachmentsForRender.empty())
{
static_assert(static_cast<size_t>(activeProgramOutputs.size()) <= 32,
"Size of active program outputs should less or equal than 32.");
GLenum i = static_cast<GLenum>(
gl::ScanForward(static_cast<uint32_t>(activeProgramOutputs.bits())));
gl::Texture *dummyTex = nullptr;
// TODO(Jamie): Handle error if dummy texture can't be created.
ANGLE_SWALLOW_ERR(mRenderer->getIncompleteTexture(context, GL_TEXTURE_2D, &dummyTex));
if (dummyTex)
{
gl::ImageIndex index = gl::ImageIndex::Make2D(0);
gl::FramebufferAttachment *dummyAttach = new gl::FramebufferAttachment(
context, GL_TEXTURE, GL_COLOR_ATTACHMENT0_EXT + i, index, dummyTex);
colorAttachmentsForRender.push_back(dummyAttach);
}
}
mColorAttachmentsForRender = std::move(colorAttachmentsForRender);
mCurrentActiveProgramOutputs = activeProgramOutputs;
......
......@@ -80,12 +80,6 @@
#define ANGLE_SKIP_DXGI_1_2_CHECK 0
#endif
#ifdef _DEBUG
// this flag enables suppressing some spurious warnings that pop up in certain WebGL samples
// and conformance tests. to enable all warnings, remove this define.
#define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
#endif
namespace rx
{
......@@ -714,8 +708,8 @@ egl::Error Renderer11::initialize()
}
}
// Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
// Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
if (mCreateDebugDevice)
{
TRACE_EVENT0("gpu.angle", "Renderer11::initialize (HideWarnings)");
ID3D11InfoQueue *infoQueue;
......@@ -734,7 +728,6 @@ egl::Error Renderer11::initialize()
SafeRelease(infoQueue);
}
}
#endif
#if !defined(NDEBUG)
mDebug = d3d11::DynamicCastComObject<ID3D11Debug>(mDevice);
......
......@@ -2179,6 +2179,7 @@ angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps
workarounds.preAddTexelFetchOffsets = true;
workarounds.useSystemMemoryForConstantBuffers = true;
workarounds.disableB5G6R5Support = capsVersion < IntelDriverVersion(4539);
workarounds.addDummyTextureNoRenderTarget = capsVersion < IntelDriverVersion(4815);
if (IsSkylake(adapterDesc.DeviceId))
{
workarounds.callClearTwice = capsVersion < IntelDriverVersion(4771);
......
......@@ -42,9 +42,6 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.image_load_store.* = SKIP
// D3D11 Failing Tests
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_framebuffer_width_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_framebuffer_height_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_framebuffer_samples_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_compute_shared_memory_size_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_compute_atomic_counter_buffers_* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.integer.max_compute_atomic_counters_* = FAIL
......
......@@ -699,7 +699,7 @@ TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
const std::string &fragShader =
"#version 310 es\n"
"uniform layout(location = 0) highp ivec2 u_expectedSize;\n"
"out layout(location = 0) mediump vec4 f_color;\n\n"
"out layout(location = 5) mediump vec4 f_color;\n\n"
"void main()\n"
"{\n"
" if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;\n"
......@@ -739,6 +739,7 @@ TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
......@@ -748,15 +749,19 @@ TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
GLuint height = 2;
glBindTexture(GL_TEXTURE_2D, mTexture.get());
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture.get(),
const GLenum bufs[] = {GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT5};
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, mTexture.get(),
0);
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
glDrawBuffers(6, bufs);
validateSamplePass(query, passedCount, width, height);
// If fbo's attachment has been removed, the rendering size should be the same as framebuffer
// default size.
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, 0, 0, 0);
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
......
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