nir: Fix handling of NV_mesh_shader PRIMITIVE_INDICES output.
authorTimur Kristóf <timur.kristof@gmail.com>
Wed, 23 Feb 2022 14:01:05 +0000 (15:01 +0100)
committerMarge Bot <emma+marge@anholt.net>
Tue, 8 Mar 2022 13:44:10 +0000 (13:44 +0000)
PRIMITIVE_INDICES is a flat array in NV_mesh_shader,
not a proper arrayed output, as opposed to D3D-style
mesh shaders where it's addressed by the primitive index.

Prevent assigning several slots to primitive indices,
to avoid issues.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Acked-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15160>

src/compiler/nir/nir_gather_info.c
src/compiler/nir/nir_lower_io.c

index 4b19d5f..85956f0 100644 (file)
@@ -173,7 +173,8 @@ mark_whole_variable(nir_shader *shader, nir_variable *var,
    if (nir_is_arrayed_io(var, shader->info.stage) ||
        /* For NV_mesh_shader. */
        (shader->info.stage == MESA_SHADER_MESH &&
-        var->data.location == VARYING_SLOT_PRIMITIVE_INDICES)) {
+        var->data.location == VARYING_SLOT_PRIMITIVE_INDICES &&
+        !var->data.per_primitive)) {
       assert(glsl_type_is_array(type));
       type = glsl_get_array_element(type);
    }
index a25d129..db50e89 100644 (file)
@@ -156,7 +156,7 @@ nir_is_arrayed_io(const nir_variable *var, gl_shader_stage stage)
    if (stage == MESA_SHADER_MESH) {
       /* NV_mesh_shader: this is flat array for the whole workgroup. */
       if (var->data.location == VARYING_SLOT_PRIMITIVE_INDICES)
-         return false;
+         return var->data.per_primitive;
    }
 
    if (var->data.mode == nir_var_shader_in)
@@ -181,6 +181,18 @@ static unsigned get_number_of_slots(struct lower_io_state *state,
       type = glsl_get_array_element(type);
    }
 
+   /* NV_mesh_shader:
+    * PRIMITIVE_INDICES is a flat array, not a proper arrayed output,
+    * as opposed to D3D-style mesh shaders where it's addressed by
+    * the primitive index.
+    * Prevent assigning several slots to primitive indices,
+    * to avoid some issues.
+    */
+   if (state->builder.shader->info.stage == MESA_SHADER_MESH &&
+       var->data.location == VARYING_SLOT_PRIMITIVE_INDICES &&
+       !nir_is_arrayed_io(var, state->builder.shader->info.stage))
+      return 1;
+
    return state->type_size(type, var->data.bindless);
 }
 
@@ -453,12 +465,6 @@ emit_store(struct lower_io_state *state, nir_ssa_def *data,
    semantics.per_view = var->data.per_view;
    semantics.invariant = var->data.invariant;
 
-   /* NV_mesh_shader: prevent assigning several slots to primitive indices. */
-   if (b->shader->info.stage == MESA_SHADER_MESH &&
-       var->data.location == VARYING_SLOT_PRIMITIVE_INDICES &&
-       !nir_is_arrayed_io(var, b->shader->info.stage))
-      semantics.num_slots = 1;
-
    nir_intrinsic_set_io_semantics(store, semantics);
 
    nir_builder_instr_insert(b, &store->instr);