Mesa (main): turnip: apply workaround for depth bounds test without depth test

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Aug 19 13:33:26 UTC 2021


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

Author: Danylo Piliaiev <dpiliaiev at igalia.com>
Date:   Tue Aug 17 14:59:56 2021 +0300

turnip: apply workaround for depth bounds test without depth test

On some GPUs when:
- depth bounds test is enabled
- depth test is disabled
- depth attachment uses UBWC in sysmem mode
GPU hangs. As a workaround we should enable z test. That's what blob
is doing for a630. And since we enable z test we should make it always pass.

Blob doesn't emit this workaround on a650 and a660. Untested on a640.

Fixes:
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_static.depth_bounds_test_disable
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.depth_bounds_test_disable
 dEQP-VK.dynamic_state.ds_state.depth_bounds_1

Signed-off-by: Danylo Piliaiev <dpiliaiev at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12407>

---

 src/freedreno/common/freedreno_dev_info.h |  5 +++++
 src/freedreno/common/freedreno_devices.py |  2 ++
 src/freedreno/vulkan/tu_cmd_buffer.c      | 22 ++++++++++++++++++++++
 src/freedreno/vulkan/tu_pipeline.c        |  3 +++
 src/freedreno/vulkan/tu_private.h         |  3 +++
 5 files changed, 35 insertions(+)

diff --git a/src/freedreno/common/freedreno_dev_info.h b/src/freedreno/common/freedreno_dev_info.h
index 5bec6b0dc6d..d005bcd483b 100644
--- a/src/freedreno/common/freedreno_dev_info.h
+++ b/src/freedreno/common/freedreno_dev_info.h
@@ -86,6 +86,11 @@ struct fd_dev_info {
           */
          bool indirect_draw_wfm_quirk;
 
+         /* On some GPUs, the depth test needs to be enabled when the
+          * depth bounds test is enabled and the depth attachment uses UBWC.
+          */
+         bool depth_bounds_require_depth_test_quirk;
+
          bool has_tex_filter_cubic;
 
          bool has_sample_locations;
diff --git a/src/freedreno/common/freedreno_devices.py b/src/freedreno/common/freedreno_devices.py
index e02e4a0af78..e1eca08e593 100644
--- a/src/freedreno/common/freedreno_devices.py
+++ b/src/freedreno/common/freedreno_devices.py
@@ -200,6 +200,7 @@ a6xx_gen1 = dict(
         reg_size_vec4 = 96,
         ccu_cntl_gmem_unk2 = True,
         indirect_draw_wfm_quirk = True,
+        depth_bounds_require_depth_test_quirk = True,
     )
 
 # a640, a680:
@@ -209,6 +210,7 @@ a6xx_gen2 = dict(
         supports_multiview_mask = True,
         has_z24uint_s8uint = True,
         indirect_draw_wfm_quirk = True,
+        depth_bounds_require_depth_test_quirk = True, # TODO: check if true
     )
 
 # a650:
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index 5903dad7ff8..e8801b2340e 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -471,6 +471,24 @@ tu6_emit_window_offset(struct tu_cs *cs, uint32_t x1, uint32_t y1)
                    A6XX_SP_TP_WINDOW_OFFSET(.x = x1, .y = y1));
 }
 
+void
+tu6_apply_depth_bounds_workaround(struct tu_device *device,
+                                  uint32_t *rb_depth_cntl)
+{
+   return;
+   if (!device->physical_device->info->a6xx.depth_bounds_require_depth_test_quirk)
+      return;
+
+   /* On some GPUs it is necessary to enable z test for depth bounds test when
+    * UBWC is enabled. Otherwise, the GPU would hang. FUNC_ALWAYS is required to
+    * pass z test. Relevant tests:
+    *  dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.depth_bounds_test_disable
+    *  dEQP-VK.dynamic_state.ds_state.depth_bounds_1
+    */
+   *rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE |
+                     A6XX_RB_DEPTH_CNTL_ZFUNC(FUNC_ALWAYS);
+}
+
 static void
 tu_cs_emit_draw_state(struct tu_cs *cs, uint32_t id, struct tu_draw_state state)
 {
@@ -3743,6 +3761,10 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
           (rb_depth_cntl & A6XX_RB_DEPTH_CNTL_Z_BOUNDS_ENABLE))
          rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_READ_ENABLE;
 
+      if ((rb_depth_cntl & A6XX_RB_DEPTH_CNTL_Z_BOUNDS_ENABLE) &&
+          !(rb_depth_cntl & A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE))
+         tu6_apply_depth_bounds_workaround(cmd->device, &rb_depth_cntl);
+
       if (pipeline->rb_depth_cntl_disable)
          rb_depth_cntl = 0;
 
diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c
index 12a9e3ee88f..fc4afd9e9fd 100644
--- a/src/freedreno/vulkan/tu_pipeline.c
+++ b/src/freedreno/vulkan/tu_pipeline.c
@@ -2806,6 +2806,9 @@ tu_pipeline_builder_parse_depth_stencil(struct tu_pipeline_builder *builder,
 
       if (ds_info->depthBoundsTestEnable)
          rb_depth_cntl |= A6XX_RB_DEPTH_CNTL_Z_BOUNDS_ENABLE | A6XX_RB_DEPTH_CNTL_Z_READ_ENABLE;
+
+      if (ds_info->depthBoundsTestEnable && !ds_info->depthTestEnable)
+         tu6_apply_depth_bounds_workaround(builder->device, &rb_depth_cntl);
    } else {
       /* if RB_DEPTH_CNTL is set dynamically, we need to make sure it is set
        * to 0 when this pipeline is used, as enabling depth test when there
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index d87d64ac2ac..9ae3d161ff8 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -1250,6 +1250,9 @@ void tu6_emit_window_offset(struct tu_cs *cs, uint32_t x1, uint32_t y1);
 
 void tu_disable_draw_states(struct tu_cmd_buffer *cmd, struct tu_cs *cs);
 
+void tu6_apply_depth_bounds_workaround(struct tu_device *device,
+                                       uint32_t *rb_depth_cntl);
+
 struct tu_pvtmem_config {
    uint64_t iova;
    uint32_t per_fiber_size;



More information about the mesa-commit mailing list