зеркало из https://github.com/AvaloniaUI/angle.git
Vulkan: Don't break the RP on masked/scissored clears
Bug: b/166809097 Change-Id: Iedd10a6528808e859c5693a2d30c98aca1a1159c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2390862 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Charlie Lao <cclao@google.com> Reviewed-by: Tim Van Patten <timvp@google.com>
This commit is contained in:
Родитель
d0d523f4b5
Коммит
b2944fcfe0
|
@ -1999,6 +1999,10 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
|
|||
|
||||
// Scissored-only clears are handled in clearImmediatelyWithRenderPassOp.
|
||||
ASSERT(clearColorBuffers.any() || clearStencil);
|
||||
|
||||
// Force start a new render pass for the depth clear to take effect.
|
||||
// UtilsVk::clearFramebuffer may not start a new render pass if there's one already started.
|
||||
ANGLE_TRY(flushDeferredClears(contextVk, clearArea));
|
||||
}
|
||||
|
||||
UtilsVk::ClearFramebufferParameters params = {};
|
||||
|
|
|
@ -1142,9 +1142,19 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
|
|||
ANGLE_TRY(ensureImageClearResourcesInitialized(contextVk));
|
||||
|
||||
const gl::Rectangle &scissoredRenderArea = params.clearArea;
|
||||
|
||||
vk::Framebuffer *currentFramebuffer = nullptr;
|
||||
vk::CommandBuffer *commandBuffer;
|
||||
ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer));
|
||||
|
||||
// Start a new render pass if not already started
|
||||
ANGLE_TRY(framebuffer->getFramebuffer(contextVk, ¤tFramebuffer, nullptr));
|
||||
if (contextVk->hasStartedRenderPassWithFramebuffer(currentFramebuffer))
|
||||
{
|
||||
commandBuffer = &contextVk->getStartedRenderPassCommands().getCommandBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer));
|
||||
}
|
||||
|
||||
ImageClearShaderParams shaderParams;
|
||||
shaderParams.clearValue = params.colorClearValue;
|
||||
|
|
|
@ -499,6 +499,46 @@ TEST_P(VulkanPerformanceCounterTest, SwapShouldInvalidateDepthAfterClear)
|
|||
EXPECT_EQ(expectedDepthClears, actualDepthClears);
|
||||
}
|
||||
|
||||
// Tests that masked color clears don't break the RP.
|
||||
TEST_P(VulkanPerformanceCounterTest, MaskedClearDoesNotBreakRenderPass)
|
||||
{
|
||||
const rx::vk::PerfCounters &counters = hackANGLE();
|
||||
|
||||
GLTexture texture;
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
GLFramebuffer framebuffer;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
||||
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
uint32_t expectedRenderPassCount = counters.renderPasses + 1;
|
||||
|
||||
// Mask color channels and clear the framebuffer multiple times.
|
||||
glClearColor(0.25f, 0.25f, 0.25f, 0.25f);
|
||||
glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
|
||||
glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glClearColor(0.75f, 0.75f, 0.75f, 0.75f);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
uint32_t actualRenderPassCount = counters.renderPasses;
|
||||
EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
|
||||
|
||||
EXPECT_PIXEL_NEAR(0, 0, 63, 127, 255, 191, 1);
|
||||
}
|
||||
|
||||
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest, ES3_VULKAN());
|
||||
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_ES31, ES31_VULKAN());
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче