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