Mesa (main): nir: Keep track of cross-invocation mesh shader output access.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri May 27 11:49:59 UTC 2022


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

Author: Timur Kristóf <timur.kristof at gmail.com>
Date:   Thu May 26 19:03:19 2022 +0200

nir: Keep track of cross-invocation mesh shader output access.

On some implementations eg. AMD RDNA2 the driver can generate a
more optimal code path knowing whether outputs are indexed using the
local invocation index or not.

Signed-off-by: Timur Kristóf <timur.kristof at gmail.com>
Reviewed-by: Marcin Ślusarz <marcin.slusarz at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16736>

---

 src/compiler/nir/nir_gather_info.c | 31 ++++++++++++++++++++++++++++++-
 src/compiler/shader_info.h         |  5 +++++
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c
index d372ac49ad6..60d38c4772d 100644
--- a/src/compiler/nir/nir_gather_info.c
+++ b/src/compiler/nir/nir_gather_info.c
@@ -36,6 +36,17 @@ src_is_invocation_id(const nir_src *src)
              nir_intrinsic_load_invocation_id;
 }
 
+static bool
+src_is_local_invocation_index(const nir_src *src)
+{
+   assert(src->is_ssa);
+   if (src->ssa->parent_instr->type != nir_instr_type_intrinsic)
+      return false;
+
+   return nir_instr_as_intrinsic(src->ssa->parent_instr)->intrinsic ==
+             nir_intrinsic_load_local_invocation_index;
+}
+
 static void
 get_deref_info(nir_shader *shader, nir_variable *var, nir_deref_instr *deref,
                bool *cross_invocation, bool *indirect)
@@ -53,7 +64,10 @@ get_deref_info(nir_shader *shader, nir_variable *var, nir_deref_instr *deref,
    /* Vertex index is the outermost array index. */
    if (is_arrayed) {
       assert((*p)->deref_type == nir_deref_type_array);
-      *cross_invocation = !src_is_invocation_id(&(*p)->arr.index);
+      if (shader->info.stage == MESA_SHADER_TESS_CTRL)
+         *cross_invocation = !src_is_invocation_id(&(*p)->arr.index);
+      else if (shader->info.stage == MESA_SHADER_MESH)
+         *cross_invocation = !src_is_local_invocation_index(&(*p)->arr.index);
       p++;
    }
 
@@ -154,6 +168,8 @@ set_io_mask(nir_shader *shader, nir_variable *var, int offset, int len,
             }
          }
 
+         if (cross_invocation && shader->info.stage == MESA_SHADER_MESH)
+            shader->info.mesh.ms_cross_invocation_output_access |= bitfield;
 
          if (var->data.fb_fetch_output) {
             shader->info.outputs_read |= bitfield;
@@ -592,6 +608,13 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader,
           !src_is_invocation_id(nir_get_io_arrayed_index_src(instr)))
          shader->info.tess.tcs_cross_invocation_outputs_read |= slot_mask;
 
+      /* NV_mesh_shader: mesh shaders can load their outputs. */
+      if (shader->info.stage == MESA_SHADER_MESH &&
+          (instr->intrinsic == nir_intrinsic_load_per_vertex_output ||
+           instr->intrinsic == nir_intrinsic_load_per_primitive_output) &&
+          !src_is_local_invocation_index(nir_get_io_arrayed_index_src(instr)))
+         shader->info.mesh.ms_cross_invocation_output_access |= slot_mask;
+
       if (shader->info.stage == MESA_SHADER_FRAGMENT &&
           nir_intrinsic_io_semantics(instr).fb_fetch_output)
          shader->info.fs.uses_fbfetch_output = true;
@@ -614,6 +637,12 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader,
          }
       }
 
+      if (shader->info.stage == MESA_SHADER_MESH &&
+          (instr->intrinsic == nir_intrinsic_store_per_vertex_output ||
+           instr->intrinsic == nir_intrinsic_store_per_primitive_output) &&
+          !src_is_local_invocation_index(nir_get_io_arrayed_index_src(instr)))
+         shader->info.mesh.ms_cross_invocation_output_access |= slot_mask;
+
       if (shader->info.stage == MESA_SHADER_FRAGMENT &&
           nir_intrinsic_io_semantics(instr).dual_source_blend_index)
          shader->info.fs.color_is_dual_source = true;
diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h
index ed3596b1f3e..20974ad8dd6 100644
--- a/src/compiler/shader_info.h
+++ b/src/compiler/shader_info.h
@@ -505,6 +505,11 @@ typedef struct shader_info {
 
       /* Applies to MESH. */
       struct {
+         /* Bit mask of MS outputs that are used
+          * with an index that is NOT the local invocation index.
+          */
+         uint64_t ms_cross_invocation_output_access;
+
          uint16_t max_vertices_out;
          uint16_t max_primitives_out;
          uint16_t primitive_type;  /* GL_POINTS, GL_LINES or GL_TRIANGLES. */



More information about the mesa-commit mailing list