radeonsi: support fragment shader per primitive input

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37932>
This commit is contained in:
Qiang Yu
2025-05-19 14:45:33 +08:00
committed by Marge Bot
parent dfc679e791
commit 01fc4efd77
3 changed files with 20 additions and 1 deletions
@@ -206,6 +206,7 @@ struct si_shader_variant_info {
uint32_t vs_output_ps_input_cntl[NUM_TOTAL_VARYING_SLOTS];
union si_ps_input_info ps_inputs[SI_NUM_INTERP];
uint8_t num_ps_inputs;
uint8_t num_ps_per_primitive_inputs;
uint8_t ps_colors_read;
uint8_t num_input_sgprs;
uint8_t num_input_vgprs;
@@ -25,6 +25,9 @@ void si_get_shader_variant_info(struct si_shader *shader,
*/
for (unsigned i = 0; i < ARRAY_SIZE(shader->info.ps_inputs); i++)
shader->info.ps_inputs[i].interpolate = INTERP_MODE_FLAT;
shader->info.num_ps_per_primitive_inputs =
util_bitcount64(nir->info.per_primitive_inputs);
}
nir_foreach_block(block, nir_shader_get_entrypoint(nir)) {
@@ -50,6 +53,7 @@ void si_get_shader_variant_info(struct si_shader *shader,
case nir_intrinsic_load_input:
case nir_intrinsic_load_input_vertex:
case nir_intrinsic_load_per_vertex_input:
case nir_intrinsic_load_per_primitive_input:
case nir_intrinsic_load_interpolated_input: {
if (nir->info.stage == MESA_SHADER_VERTEX) {
shader->info.uses_vmem_load_other = true;
@@ -78,6 +82,9 @@ void si_get_shader_variant_info(struct si_shader *shader,
shader->info.ps_inputs[index].interpolate = INTERP_MODE_SMOOTH;
if (intr->def.bit_size == 16)
shader->info.ps_inputs[index].fp16_lo_hi_valid |= 0x1 << sem.high_16bits;
} else if (intr->intrinsic == nir_intrinsic_load_per_primitive_input) {
/* per primitive input from mesh shader */
shader->info.ps_inputs[index].interpolate = INTERP_MODE_NONE;
}
}
break;
@@ -2249,7 +2249,18 @@ static void si_shader_ps(struct si_screen *sscreen, struct si_shader *shader)
(sscreen->info.gfx_level == GFX11 && !shader->ps.num_interp &&
shader->config.lds_size);
shader->ps.spi_ps_in_control = S_0286D8_NUM_INTERP(shader->ps.num_interp) |
unsigned num_prim_interp = 0;
unsigned num_interp = shader->ps.num_interp;
if (sscreen->info.gfx_level == GFX10_3) {
/* NUM_INTERP / NUM_PRIM_INTERP separately contain
* the number of per-vertex and per-primitive PS input attributes.
*/
num_prim_interp = shader->info.num_ps_per_primitive_inputs;
num_interp -= num_prim_interp;
}
shader->ps.spi_ps_in_control = S_0286D8_NUM_INTERP(num_interp) |
S_0286D8_NUM_PRIM_INTERP(num_prim_interp) |
S_0286D8_PARAM_GEN(param_gen) |
S_0286D8_PS_W32_EN(shader->wave_size == 32);
}