Mesa (main): vulkan/graphics_state: Improve the depth/stencil optimization code

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 19 23:53:37 UTC 2022


Module: Mesa
Branch: main
Commit: 07f5f159634eee84d7ff1078d65712ddf66c3c6d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=07f5f159634eee84d7ff1078d65712ddf66c3c6d

Author: Jason Ekstrand <jason.ekstrand at collabora.com>
Date:   Thu Jul 14 20:59:38 2022 -0500

vulkan/graphics_state: Improve the depth/stencil optimization code

We now disable stencil writes when the stencil test is disabled or when
both stencil write masks are zero.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17564>

---

 src/intel/vulkan/genX_pipeline.c       |  2 +-
 src/vulkan/runtime/vk_graphics_state.c | 47 ++++++++++++++++++++++++++--------
 src/vulkan/runtime/vk_graphics_state.h | 12 ++++++---
 3 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index 2508de9d66c..5fb805441a9 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -999,7 +999,7 @@ emit_ds_state(struct anv_graphics_pipeline *pipeline,
    }
 
    struct vk_depth_stencil_state ds = *ds_in;
-   vk_optimize_depth_stencil_state(&ds, ds_aspects);
+   vk_optimize_depth_stencil_state(&ds, ds_aspects, false);
    pipeline->writes_stencil = ds.stencil.write_enable;
    pipeline->stencil_test_enable = ds.stencil.test_enable;
    pipeline->writes_depth = ds.depth.write_enable;
diff --git a/src/vulkan/runtime/vk_graphics_state.c b/src/vulkan/runtime/vk_graphics_state.c
index 19a158306fa..d01050cb009 100644
--- a/src/vulkan/runtime/vk_graphics_state.c
+++ b/src/vulkan/runtime/vk_graphics_state.c
@@ -669,7 +669,8 @@ vk_dynamic_graphics_state_init_ds(struct vk_dynamic_graphics_state *dst,
 
 static bool
 optimize_stencil_face(struct vk_stencil_test_face_state *face,
-                      VkCompareOp depthCompareOp)
+                      VkCompareOp depthCompareOp,
+                      bool consider_write_mask)
 {
    /* If compareOp is ALWAYS then the stencil test will never fail and failOp
     * will never happen.  Set failOp to KEEP in this case.
@@ -692,6 +693,15 @@ optimize_stencil_face(struct vk_stencil_test_face_state *face,
        depthCompareOp == VK_COMPARE_OP_ALWAYS)
       face->op.depth_fail = VK_STENCIL_OP_KEEP;
 
+   /* If the write mask is zero, nothing will be written to the stencil buffer
+    * so it's as if all operations are KEEP.
+    */
+   if (consider_write_mask && face->write_mask == 0) {
+      face->op.pass = VK_STENCIL_OP_KEEP;
+      face->op.fail = VK_STENCIL_OP_KEEP;
+      face->op.depth_fail = VK_STENCIL_OP_KEEP;
+   }
+
    return face->op.fail != VK_STENCIL_OP_KEEP ||
           face->op.depth_fail != VK_STENCIL_OP_KEEP ||
           face->op.pass != VK_STENCIL_OP_KEEP;
@@ -699,24 +709,39 @@ optimize_stencil_face(struct vk_stencil_test_face_state *face,
 
 void
 vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
-                                VkImageAspectFlags ds_aspects)
+                                VkImageAspectFlags ds_aspects,
+                                bool consider_write_mask)
 {
    /* stencil.write_enable is a dummy right now that should always be true */
    assert(ds->stencil.write_enable);
 
+   /* From the Vulkan 1.3.221 spec:
+    *
+    *    "If there is no depth attachment then the depth test is skipped."
+    */
+   if (!(ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
+      ds->depth.test_enable = false;
+
+   /* From the Vulkan 1.3.221 spec:
+    *
+    *    "...or if there is no stencil attachment, the coverage mask is
+    *    unmodified by this operation."
+    */
+   if (!(ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT))
+      ds->stencil.test_enable = false;
+
    /* If the depth test is disabled, we won't be writing anything. Make sure we
     * treat the test as always passing later on as well.
-    *
-    * Also, the Vulkan spec requires that if either depth or stencil is not
-    * present, the pipeline is to act as if the test silently passes. In that
-    * case we won't write either.
     */
-   if (!ds->depth.test_enable || !(ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) {
+   if (!ds->depth.test_enable) {
       ds->depth.write_enable = false;
       ds->depth.compare_op = VK_COMPARE_OP_ALWAYS;
    }
 
-   if (!(ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) {
+   /* If the stencil test is disabled, we won't be writing anything. Make sure
+    * we treat the test as always passing later on as well.
+    */
+   if (!ds->stencil.test_enable) {
       ds->stencil.write_enable = false;
       ds->stencil.front.op.compare = VK_COMPARE_OP_ALWAYS;
       ds->stencil.back.op.compare = VK_COMPARE_OP_ALWAYS;
@@ -742,8 +767,10 @@ vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
    /* If the stencil ops are such that we don't actually ever modify the
     * stencil buffer, we should disable writes.
     */
-   if (!optimize_stencil_face(&ds->stencil.front, ds->depth.compare_op) &&
-       !optimize_stencil_face(&ds->stencil.back, ds->depth.compare_op))
+   if (!optimize_stencil_face(&ds->stencil.front, ds->depth.compare_op,
+                              consider_write_mask) &&
+       !optimize_stencil_face(&ds->stencil.back, ds->depth.compare_op,
+                              consider_write_mask))
       ds->stencil.write_enable = false;
 
    /* If the depth test always passes and we never write out depth, that's the
diff --git a/src/vulkan/runtime/vk_graphics_state.h b/src/vulkan/runtime/vk_graphics_state.h
index 3f204ae6332..415ff8d62cf 100644
--- a/src/vulkan/runtime/vk_graphics_state.h
+++ b/src/vulkan/runtime/vk_graphics_state.h
@@ -410,12 +410,16 @@ struct vk_depth_stencil_state {
  * hit.  This function attempts to optimize the depth stencil state and
  * disable writes and sometimes even testing whenever possible.
  *
- * @param[inout]  ds          The depth stencil state to optimize
- * @param[in]     ds_aspects  Which image aspects are present in the render
- *                            pass.
+ * @param[inout]  ds                   The depth stencil state to optimize
+ * @param[in]     ds_aspects           Which image aspects are present in the
+ *                                     render pass.
+ * @param[in]     consider_write_mask  If true, the write mask will be taken
+ *                                     into account when optimizing.  If
+ *                                     false, it will be ignored.
  */
 void vk_optimize_depth_stencil_state(struct vk_depth_stencil_state *ds,
-                                     VkImageAspectFlags ds_aspects);
+                                     VkImageAspectFlags ds_aspects,
+                                     bool consider_write_mask);
 
 struct vk_color_blend_attachment_state {
    /** VkPipelineColorBlendAttachmentState::blendEnable */



More information about the mesa-commit mailing list