Commit 8f36b846 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Optimize glFramebufferSubInvalidate

If glFramebufferSubInvalidate() is called with an area that covers the whole framebuffer, behave as if glFramebufferInvalidate() is called. This allows deferred clears to be removed for example, and attachment contents to be marked undefined. Bug: angleproject:4988 Change-Id: Iff3f291ea6c07abccc2740174d0451b432ac5da8 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2508977Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent aff43fa0
...@@ -359,11 +359,18 @@ angle::Result FramebufferVk::invalidateSub(const gl::Context *context, ...@@ -359,11 +359,18 @@ angle::Result FramebufferVk::invalidateSub(const gl::Context *context,
{ {
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
// If invalidateSub() covers the whole framebuffer area, make it behave as invalidate().
const gl::Rectangle completeRenderArea = getRotatedCompleteRenderArea(contextVk);
if (area.encloses(completeRenderArea))
{
return invalidateImpl(contextVk, count, attachments, false);
}
// If there are deferred clears, flush them. syncState may have accumulated deferred clears, // If there are deferred clears, flush them. syncState may have accumulated deferred clears,
// but if the framebuffer's attachments are used after this call not through the framebuffer, // but if the framebuffer's attachments are used after this call not through the framebuffer,
// those clears wouldn't get flushed otherwise (for example as the destination of // those clears wouldn't get flushed otherwise (for example as the destination of
// glCopyTex[Sub]Image, shader storage image, etc). // glCopyTex[Sub]Image, shader storage image, etc).
ANGLE_TRY(flushDeferredClears(contextVk, getRotatedCompleteRenderArea(contextVk))); ANGLE_TRY(flushDeferredClears(contextVk, completeRenderArea));
if (area.encloses(contextVk->getStartedRenderPassCommands().getRenderArea())) if (area.encloses(contextVk->getStartedRenderPassCommands().getRenderArea()))
{ {
......
...@@ -729,6 +729,45 @@ TEST_P(VulkanPerformanceCounterTest, Invalidate) ...@@ -729,6 +729,45 @@ TEST_P(VulkanPerformanceCounterTest, Invalidate)
compareLoadCountersForInvalidateTest(counters, expected); compareLoadCountersForInvalidateTest(counters, expected);
} }
// Similar to Invalidate, but uses glInvalidateSubFramebuffer such that the given area covers the
// whole framebuffer.
TEST_P(VulkanPerformanceCounterTest, InvalidateSub)
{
const rx::vk::PerfCounters &counters = hackANGLE();
rx::vk::PerfCounters expected;
// Expect rpCount+1, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+0, Load+0, Stores+0)
setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 0, 0, 0, &expected);
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
GLFramebuffer framebuffer;
GLTexture texture;
GLRenderbuffer renderbuffer;
setupClearAndDrawForInvalidateTest(&program, &framebuffer, &texture, &renderbuffer, false);
// Execute the scenario that this test is for:
// Invalidate (storeOp = DONT_CARE; mContentDefined = false)
const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
glInvalidateSubFramebuffer(GL_FRAMEBUFFER, 2, discards, -100, -100, kInvalidateTestSize + 200,
kInvalidateTestSize + 200);
ASSERT_GL_NO_ERROR();
// Ensure that the render pass wasn't broken
EXPECT_EQ(expected.renderPasses, counters.renderPasses);
// Use swapBuffers and then check how many loads and stores were actually done
swapBuffers();
compareDepthStencilCountersForInvalidateTest(counters, expected);
// Start and end another render pass, to check that the load ops are as expected
setAndIncrementLoadCountersForInvalidateTest(counters, 0, 0, &expected);
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
ASSERT_GL_NO_ERROR();
swapBuffers();
compareLoadCountersForInvalidateTest(counters, expected);
}
// Tests that another case does not break render pass, and that counts are correct: // Tests that another case does not break render pass, and that counts are correct:
// //
// - Scenario: invalidate, draw // - Scenario: invalidate, draw
......
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