nir/zink: use sysvals in `nir_create_passthrough_gs`
authorantonino <antonino.maniscalco@collabora.com>
Mon, 24 Apr 2023 11:46:52 +0000 (13:46 +0200)
committerMarge Bot <emma+marge@anholt.net>
Tue, 25 Apr 2023 13:11:59 +0000 (13:11 +0000)
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 <faith.ekstrand@collabora.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22667>

src/compiler/nir/nir.h
src/compiler/nir/nir_intrinsics.py
src/compiler/nir/nir_passthrough_gs.c
src/gallium/drivers/zink/zink_compiler.c
src/gallium/drivers/zink/zink_compiler.h
src/gallium/drivers/zink/zink_program.c

index 1995d6d..753b882 100644 (file)
@@ -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);
 
index 9cb0125..837803c 100644 (file)
@@ -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
index 999358b..2975dae 100644 (file)
@@ -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);
index ac765a1..d708ab1 100644 (file)
@@ -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)
 {
index 2fb84f7..97de58a 100644 (file)
@@ -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);
index be7b361..40117b6 100644 (file)
@@ -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);