anv: Disable stencil writes when both write masks are zero
authorJason Ekstrand <jason.ekstrand@intel.com>
Thu, 8 Dec 2016 04:31:12 +0000 (20:31 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 14 Feb 2017 22:18:55 +0000 (14:18 -0800)
Vulkan doesn't have a stencilWriteEnable bit like it does for depth.
Instead, you have a stencil mask.  Since the stencil mask is handled as
dynamic state, we have to handle it later during command buffer
construction.  This, combined with a later commit, seems to help Dota2
on my Broadwell GT3e desktop by a couple percent because it allows the
hardware to move the depth and stencil writes to early in more cases.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
src/intel/vulkan/anv_private.h
src/intel/vulkan/gen7_cmd_buffer.c
src/intel/vulkan/gen8_cmd_buffer.c
src/intel/vulkan/genX_pipeline.c

index ec791a42871f93b63e1347488d249e72b8275775..89ae8183799a733f5d4d6f43c77f8c7fddaa546a 100644 (file)
@@ -1471,6 +1471,7 @@ struct anv_pipeline {
 
    uint32_t                                     cs_right_mask;
 
+   bool                                         writes_stencil;
    bool                                         depth_clamp_enable;
 
    struct {
index 8d68aba9c9aff3b1d9deade9b1118a88e2a9ccf6..013ed8718a4c3f3f75948230cfd18b7706a6c62e 100644 (file)
@@ -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);
 
index ab68872a260b7f4100e61e566697ea99f4c13b64..8c8de622eb8634e98a983a0bf636085c697f744d 100644 (file)
@@ -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);
 
index 55d1e5571d7d239e893219a9e836b33f64ea1465..f641661db1b56935071061dc34784af1c193740d 100644 (file)
@@ -663,12 +663,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
@@ -680,7 +683,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],
@@ -707,7 +709,7 @@ emit_ds_state(struct anv_pipeline *pipeline,
    }
 
    if (!(aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) {
-      depth_stencil.StencilBufferWriteEnable = false;
+      pipeline->writes_stencil = false;
       depth_stencil.StencilTestFunction = PREFILTEROPALWAYS;
       depth_stencil.BackfaceStencilTestFunction = PREFILTEROPALWAYS;
    }