Commit c6dc9d73 by Charlie Lao Committed by Commit Bot

Vulkan: Add a test and fix the bug with draw/invalidate/clear

This adds a test that does draw with depth enabled, then disable depth test but with depth mask still enabled. Then invalidate framebuffer and followed by a clear. That clear will go down clearWithCommand path and should still work and data stored. Bug: b/169590459 Change-Id: I6dd30d6a1e12ad7820d98fe79445c336cfa3a643 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2422081Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com> Commit-Queue: Charlie Lao <cclao@google.com>
parent e9a82849
......@@ -2202,6 +2202,7 @@ angle::Result FramebufferVk::clearWithCommand(
VkClearValue clearValue = getCorrectedColorClearValue(colorIndexGL, clearColorValue);
attachments.emplace_back(VkClearAttachment{
VK_IMAGE_ASPECT_COLOR_BIT, static_cast<uint32_t>(colorIndexGL), clearValue});
ASSERT(getColorDrawRenderTarget(colorIndexGL)->hasDefinedContent());
}
// Add depth and stencil to list of attachments as needed.
......@@ -2212,7 +2213,11 @@ angle::Result FramebufferVk::clearWithCommand(
dsAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
dsClearValue.depthStencil = clearDepthStencilValue;
// Explicitly mark a depth write because we are clearing the depth buffer.
renderpassCommands->onDepthAccess(vk::ResourceAccess::Write);
if (renderpassCommands->onDepthAccess(vk::ResourceAccess::Write))
{
// The attachment is no longer invalidated, so set mContentDefined to true
restoreDepthStencilDefinedContents();
}
}
if (clearStencil)
......@@ -2220,7 +2225,11 @@ angle::Result FramebufferVk::clearWithCommand(
dsAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
dsClearValue.depthStencil = clearDepthStencilValue;
// Explicitly mark a stencil write because we are clearing the stencil buffer.
renderpassCommands->onStencilAccess(vk::ResourceAccess::Write);
if (renderpassCommands->onStencilAccess(vk::ResourceAccess::Write))
{
// The attachment is no longer invalidated, so set mContentDefined to true
restoreDepthStencilDefinedContents();
}
}
if (dsAspectFlags != 0)
......
......@@ -1118,6 +1118,55 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDisableEnableDraw)
compareLoadCountersForInvalidateTest(counters, expected);
}
// Tests that an in renderpass clear after invalidate keeps content stored.
TEST_P(VulkanPerformanceCounterTest, InvalidateAndClear)
{
const rx::vk::PerfCounters &counters = hackANGLE();
rx::vk::PerfCounters expected;
// Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+0, Load+1, Stores+1)
setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 1, 0, 1, 1, &expected);
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
GLFramebuffer framebuffer;
GLTexture texture;
GLRenderbuffer renderbuffer;
setupClearAndDrawForInvalidateTest(&program, &framebuffer, &texture, &renderbuffer);
// Disable depth test but with depth mask enabled so that clear should still work.
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
// Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
ASSERT_GL_NO_ERROR();
// Do in-renderpass clear. This should result in StoreOp=STORE; mContentDefined = true.
glClearDepthf(1.0f);
glClear(GL_DEPTH_BUFFER_BIT);
ASSERT_GL_NO_ERROR();
// Use swapBuffers and then check how many loads and stores were actually done
swapBuffers();
compareDepthStencilCountersForInvalidateTest(counters, expected);
// Expect rpCount+1, depth(Clears+0, Loads+1, Stores+1), stencil(Clears+0, Load+1, Stores+1)
setExpectedCountersForInvalidateTest(counters, 0, 0, 1, 1, 0, 1, 1, &expected);
// Bind FBO again and try to use the depth buffer without clear. This should result in
// loadOp=LOAD and StoreOP=STORE
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDisable(GL_STENCIL_TEST);
ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
// Should pass depth test: (0.5+1.0)/2.0=0.75 < 1.0
drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
EXPECT_PIXEL_COLOR_EQ(5, 4, GLColor::blue);
compareDepthStencilCountersForInvalidateTest(counters, expected);
}
// Tests whether depth-stencil ContentDefined will be correct when:
//
// - Scenario: invalidate, detach D/S texture and modify it, attach D/S texture, draw with blend
......
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