diff --git a/src/gallium/drivers/radeonsi/si_nir_lower_abi.c b/src/gallium/drivers/radeonsi/si_nir_lower_abi.c index ad57e18faa4..c02204751b0 100644 --- a/src/gallium/drivers/radeonsi/si_nir_lower_abi.c +++ b/src/gallium/drivers/radeonsi/si_nir_lower_abi.c @@ -277,6 +277,17 @@ static void preload_reusable_variables(nir_builder *b, struct lower_abi_state *s build_gsvs_ring_desc(b, s); } +static nir_def *get_num_vertices_per_prim(nir_builder *b, struct lower_abi_state *s) +{ + struct si_shader_args *args = s->args; + unsigned num_vertices = gfx10_ngg_get_vertices_per_prim(s->shader); + + if (num_vertices) + return nir_imm_int(b, num_vertices); + else + return nir_iadd_imm(b, GET_FIELD_NIR(GS_STATE_OUTPRIM), 1); +} + static bool lower_intrinsic(nir_builder *b, nir_instr *instr, struct lower_abi_state *s) { nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); @@ -379,14 +390,9 @@ static bool lower_intrinsic(nir_builder *b, nir_instr *instr, struct lower_abi_s replacement = nir_load_smem_amd(b, 4, addr, nir_imm_int(b, offset)); break; } - case nir_intrinsic_load_num_vertices_per_primitive_amd: { - unsigned num_vertices = gfx10_ngg_get_vertices_per_prim(shader); - if (num_vertices) - replacement = nir_imm_int(b, num_vertices); - else - replacement = nir_iadd_imm(b, GET_FIELD_NIR(GS_STATE_OUTPRIM), 1); + case nir_intrinsic_load_num_vertices_per_primitive_amd: + replacement = get_num_vertices_per_prim(b, s); break; - } case nir_intrinsic_load_cull_ccw_amd: /* radeonsi embed cw/ccw info into front/back face enabled */ replacement = nir_imm_false(b); @@ -417,7 +423,9 @@ static bool lower_intrinsic(nir_builder *b, nir_instr *instr, struct lower_abi_s break; } case nir_intrinsic_load_provoking_vtx_in_prim_amd: - replacement = GET_FIELD_NIR(GS_STATE_PROVOKING_VTX_INDEX); + replacement = nir_bcsel(b, nir_i2b(b, GET_FIELD_NIR(GS_STATE_PROVOKING_VTX_FIRST)), + nir_imm_int(b, 0), + nir_iadd_imm(b, get_num_vertices_per_prim(b, s), -1)); break; case nir_intrinsic_load_pipeline_stat_query_enabled_amd: replacement = nir_i2b(b, GET_FIELD_NIR(GS_STATE_PIPELINE_STATS_EMU)); diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 9c1dcb63946..f916569d0d5 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -2158,9 +2158,8 @@ si_update_ngg_prim_state_sgpr(struct si_context *sctx, struct si_shader *hw_vs, return; if (hw_vs->uses_vs_state_provoking_vertex) { - unsigned vtx_index = sctx->queued.named.rasterizer->flatshade_first ? 0 : sctx->gs_out_prim; - - SET_FIELD(sctx->current_gs_state, GS_STATE_PROVOKING_VTX_INDEX, vtx_index); + SET_FIELD(sctx->current_gs_state, GS_STATE_PROVOKING_VTX_FIRST, + sctx->queued.named.rasterizer->flatshade_first); } if (hw_vs->uses_gs_state_outprim) { diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 06d22a6cd78..869c6439797 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -3585,9 +3585,11 @@ bool si_create_shader_variant(struct si_screen *sscreen, struct ac_llvm_compiler shader->key.ge.mono.u.vs_export_prim_id)); shader->uses_gs_state_outprim = sscreen->use_ngg && - /* Only used by streamout in vertex shaders. */ + /* Only used by streamout and the PrimID export in vertex + * shaders. */ sel->stage == MESA_SHADER_VERTEX && - si_shader_uses_streamout(shader); + (si_shader_uses_streamout(shader) || + shader->uses_vs_state_provoking_vertex); if (sel->stage == MESA_SHADER_VERTEX) { shader->uses_base_instance = sel->info.uses_base_instance || diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 4a823469a8a..73bdef6730b 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -253,7 +253,7 @@ enum * in the shader via vs_state_bits in legacy GS, the GS copy shader, and any NGG shader. */ /* bit gap */ -#define GS_STATE_ESGS_VERTEX_STRIDE__SHIFT 10 +#define GS_STATE_ESGS_VERTEX_STRIDE__SHIFT 11 #define GS_STATE_ESGS_VERTEX_STRIDE__MASK 0xff /* max 32 * 4 + 1 */ /* Small prim filter precision = num_samples / quant_mode, which can only be equal to 1/2^n * where n is between 4 and 12. Knowing that, we only need to store 4 bits of the FP32 exponent. @@ -262,14 +262,14 @@ enum * With 0x70 = 112, we get 2^(112 + value - 127) = 2^(value - 15), which is always a negative * exponent and it's equal to 1/2^(15 - value). */ -#define GS_STATE_SMALL_PRIM_PRECISION_NO_AA__SHIFT 18 +#define GS_STATE_SMALL_PRIM_PRECISION_NO_AA__SHIFT 19 #define GS_STATE_SMALL_PRIM_PRECISION_NO_AA__MASK 0xf -#define GS_STATE_SMALL_PRIM_PRECISION__SHIFT 22 +#define GS_STATE_SMALL_PRIM_PRECISION__SHIFT 23 #define GS_STATE_SMALL_PRIM_PRECISION__MASK 0xf -#define GS_STATE_STREAMOUT_QUERY_ENABLED__SHIFT 26 +#define GS_STATE_STREAMOUT_QUERY_ENABLED__SHIFT 27 #define GS_STATE_STREAMOUT_QUERY_ENABLED__MASK 0x1 -#define GS_STATE_PROVOKING_VTX_INDEX__SHIFT 27 -#define GS_STATE_PROVOKING_VTX_INDEX__MASK 0x3 +#define GS_STATE_PROVOKING_VTX_FIRST__SHIFT 28 +#define GS_STATE_PROVOKING_VTX_FIRST__MASK 0x1 #define GS_STATE_OUTPRIM__SHIFT 29 #define GS_STATE_OUTPRIM__MASK 0x3 #define GS_STATE_PIPELINE_STATS_EMU__SHIFT 31