Commit 96714af8 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Dirty pipeline and desc set after mid-RP clear with draw

If UtilsVk::clearFramebuffer issues a draw call on the currently open render pass (as opposed to starting one itself), ContextVk would be unaware of the fact that the graphics pipeline and descriptor sets have been changed. This change sets the necessary dirty bits for ContextVk to recover from a UtilsVk::clearFramebuffer call. Bug: chromium:1141040 Change-Id: I865220fb5b3b78bf4c6b6b2896e57d8a7490c270 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2493184 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 62d010f9
......@@ -5298,6 +5298,12 @@ void ContextVk::setDefaultUniformBlocksMinSizeForTesting(size_t minSize)
mDefaultUniformStorage.setMinimumSizeForTesting(minSize);
}
void ContextVk::invalidateGraphicsPipelineAndDescriptorSets()
{
mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE);
mGraphicsDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS);
}
angle::Result ContextVk::updateRenderPassDepthStencilAccess()
{
if (hasStartedRenderPass() && mDrawFramebuffer->getDepthStencilRenderTarget())
......
......@@ -681,6 +681,10 @@ class ContextVk : public ContextImpl, public vk::Context
void onSyncHelperInitialize() { mSyncObjectPendingFlush = true; }
// When UtilsVk issues a draw call on the currently running render pass, the pipelines and
// descriptor sets it binds need to be undone.
void invalidateGraphicsPipelineAndDescriptorSets();
private:
// Dirty bits.
enum DirtyBitType : size_t
......
......@@ -1517,7 +1517,12 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
ANGLE_TRY(contextVk->pauseOcclusionQueryIfActive());
commandBuffer->setScissor(0, 1, &scissor);
commandBuffer->draw(3, 0);
return contextVk->resumeOcclusionQueryIfActive();
ANGLE_TRY(contextVk->resumeOcclusionQueryIfActive());
// Make sure what's bound here is correctly reverted on the next draw.
contextVk->invalidateGraphicsPipelineAndDescriptorSets();
return angle::Result::Continue;
}
angle::Result UtilsVk::colorBlitResolve(ContextVk *contextVk,
......
......@@ -1908,7 +1908,6 @@ TEST_P(ClearTestES3, ClearThenMixedMaskedClear)
// Setup framebuffer.
GLRenderbuffer color;
glBindRenderbuffer(GL_RENDERBUFFER, color);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
......@@ -1972,6 +1971,66 @@ TEST_P(ClearTestES3, ClearThenMixedMaskedClear)
EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
}
// Test that draw without state change after masked clear works
TEST_P(ClearTestES3, DrawClearThenDrawWithoutStateChange)
{
swapBuffers();
constexpr GLsizei kSize = 16;
GLint maxDrawBuffers = 0;
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
ASSERT_GE(maxDrawBuffers, 4);
// Setup framebuffer.
GLRenderbuffer color;
glBindRenderbuffer(GL_RENDERBUFFER, color);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
GLFramebuffer fb;
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
EXPECT_GL_NO_ERROR();
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
// Clear color initially.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Mask color.
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
glUseProgram(drawColor);
GLint colorUniformLocation =
glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
ASSERT_NE(colorUniformLocation, -1);
// Initialize position attribute.
GLint posLoc = glGetAttribLocation(drawColor, essl1_shaders::PositionAttrib());
ASSERT_NE(-1, posLoc);
setupQuadVertexBuffer(0.5f, 1.0f);
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(posLoc);
// Draw red.
glViewport(0, 0, kSize, kSize);
glClearColor(0.0f, 1.0f, 0.0f, 0.0f);
glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 0.5f);
glDrawArrays(GL_TRIANGLES, 0, 6);
// Clear to green without any state change.
glClear(GL_COLOR_BUFFER_BIT);
// Draw red again without any state change.
glDrawArrays(GL_TRIANGLES, 0, 6);
// Verify that the color buffer is now red
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
}
// Test that clear stencil value is correctly masked to 8 bits.
TEST_P(ClearTest, ClearStencilMask)
{
......
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