Module: Mesa
Branch: master
Commit: 6d6cbb73619b1244086914d2a1b83806a0482f5a
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=6d6cbb73619b1244086914d2a1b83806a0482f5a

Author: Samuel Iglesias Gonsálvez <[email protected]>
Date:   Tue Jan 19 10:07:28 2021 +0100

turnip: refactor how LRZ state is calculated

Signed-off-by: Samuel Iglesias Gonsálvez <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8615>

---

 src/freedreno/vulkan/tu_cmd_buffer.c | 106 +++++++++++++++++++++++++----------
 src/freedreno/vulkan/tu_pipeline.c   |  52 +++--------------
 src/freedreno/vulkan/tu_private.h    |  13 ++---
 3 files changed, 90 insertions(+), 81 deletions(-)

diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c 
b/src/freedreno/vulkan/tu_cmd_buffer.c
index 26391605f23..e68bdb31253 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -3234,6 +3234,77 @@ tu6_emit_tess_consts(struct tu_cmd_buffer *cmd,
    return VK_SUCCESS;
 }
 
+static void
+tu6_lrz_depth_mode(struct A6XX_GRAS_LRZ_CNTL *gras_lrz_cntl,
+                   VkCompareOp depthCompareOp,
+                   bool *invalidate_lrz)
+{
+   /* LRZ does not support some depth modes.
+    *
+    * The HW has a flag for GREATER and GREATER_OR_EQUAL modes which is used
+    * in freedreno, however there are some dEQP-VK tests that fail if we use 
here.
+    * Furthermore, blob disables LRZ on these comparison opcodes too.
+    *
+    * TODO: investigate if we can enable GREATER flag here.
+    */
+   switch (depthCompareOp) {
+   case VK_COMPARE_OP_ALWAYS:
+   case VK_COMPARE_OP_NOT_EQUAL:
+   case VK_COMPARE_OP_GREATER:
+   case VK_COMPARE_OP_GREATER_OR_EQUAL:
+      *invalidate_lrz = true;
+      gras_lrz_cntl->lrz_write = false;
+      break;
+   case VK_COMPARE_OP_EQUAL:
+   case VK_COMPARE_OP_NEVER:
+      gras_lrz_cntl->lrz_write = false;
+      break;
+   case VK_COMPARE_OP_LESS:
+   case VK_COMPARE_OP_LESS_OR_EQUAL:
+      break;
+   default:
+      unreachable("bad VK_COMPARE_OP value or uninitialized");
+      break;
+   };
+}
+
+static struct A6XX_GRAS_LRZ_CNTL
+tu6_calculate_lrz_state(struct tu_cmd_buffer *cmd,
+                        const uint32_t a)
+{
+   struct tu_pipeline *pipeline = cmd->state.pipeline;
+   struct A6XX_GRAS_LRZ_CNTL gras_lrz_cntl = { 0 };
+   bool invalidate_lrz = pipeline->lrz.force_disable_mask & 
TU_LRZ_FORCE_DISABLE_LRZ;
+   bool force_disable_write = pipeline->lrz.force_disable_mask & 
TU_LRZ_FORCE_DISABLE_WRITE;
+
+   gras_lrz_cntl.enable = cmd->state.rb_depth_cntl & 
A6XX_RB_DEPTH_CNTL_Z_ENABLE;
+   gras_lrz_cntl.lrz_write = cmd->state.rb_depth_cntl & 
A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE;
+   gras_lrz_cntl.z_test_enable = cmd->state.rb_depth_cntl & 
A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE;
+
+   VkCompareOp depth_compare_op = (cmd->state.rb_depth_cntl & 
A6XX_RB_DEPTH_CNTL_ZFUNC__MASK) >> A6XX_RB_DEPTH_CNTL_ZFUNC__SHIFT;
+   tu6_lrz_depth_mode(&gras_lrz_cntl, depth_compare_op, &invalidate_lrz);
+
+   /* Invalidate LRZ and disable write if stencil test is enabled */
+   bool stencil_test_enable = cmd->state.rb_stencil_cntl & 
A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE;
+   if (stencil_test_enable) {
+      force_disable_write = true;
+      invalidate_lrz = true;
+   }
+
+   if (force_disable_write)
+      gras_lrz_cntl.lrz_write = false;
+
+   if (invalidate_lrz) {
+      cmd->state.lrz.valid = false;
+   }
+
+   /* In case no depth attachment or invalid, we clear the gras_lrz_cntl 
register */
+   if (a == VK_ATTACHMENT_UNUSED || !cmd->state.lrz.valid)
+      memset(&gras_lrz_cntl, 0, sizeof(gras_lrz_cntl));
+
+   return gras_lrz_cntl;
+}
+
 static struct tu_draw_state
 tu6_build_lrz(struct tu_cmd_buffer *cmd)
 {
@@ -3241,38 +3312,15 @@ tu6_build_lrz(struct tu_cmd_buffer *cmd)
    struct tu_cs lrz_cs;
    struct tu_draw_state ds = tu_cs_draw_state(&cmd->sub_cs, &lrz_cs, 4);
 
-   if (cmd->state.pipeline->lrz.invalidate) {
-      /* LRZ is not valid for next draw commands, so don't use it until 
cleared */
-      cmd->state.lrz.valid = false;
-   }
-
-   if (a == VK_ATTACHMENT_UNUSED || !cmd->state.lrz.valid) {
-      tu_cs_emit_regs(&lrz_cs, A6XX_GRAS_LRZ_CNTL(0));
-      tu_cs_emit_regs(&lrz_cs, A6XX_RB_LRZ_CNTL(0));
-      return ds;
-   }
-
-   /* Disable LRZ writes when blend is enabled, since the
-    * resulting pixel value from the blend-draw
-    * depends on an earlier draw, which LRZ in the draw pass
-    * could early-reject if the previous blend-enabled draw wrote LRZ.
-    *
-    * TODO: We need to disable LRZ writes only for the binning pass.
-    * Therefore, we need to emit it in a separate draw state. We keep
-    * it disabled for sysmem path as well for the moment.
-    */
-   bool lrz_write = cmd->state.pipeline->lrz.write;
-   if (cmd->state.pipeline->lrz.blend_disable_write)
-      lrz_write = false;
+   struct A6XX_GRAS_LRZ_CNTL gras_lrz_cntl = tu6_calculate_lrz_state(cmd, a);
 
    tu_cs_emit_regs(&lrz_cs, A6XX_GRAS_LRZ_CNTL(
-      .enable = cmd->state.pipeline->lrz.enable,
-      .greater = cmd->state.pipeline->lrz.greater,
-      .lrz_write = lrz_write,
-      .z_test_enable = cmd->state.pipeline->lrz.z_test_enable,
-   ));
+      .enable = gras_lrz_cntl.enable,
+      .greater = gras_lrz_cntl.greater,
+      .lrz_write = gras_lrz_cntl.lrz_write,
+      .z_test_enable = gras_lrz_cntl.z_test_enable));
+   tu_cs_emit_regs(&lrz_cs, A6XX_RB_LRZ_CNTL(.enable = gras_lrz_cntl.enable));
 
-   tu_cs_emit_regs(&lrz_cs, A6XX_RB_LRZ_CNTL(.enable = 
cmd->state.pipeline->lrz.enable));
    return ds;
 }
 
diff --git a/src/freedreno/vulkan/tu_pipeline.c 
b/src/freedreno/vulkan/tu_pipeline.c
index 360992b0dbb..fee9c16401d 100644
--- a/src/freedreno/vulkan/tu_pipeline.c
+++ b/src/freedreno/vulkan/tu_pipeline.c
@@ -2717,55 +2717,13 @@ tu_pipeline_builder_parse_depth_stencil(struct 
tu_pipeline_builder *builder,
                                               .bfref = ds_info->back.reference 
& 0xff));
    }
 
-   if (ds_info->depthTestEnable) {
-      pipeline->lrz.write = ds_info->depthWriteEnable;
-      pipeline->lrz.invalidate = false;
-      pipeline->lrz.z_test_enable = true;
-
-      /* LRZ does not support some depth modes.
-       *
-       * The HW has a flag for GREATER and GREATER_OR_EQUAL modes which is used
-       * in freedreno, however there are some dEQP-VK tests that fail if we 
use here.
-       * Furthermore, blob disables LRZ on these comparison opcodes too.
-       *
-       * TODO: investigate if we can enable GREATER flag here.
-       */
-      switch(ds_info->depthCompareOp) {
-      case VK_COMPARE_OP_ALWAYS:
-      case VK_COMPARE_OP_NOT_EQUAL:
-      case VK_COMPARE_OP_GREATER:
-      case VK_COMPARE_OP_GREATER_OR_EQUAL:
-         pipeline->lrz.invalidate = true;
-         pipeline->lrz.write = false;
-         break;
-      case VK_COMPARE_OP_EQUAL:
-      case VK_COMPARE_OP_NEVER:
-         pipeline->lrz.enable = true;
-         pipeline->lrz.write = false;
-         break;
-      case VK_COMPARE_OP_LESS:
-      case VK_COMPARE_OP_LESS_OR_EQUAL:
-         pipeline->lrz.enable = true;
-         break;
-      default:
-         unreachable("bad VK_COMPARE_OP value");
-         break;
-      };
-   }
-
-   if (ds_info->stencilTestEnable) {
-      pipeline->lrz.write = false;
-      pipeline->lrz.invalidate = true;
-   }
-
    if (builder->shaders[MESA_SHADER_FRAGMENT]) {
       const struct ir3_shader_variant *fs = 
&builder->shaders[MESA_SHADER_FRAGMENT]->ir3_shader->variants[0];
       if (fs->has_kill || fs->no_earlyz || fs->writes_pos) {
-         pipeline->lrz.write = false;
+         pipeline->lrz.force_disable_mask |= TU_LRZ_FORCE_DISABLE_WRITE;
       }
       if (fs->no_earlyz || fs->writes_pos) {
-         pipeline->lrz.enable = false;
-         pipeline->lrz.z_test_enable = false;
+         pipeline->lrz.force_disable_mask = TU_LRZ_FORCE_DISABLE_LRZ;
       }
    }
 }
@@ -2825,9 +2783,13 @@ tu_pipeline_builder_parse_multisample_and_color_blend(
           * From the PoV of LRZ, having masked color channels is
           * the same as having blend enabled, in that the draw will
           * care about the fragments from an earlier draw.
+          *
+          * TODO: We need to disable LRZ writes only for the binning pass.
+          * Therefore, we need to emit it in a separate draw state. We keep
+          * it disabled for sysmem path as well for the moment.
           */
          if (blendAttachment.blendEnable || blendAttachment.colorWriteMask != 
0xf) {
-            pipeline->lrz.blend_disable_write = true;
+            pipeline->lrz.force_disable_mask |= TU_LRZ_FORCE_DISABLE_WRITE;
          }
       }
    }
diff --git a/src/freedreno/vulkan/tu_private.h 
b/src/freedreno/vulkan/tu_private.h
index 1fd5bd5b153..13fc085abbc 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -836,15 +836,14 @@ struct tu_cache_state {
    enum tu_cmd_flush_bits flush_bits;
 };
 
+enum tu_lrz_force_disable_mask {
+   TU_LRZ_FORCE_DISABLE_LRZ = 1 << 0,
+   TU_LRZ_FORCE_DISABLE_WRITE = 1 << 1,
+};
+
 struct tu_lrz_pipeline
 {
-   bool write : 1;
-   bool invalidate : 1;
-
-   bool enable : 1;
-   bool greater : 1;
-   bool z_test_enable : 1;
-   bool blend_disable_write : 1;
+   uint32_t force_disable_mask;
 };
 
 struct tu_lrz_state

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to