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)
     {