tu: Disable preamble push consts when they are not used
authorDanylo Piliaiev <dpiliaiev@igalia.com>
Tue, 10 Oct 2023 12:55:26 +0000 (14:55 +0200)
committerMarge Bot <emma+marge@anholt.net>
Wed, 11 Oct 2023 09:40:21 +0000 (09:40 +0000)
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 <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25641>

src/freedreno/vulkan/tu_shader.cc

index a032e0a8e3dd9c36ac9cc7b56d4612f2242ea734..2179a64f8e9260cd839169ba61bc0e3a45157c4b 100644 (file)
@@ -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);