Vulkan: Clear DS through render pass even if color is masked
Other than for a Qualcomm driver bug workaround, this makes a few
fallbacks unnecessary.
Bug: angleproject:2361
Change-Id: I8bdc8efba69527ca89bfa7b646a9d41e07f4f895
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1541669
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index a8da4c7..dc83afe 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -232,17 +232,30 @@
VkColorComponentFlags colorMaskFlags = contextVk->getClearColorMask();
bool maskedClearColor =
clearColor && (mActiveColorComponents & colorMaskFlags) != mActiveColorComponents;
+ bool clearColorWithRenderPassLoadOp = clearColor && !maskedClearColor;
+ bool clearAnyWithRenderPassLoadOp =
+ clearColorWithRenderPassLoadOp || clearDepth || clearStencil;
- if (!maskedClearColor && !isScissorTestEffectivelyEnabled &&
+ if (clearAnyWithRenderPassLoadOp && !isScissorTestEffectivelyEnabled &&
!contextVk->getRenderer()->getFeatures().disableClearWithRenderPassLoadOp)
{
- // Note(syoussefi): A possible optimization could be to allow depth/stencil clear in
- // presence of color mask, and leave the color clear to the following steps, i.e. start a
- // render pass with depth/stencil = Clear and have a subsequent draw call within the render
- // pass to clear the color. That could render some of the depth/stencil clear paths below
- // unnecessary.
- return clearWithRenderPassOp(contextVk, clearColor, clearDepth, clearStencil,
- contextVk->getClearColorValue().color, clearDepthStencilValue);
+ // If there's a color mask, only clear depth/stencil with render pass loadOp.
+ ANGLE_TRY(clearWithRenderPassOp(contextVk, clearColorWithRenderPassLoadOp, clearDepth,
+ clearStencil, contextVk->getClearColorValue().color,
+ clearDepthStencilValue));
+
+ // Fallback to other methods for whatever isn't cleared here.
+ clearDepth = false;
+ clearStencil = false;
+ if (clearColorWithRenderPassLoadOp)
+ {
+ clearColor = false;
+ }
+
+ if (!clearColor)
+ {
+ return angle::Result::Continue;
+ }
}
// The most costly clear mode is when we need to mask out specific color channels. This can
@@ -276,6 +289,9 @@
return angle::Result::Continue;
}
+ // Unless working around driver bugs, every clear should have been covered at this point.
+ ASSERT(contextVk->getRenderer()->getFeatures().disableClearWithRenderPassLoadOp);
+
// Standard Depth/stencil clear without scissor.
if (clearDepth || clearStencil)
{