Commit 74c179bb by Jamie Madill Committed by Commit Bot

Vulkan: Refresh descriptor sets on driver uniform change.

In some state change scenarios the driver uniforms would be updated but not reapplied to the current state. Fix this by setting the descriptor sets dirty when we dirty the driver uniforms. Includes a test using gl_DepthRange. Also fixes a bug with the upcoming line segment rasterization emulation. Bug: angleproject:2598 Bug: angleproject:2845 Change-Id: Ia66f3c86f9770ceb145069eec879fd8725111a76 Reviewed-on: https://chromium-review.googlesource.com/1240413Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 4ebd8f3d
......@@ -153,6 +153,16 @@ constexpr ImmutableString kFlippedPointCoordName = ImmutableString("flippedPoint
constexpr ImmutableString kFlippedFragCoordName = ImmutableString("flippedFragCoord");
constexpr ImmutableString kEmulatedDepthRangeParams = ImmutableString("ANGLEDepthRangeParams");
constexpr const char *kHalfRenderAreaHeight = "halfRenderAreaHeight";
constexpr const char *kViewportYScale = "viewportYScale";
constexpr const char *kInviewportYScale = "invViewportYScale";
constexpr const char *kDepthRange = "depthRange";
constexpr size_t kNumDriverUniforms = 6;
constexpr std::array<const char *, kNumDriverUniforms> kDriverUniformNames = {
{"viewport", kHalfRenderAreaHeight, kViewportYScale, kInviewportYScale, "padding",
kDepthRange}};
TIntermConstantUnion *CreateConstantFloat(float value)
{
const TType *constantType = StaticType::GetBasic<TBasicType::EbtFloat>();
......@@ -246,8 +256,7 @@ void ReplaceGLDepthRangeWithDriverUniform(TIntermBlock *root,
symbolTable->findBuiltIn(ImmutableString("gl_DepthRange"), 0));
// ANGLEUniforms.depthRange
TIntermBinary *angleEmulatedDepthRangeRef =
CreateDriverUniformRef(driverUniforms, "depthRange");
TIntermBinary *angleEmulatedDepthRangeRef = CreateDriverUniformRef(driverUniforms, kDepthRange);
// Use this variable instead of gl_DepthRange everywhere.
ReplaceVariableWithTyped(root, depthRangeVar, angleEmulatedDepthRangeRef);
......@@ -293,15 +302,6 @@ void AppendVertexShaderDepthCorrectionToMain(TIntermBlock *root, TSymbolTable *s
RunAtTheEndOfShader(root, assignment, symbolTable);
}
constexpr const char *kHalfRenderAreaHeight = "halfRenderAreaHeight";
constexpr const char *kViewportYScale = "viewportYScale";
constexpr const char *kInviewportYScale = "invViewportYScale";
constexpr size_t kNumDriverUniforms = 6;
constexpr std::array<const char *, kNumDriverUniforms> kDriverUniformNames = {
{"viewport", kHalfRenderAreaHeight, kViewportYScale, kInviewportYScale, "padding",
"depthRange"}};
// The AddDriverUniformsToShader operation adds an internal uniform block to a shader. The driver
// block is used to implement Vulkan-specific features and workarounds. Returns the driver uniforms
// variable.
......
......@@ -663,12 +663,12 @@ gl::Error ContextVk::syncState(const gl::Context *context, const gl::State::Dirt
mPipelineDesc->updateViewport(framebufferVk, glState.getViewport(),
glState.getNearPlane(), glState.getFarPlane(),
isViewportFlipEnabledForDrawFBO());
mDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
invalidateDriverUniforms();
break;
}
case gl::State::DIRTY_BIT_DEPTH_RANGE:
mPipelineDesc->updateDepthRange(glState.getNearPlane(), glState.getFarPlane());
mDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
invalidateDriverUniforms();
break;
case gl::State::DIRTY_BIT_BLEND_ENABLED:
mPipelineDesc->updateBlendEnabled(glState.isBlendEnabled());
......@@ -807,7 +807,7 @@ gl::Error ContextVk::syncState(const gl::Context *context, const gl::State::Dirt
glState.getDrawFramebuffer());
mPipelineDesc->updateStencilBackWriteMask(glState.getDepthStencilState(),
glState.getDrawFramebuffer());
mDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
invalidateDriverUniforms();
break;
}
case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
......@@ -900,7 +900,7 @@ gl::Error ContextVk::onMakeCurrent(const gl::Context *context)
const gl::State &glState = context->getGLState();
updateFlipViewportDrawFramebuffer(glState);
updateFlipViewportReadFramebuffer(glState);
mDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
invalidateDriverUniforms();
return gl::NoError();
}
......@@ -1031,6 +1031,12 @@ void ContextVk::invalidateCurrentTextures()
}
}
void ContextVk::invalidateDriverUniforms()
{
mDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
mDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS);
}
gl::Error ContextVk::dispatchCompute(const gl::Context *context,
GLuint numGroupsX,
GLuint numGroupsY,
......
......@@ -218,6 +218,7 @@ class ContextVk : public ContextImpl, public vk::Context
angle::Result updateDefaultAttribute(size_t attribIndex);
void invalidateCurrentTextures();
void invalidateDriverUniforms();
angle::Result handleDirtyDefaultAttribs(const gl::Context *context,
const gl::DrawCallParams &drawCallParams,
......
......@@ -640,6 +640,64 @@ TEST_P(StateChangeRenderTest, GenerateMipmap)
EXPECT_GL_NO_ERROR();
}
// Tests that gl_DepthRange syncs correctly after a change.
TEST_P(StateChangeRenderTest, DepthRangeUpdates)
{
// http://anglebug.com/2598: Seems to be an Intel driver bug.
ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL() && IsWindows());
constexpr char kFragCoordShader[] = R"(void main()
{
if (gl_DepthRange.near == 0.2)
{
gl_FragColor = vec4(1, 0, 0, 1);
}
else if (gl_DepthRange.near == 0.5)
{
gl_FragColor = vec4(0, 1, 0, 1);
}
else
{
gl_FragColor = vec4(0, 0, 1, 1);
}
})";
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFragCoordShader);
glUseProgram(program);
const auto &quadVertices = GetQuadVertices();
ASSERT_EQ(0, glGetAttribLocation(program, essl1_shaders::PositionAttrib()));
GLBuffer vertexBuffer;
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(quadVertices[0]),
quadVertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0u, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(0u);
// First, clear.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw to left half viewport with a first depth range.
glDepthRangef(0.2f, 1.0f);
glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR();
// Draw to right half viewport with a second depth range.
glDepthRangef(0.5f, 1.0f);
glViewport(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR();
// Verify left half of the framebuffer is red and right half is green.
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth() / 2, getWindowHeight(), GLColor::red);
EXPECT_PIXEL_RECT_EQ(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight(),
GLColor::green);
}
// Tests that D3D11 dirty bit updates don't forget about BufferSubData attrib updates.
TEST_P(StateChangeTest, VertexBufferUpdatedAfterDraw)
{
......
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