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

Author: Danylo Piliaiev <[email protected]>
Date:   Tue Oct 10 14:55:26 2023 +0200

tu: Disable preamble push consts when they are not used

It's a common case for Zink which has to declare push consts in
pipeline layout, even if they are not actually used in shaders, due
to the compatibility rules.

Signed-off-by: Danylo Piliaiev <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25641>

---

 src/freedreno/vulkan/tu_shader.cc | 42 ++++++++++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/freedreno/vulkan/tu_shader.cc 
b/src/freedreno/vulkan/tu_shader.cc
index a032e0a8e3d..2179a64f8e9 100644
--- a/src/freedreno/vulkan/tu_shader.cc
+++ b/src/freedreno/vulkan/tu_shader.cc
@@ -701,14 +701,48 @@ gather_push_constants(nir_shader *shader, struct 
tu_shader *tu_shader)
       align(max, 16) / 4 - tu_shader->const_state.push_consts.lo;
 }
 
+static bool
+shader_uses_push_consts(nir_shader *shader)
+{
+   nir_foreach_function_impl (impl, shader) {
+      nir_foreach_block (block, impl) {
+         nir_foreach_instr_safe (instr, block) {
+            if (instr->type != nir_instr_type_intrinsic)
+               continue;
+
+            nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+            if (intrin->intrinsic == nir_intrinsic_load_push_constant)
+               return true;
+         }
+      }
+   }
+   return false;
+}
+
 static bool
 tu_lower_io(nir_shader *shader, struct tu_device *dev,
             struct tu_shader *tu_shader,
             const struct tu_pipeline_layout *layout,
             unsigned *reserved_consts_vec4_out)
 {
-   if (tu_shader->const_state.push_consts.type == IR3_PUSH_CONSTS_PER_STAGE)
+   tu_shader->const_state.push_consts = (struct tu_push_constant_range) {
+      .lo = 0,
+      .dwords = layout->push_constant_size / 4,
+      .type = tu_push_consts_type(layout, dev->compiler),
+   };
+
+   if (tu_shader->const_state.push_consts.type == IR3_PUSH_CONSTS_PER_STAGE) {
       gather_push_constants(shader, tu_shader);
+   } else if (tu_shader->const_state.push_consts.type ==
+            IR3_PUSH_CONSTS_SHARED_PREAMBLE) {
+      /* Disable pushing constants for this stage if none were loaded in the
+       * shader.  If all stages don't load their declared push constants, as
+       * is often the case under zink, then we could additionally skip
+       * emitting REG_A7XX_HLSQ_SHARED_CONSTS_IMM entirely.
+       */
+      if (!shader_uses_push_consts(shader))
+         tu_shader->const_state.push_consts = (struct tu_push_constant_range) 
{};
+   }
 
    struct tu_const_state *const_state = &tu_shader->const_state;
    unsigned reserved_consts_vec4 =
@@ -2271,12 +2305,6 @@ tu_shader_create(struct tu_device *dev,
          nir->info.stage == MESA_SHADER_GEOMETRY)
       tu_gather_xfb_info(nir, &so_info);
 
-   shader->const_state.push_consts = (struct tu_push_constant_range) {
-      .lo = 0,
-      .dwords = layout->push_constant_size / 4,
-      .type = tu_push_consts_type(layout, dev->compiler),
-   };
-
    unsigned reserved_consts_vec4 = 0;
    NIR_PASS_V(nir, tu_lower_io, dev, shader, layout, &reserved_consts_vec4);
 

Reply via email to