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);
