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

Author: antonino <[email protected]>
Date:   Mon Apr 24 13:46:52 2023 +0200

nir/zink: use sysvals in `nir_create_passthrough_gs`

Previously the passthrough gs shader loaded some values with uniform
loads using sevaral hardcoded values.

This was not flexible for other drivers and started becoming too
unflexible for zink itself.

Use system values instead and use a lowering pass in zink.

Acked-by: Faith Ekstrand <[email protected]>
Reviewed-by: Erik Faye-Lund <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22667>

---

 src/compiler/nir/nir.h                   |  2 --
 src/compiler/nir/nir_intrinsics.py       |  8 ++++++
 src/compiler/nir/nir_passthrough_gs.c    | 10 ++------
 src/gallium/drivers/zink/zink_compiler.c | 44 ++++++++++++++++++++++++++++----
 src/gallium/drivers/zink/zink_compiler.h |  6 +++--
 src/gallium/drivers/zink/zink_program.c  |  6 ++---
 6 files changed, 55 insertions(+), 21 deletions(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 1995d6de433..753b8821c27 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -5108,8 +5108,6 @@ nir_shader * nir_create_passthrough_tcs(const 
nir_shader_compiler_options *optio
 nir_shader * nir_create_passthrough_gs(const nir_shader_compiler_options 
*options,
                                        const nir_shader *prev_stage,
                                        enum shader_prim primitive_type,
-                                       int flat_interp_mask_offset,
-                                       int last_pv_vert_offset,
                                        bool emulate_edgeflags,
                                        bool force_line_strip_out);
 
diff --git a/src/compiler/nir/nir_intrinsics.py 
b/src/compiler/nir/nir_intrinsics.py
index 9cb01252e46..837803ccd16 100644
--- a/src/compiler/nir/nir_intrinsics.py
+++ b/src/compiler/nir/nir_intrinsics.py
@@ -1142,6 +1142,14 @@ load("mesh_view_indices", [1], [BASE, RANGE], 
[CAN_ELIMINATE, CAN_REORDER])
 load("preamble", [], indices=[BASE], flags=[CAN_ELIMINATE, CAN_REORDER])
 store("preamble", [], indices=[BASE])
 
+# A 32 bits bitfield storing 1 in bits corresponding to varyings
+# that have the flat interpolation specifier in the fragment shader
+# and 0 otherwise
+system_value("flat_mask", 1)
+
+# Whether provoking vertex mode is last
+system_value("provoking_last", 1)
+
 # IR3-specific version of most SSBO intrinsics. The only different
 # compare to the originals is that they add an extra source to hold
 # the dword-offset, which is needed by the backend code apart from
diff --git a/src/compiler/nir/nir_passthrough_gs.c 
b/src/compiler/nir/nir_passthrough_gs.c
index 999358b4068..2975daee37c 100644
--- a/src/compiler/nir/nir_passthrough_gs.c
+++ b/src/compiler/nir/nir_passthrough_gs.c
@@ -150,8 +150,6 @@ nir_shader *
 nir_create_passthrough_gs(const nir_shader_compiler_options *options,
                           const nir_shader *prev_stage,
                           enum shader_prim primitive_type,
-                          int flat_interp_mask_offset,
-                          int last_pv_vert_offset,
                           bool emulate_edgeflags,
                           bool force_line_strip_out)
 {
@@ -255,12 +253,8 @@ nir_create_passthrough_gs(const 
nir_shader_compiler_options *options,
    }
 
    nir_variable *edge_var = nir_find_variable_with_location(nir, 
nir_var_shader_in, VARYING_SLOT_EDGE);
-   nir_ssa_def *flat_interp_mask_def = nir_load_ubo(&b, 1, 32,
-                                                    nir_imm_int(&b, 0), 
nir_imm_int(&b, flat_interp_mask_offset),
-                                                    .align_mul = 4, 
.align_offset = 0, .range_base = 0, .range = ~0);
-   nir_ssa_def *last_pv_vert_def = nir_load_ubo(&b, 1, 32,
-                                                nir_imm_int(&b, 0), 
nir_imm_int(&b, last_pv_vert_offset),
-                                                .align_mul = 4, .align_offset 
= 0, .range_base = 0, .range = ~0);
+   nir_ssa_def *flat_interp_mask_def = nir_load_flat_mask(&b);
+   nir_ssa_def *last_pv_vert_def = nir_load_provoking_last(&b);
    last_pv_vert_def = nir_ine_imm(&b, last_pv_vert_def, 0);
    nir_ssa_def *start_vert_index = nir_imm_int(&b, start_vert);
    nir_ssa_def *end_vert_index = nir_imm_int(&b, end_vert - 1);
diff --git a/src/gallium/drivers/zink/zink_compiler.c 
b/src/gallium/drivers/zink/zink_compiler.c
index ac765a14ac3..d708ab1c879 100644
--- a/src/gallium/drivers/zink/zink_compiler.c
+++ b/src/gallium/drivers/zink/zink_compiler.c
@@ -1182,8 +1182,7 @@ lower_64bit_pack(nir_shader *shader)
 
 nir_shader *
 zink_create_quads_emulation_gs(const nir_shader_compiler_options *options,
-                               const nir_shader *prev_stage,
-                               int last_pv_vert_offset)
+                               const nir_shader *prev_stage)
 {
    nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_GEOMETRY,
                                                   options,
@@ -1241,9 +1240,7 @@ zink_create_quads_emulation_gs(const 
nir_shader_compiler_options *options,
 
    int mapping_first[] = {0, 1, 2, 0, 2, 3};
    int mapping_last[] = {0, 1, 3, 1, 2, 3};
-   nir_ssa_def *last_pv_vert_def = nir_load_ubo(&b, 1, 32,
-                                                nir_imm_int(&b, 0), 
nir_imm_int(&b, last_pv_vert_offset),
-                                                .align_mul = 4, .align_offset 
= 0, .range_base = 0, .range = ~0);
+   nir_ssa_def *last_pv_vert_def = nir_load_provoking_last(&b);
    last_pv_vert_def = nir_ine_imm(&b, last_pv_vert_def, 0);
    for (unsigned i = 0; i < 6; ++i) {
       /* swap indices 2 and 3 */
@@ -1269,6 +1266,43 @@ zink_create_quads_emulation_gs(const 
nir_shader_compiler_options *options,
    return nir;
 }
 
+static bool
+lower_system_values_to_inlined_uniforms_instr(nir_builder *b, nir_instr 
*instr, void *data)
+{
+   if (instr->type != nir_instr_type_intrinsic)
+      return false;
+
+   nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+
+   int inlined_uniform_offset;
+   switch (intrin->intrinsic) {
+   case nir_intrinsic_load_flat_mask:
+      inlined_uniform_offset = ZINK_INLINE_VAL_FLAT_MASK * sizeof(uint32_t);
+      break;
+   case nir_intrinsic_load_provoking_last:
+      inlined_uniform_offset = ZINK_INLINE_VAL_PV_LAST_VERT * sizeof(uint32_t);
+      break;
+   default:
+      return false;
+   }
+
+   b->cursor = nir_before_instr(&intrin->instr);
+   nir_ssa_def *new_dest_def = nir_load_ubo(b, 1, 32, nir_imm_int(b, 0),
+                                            nir_imm_int(b, 
inlined_uniform_offset),
+                                            .align_mul = 4, .align_offset = 0,
+                                            .range_base = 0, .range = ~0);
+   nir_ssa_def_rewrite_uses(&intrin->dest.ssa, new_dest_def);
+   nir_instr_remove(instr);
+   return true;
+}
+
+bool
+zink_lower_system_values_to_inlined_uniforms(nir_shader *nir)
+{
+   return nir_shader_instructions_pass(nir, 
lower_system_values_to_inlined_uniforms_instr,
+                                       nir_metadata_dominance, NULL);
+}
+
 void
 zink_screen_init_compiler(struct zink_screen *screen)
 {
diff --git a/src/gallium/drivers/zink/zink_compiler.h 
b/src/gallium/drivers/zink/zink_compiler.h
index 2fb84f72dc5..97de58a71d6 100644
--- a/src/gallium/drivers/zink/zink_compiler.h
+++ b/src/gallium/drivers/zink/zink_compiler.h
@@ -58,8 +58,10 @@ zink_tgsi_to_nir(struct pipe_screen *screen, const struct 
tgsi_token *tokens);
 
 nir_shader*
 zink_create_quads_emulation_gs(const nir_shader_compiler_options *options,
-                               const nir_shader *prev_stage,
-                               int last_pv_vert_offset);
+                               const nir_shader *prev_stage);
+
+bool
+zink_lower_system_values_to_inlined_uniforms(nir_shader *nir);
 
 void
 zink_screen_init_compiler(struct zink_screen *screen);
diff --git a/src/gallium/drivers/zink/zink_program.c 
b/src/gallium/drivers/zink/zink_program.c
index be7b361ee41..40117b6c08e 100644
--- a/src/gallium/drivers/zink/zink_program.c
+++ b/src/gallium/drivers/zink/zink_program.c
@@ -2362,8 +2362,7 @@ zink_set_primitive_emulation_keys(struct zink_context 
*ctx)
             if (lower_filled_quad) {
                nir = zink_create_quads_emulation_gs(
                   &screen->nir_options,
-                  prev_stage,
-                  ZINK_INLINE_VAL_PV_LAST_VERT * 4);
+                  prev_stage);
             } else {
                enum pipe_prim_type prim = 
ctx->gfx_pipeline_state.gfx_prim_mode;
                if (prev_vertex_stage == MESA_SHADER_TESS_EVAL)
@@ -2372,11 +2371,10 @@ zink_set_primitive_emulation_keys(struct zink_context 
*ctx)
                   &screen->nir_options,
                   prev_stage,
                   prim,
-                  ZINK_INLINE_VAL_FLAT_MASK * sizeof(uint32_t),
-                  ZINK_INLINE_VAL_PV_LAST_VERT * sizeof(uint32_t),
                   lower_edge_flags,
                   lower_line_stipple || lower_quad_prim);
             }
+            zink_lower_system_values_to_inlined_uniforms(nir);
 
             zink_add_inline_uniform(nir, ZINK_INLINE_VAL_FLAT_MASK);
             zink_add_inline_uniform(nir, ZINK_INLINE_VAL_PV_LAST_VERT);

Reply via email to