Commit 63ba357c by JiangYizhou Committed by Commit Bot

Enable depth buffer to workaround driver bug on Intel windows

Rendering with depth buffer disabled and stencil buffer enabled leads to memory leak if we set viewport a large size on Intel windows platforms. So we enable depth buffer if stencil buffer is enabled to workaround this issue. TEST=gl_test.exe --gtest_filter=GLClearFramebufferTestWithParam/GLClearFramebufferTest.ClearDepthStencil/0 TEST=conformance/rendering/rendering-stencil-large-viewport.html TEST=RenderStencilBufferTest.DrawWithLargeViewport/ES3_D3D11 BUG=782317 Change-Id: Idb185db296f13e3fa897534514e198651a56439f Reviewed-on: https://chromium-review.googlesource.com/809574 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 2768bc8a
......@@ -123,6 +123,11 @@ struct WorkaroundsD3D
// 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;
// Rendering with depth buffer disabled and stencil buffer enabled leads to memory leak if we
// set viewport a large size on Intel windows platforms. So we enable depth buffer if stencil
// buffer is enabled to workaround this issue. See http://crbug.com/782317
bool enableDepthBufferWhenStencilBufferEnabled = false;
};
} // namespace angle
......
......@@ -208,6 +208,14 @@ gl::Error RenderStateCache::getDepthStencilState(Renderer11 *renderer,
dsDesc.BackFace.StencilPassOp = ConvertStencilOp(glState.stencilBackPassDepthPass);
dsDesc.BackFace.StencilFunc = ConvertComparison(glState.stencilBackFunc);
if (renderer->getWorkarounds().enableDepthBufferWhenStencilBufferEnabled &&
dsDesc.StencilEnable && !dsDesc.DepthEnable)
{
dsDesc.DepthEnable = TRUE;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
}
d3d11::DepthStencilState dx11DepthStencilState;
ANGLE_TRY(renderer->allocateResource(dsDesc, &dx11DepthStencilState));
const auto &iter = mDepthStencilStateCache.Put(glState, std::move(dx11DepthStencilState));
......
......@@ -2207,6 +2207,8 @@ angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps
workarounds.useSystemMemoryForConstantBuffers = true;
workarounds.disableB5G6R5Support = capsVersion < IntelDriverVersion(4539);
workarounds.addDummyTextureNoRenderTarget = capsVersion < IntelDriverVersion(4815);
workarounds.enableDepthBufferWhenStencilBufferEnabled =
capsVersion >= IntelDriverVersion(4815);
if (IsSkylake(adapterDesc.DeviceId))
{
workarounds.callClearTwice = capsVersion < IntelDriverVersion(4771);
......
......@@ -73,6 +73,7 @@
'<(angle_path)/src/tests/gl_tests/ProgramPipelineTest.cpp',
'<(angle_path)/src/tests/gl_tests/ReadPixelsTest.cpp',
'<(angle_path)/src/tests/gl_tests/RendererTest.cpp',
'<(angle_path)/src/tests/gl_tests/RenderStencilBufferTest.cpp',
'<(angle_path)/src/tests/gl_tests/RobustBufferAccessBehaviorTest.cpp',
'<(angle_path)/src/tests/gl_tests/RobustClientMemoryTest.cpp',
'<(angle_path)/src/tests/gl_tests/RobustResourceInitTest.cpp',
......
//
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RenderStencilBufferTest:
// Reproduce driver bug on Intel windows and mac when rendering with stencil
// buffer enabled, depth buffer disabled and large viewport.
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
using namespace angle;
class RenderStencilBufferTest : public ANGLETest
{
protected:
RenderStencilBufferTest() : mProgram(0)
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
setConfigDepthBits(24);
setWebGLCompatibilityEnabled(true);
}
void SetUp() override
{
ANGLETest::SetUp();
const std::string vertexShaderSource =
R"(attribute vec4 position;
void main()
{
gl_Position = position;
})";
const std::string fragmentShaderSource =
R"(precision mediump float;
uniform vec4 u_draw_color;
void main()
{
gl_FragColor = u_draw_color;
})";
mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
ASSERT_NE(0u, mProgram);
glUseProgram(mProgram);
GLint positionLoc = glGetAttribLocation(mProgram, "position");
ASSERT_NE(-1, positionLoc);
setupQuadVertexBuffer(1.0f, 1.0f);
glEnableVertexAttribArray(positionLoc);
glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
GLint colorLoc = glGetUniformLocation(mProgram, "u_draw_color");
ASSERT_NE(-1, colorLoc);
glUniform4f(colorLoc, 1.0f, 0.0f, 0.0f, 1.0f);
ASSERT_GL_NO_ERROR();
glEnable(GL_STENCIL_TEST);
}
void TearDown() override
{
glDisable(GL_STENCIL_TEST);
if (mProgram != 0)
glDeleteProgram(mProgram);
ANGLETest::TearDown();
}
GLuint mProgram;
};
// This test reproduce driver bug on Intel windows platforms on driver version
// from 4815 to 4877.
// When rendering with Stencil buffer enabled and depth buffer disabled, and
// large viewport will lead to memory leak and driver crash. And the pixel
// result is a random value.
TEST_P(RenderStencilBufferTest, DrawWithLargeViewport)
{
ANGLE_SKIP_TEST_IF(IsIntel() && IsOSX());
// The iteration is to reproduce memory leak when rendering several times.
for (int i = 0; i < 10; ++i)
{
// Create offscreen fbo and its color attachment and depth stencil attachment.
GLTexture framebufferColorTexture;
glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
ASSERT_GL_NO_ERROR();
GLTexture framebufferStencilTexture;
glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, getWindowWidth(), getWindowHeight());
ASSERT_GL_NO_ERROR();
GLFramebuffer fb;
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
framebufferColorTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
framebufferStencilTexture, 0);
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
ASSERT_GL_NO_ERROR();
glEnable(GL_STENCIL_TEST);
glDisable(GL_DEPTH_TEST);
GLint kStencilRef = 4;
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
glStencilFunc(GL_ALWAYS, kStencilRef, 0xFF);
glViewport(0, 0, 16384, 16384);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR();
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
EXPECT_GL_NO_ERROR();
}
}
ANGLE_INSTANTIATE_TEST(RenderStencilBufferTest, ES3_D3D11(), ES3_OPENGL());
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