[Mesa-dev] [PATCH 1/5] anv: Disable stencil writes when both write masks are zero

Jason Ekstrand jason at jlekstrand.net
Thu Feb 2 04:07:22 UTC 2017


The only mechanism Vulkan provides for disabling stencil writes is to set
the stencil write mask to 0.  Since that is dynamic state, we have to move
handle it late during command buffer builder.  This helps Dota2 by a couple
percent because it allows the hardware to move the depth and stencil writes
to early in more cases.

v2 (Jason Ekstrand): Always initialize the new pipeline variable
---
 src/intel/vulkan/anv_private.h     | 1 +
 src/intel/vulkan/gen7_cmd_buffer.c | 4 ++++
 src/intel/vulkan/gen8_cmd_buffer.c | 8 ++++++++
 src/intel/vulkan/genX_pipeline.c   | 4 +++-
 4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index a0cb35c..4fe3ebc 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1465,6 +1465,7 @@ struct anv_pipeline {
 
    uint32_t                                     cs_right_mask;
 
+   bool                                         writes_stencil;
    bool                                         depth_clamp_enable;
 
    struct {
diff --git a/src/intel/vulkan/gen7_cmd_buffer.c b/src/intel/vulkan/gen7_cmd_buffer.c
index 8d68aba..013ed87 100644
--- a/src/intel/vulkan/gen7_cmd_buffer.c
+++ b/src/intel/vulkan/gen7_cmd_buffer.c
@@ -212,6 +212,10 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
 
          .BackfaceStencilTestMask = d->stencil_compare_mask.back & 0xff,
          .BackfaceStencilWriteMask = d->stencil_write_mask.back & 0xff,
+
+         .StencilBufferWriteEnable =
+            (d->stencil_write_mask.front || d->stencil_write_mask.back) &&
+            pipeline->writes_stencil,
       };
       GENX(DEPTH_STENCIL_STATE_pack)(NULL, depth_stencil_dw, &depth_stencil);
 
diff --git a/src/intel/vulkan/gen8_cmd_buffer.c b/src/intel/vulkan/gen8_cmd_buffer.c
index ab68872..8c8de62 100644
--- a/src/intel/vulkan/gen8_cmd_buffer.c
+++ b/src/intel/vulkan/gen8_cmd_buffer.c
@@ -224,6 +224,10 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
 
          .BackfaceStencilTestMask = d->stencil_compare_mask.back & 0xff,
          .BackfaceStencilWriteMask = d->stencil_write_mask.back & 0xff,
+
+         .StencilBufferWriteEnable =
+            (d->stencil_write_mask.front || d->stencil_write_mask.back) &&
+            pipeline->writes_stencil,
       };
       GENX(3DSTATE_WM_DEPTH_STENCIL_pack)(NULL, wm_depth_stencil_dw,
                                           &wm_depth_stencil);
@@ -271,6 +275,10 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
 
          .StencilReferenceValue = d->stencil_reference.front & 0xff,
          .BackfaceStencilReferenceValue = d->stencil_reference.back & 0xff,
+
+         .StencilBufferWriteEnable =
+            (d->stencil_write_mask.front || d->stencil_write_mask.back) &&
+            pipeline->writes_stencil,
       };
       GEN9_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, dwords, &wm_depth_stencil);
 
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index 9d28466..18fe48c 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -652,12 +652,15 @@ emit_ds_state(struct anv_pipeline *pipeline,
       /* We're going to OR this together with the dynamic state.  We need
        * to make sure it's initialized to something useful.
        */
+      pipeline->writes_stencil = false;
       memset(depth_stencil_dw, 0, sizeof(depth_stencil_dw));
       return;
    }
 
    /* VkBool32 depthBoundsTestEnable; // optional (depth_bounds_test) */
 
+   pipeline->writes_stencil = info->stencilTestEnable;
+
 #if GEN_GEN <= 7
    struct GENX(DEPTH_STENCIL_STATE) depth_stencil = {
 #else
@@ -669,7 +672,6 @@ emit_ds_state(struct anv_pipeline *pipeline,
       .DoubleSidedStencilEnable = true,
 
       .StencilTestEnable = info->stencilTestEnable,
-      .StencilBufferWriteEnable = info->stencilTestEnable,
       .StencilFailOp = vk_to_gen_stencil_op[info->front.failOp],
       .StencilPassDepthPassOp = vk_to_gen_stencil_op[info->front.passOp],
       .StencilPassDepthFailOp = vk_to_gen_stencil_op[info->front.depthFailOp],
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list