radeonsi: fix color interpolation when finalize_nir is called twice

Calling finalize_nir twice causes si_nir_lower_color_inputs_to_sysvals
to be called twice. The pass always sets color interpolation to FLAT
at the beginning, and then lowers color input loads and sets the correct
interpolation mode. However, when the pass is called for the second time,
it just sets color interpolation to flat and does nothing, which overrides
the original interpolation mode.

This fixes color interpolation for those cases. This only happens with
ATI_fragment_shader AFAIK.

Fixes: deda05e2b7 - nir: move nir_lower_color_inputs into radeonsi

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
(cherry picked from commit e5b1c568b9)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39462>
This commit is contained in:
Marek Olšák 2025-11-22 15:41:14 -05:00 committed by Dylan Baker
parent 13c336900a
commit dfb6ec7f93
2 changed files with 9 additions and 7 deletions

View file

@ -2004,7 +2004,7 @@
"description": "radeonsi: fix color interpolation when finalize_nir is called twice",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "deda05e2b71136c9620983c05628ac7defd5de3e",
"notes": null

View file

@ -12,11 +12,9 @@ bool si_nir_lower_color_inputs_to_sysvals(nir_shader *nir)
/* Both flat and non-flat can occur with nir_io_mix_convergent_flat_with_interpolated,
* but we want to save only the non-flat interp mode in that case.
*
* Start with flat and set to non-flat only if it's present.
*/
nir->info.fs.color0_interp = INTERP_MODE_FLAT;
nir->info.fs.color1_interp = INTERP_MODE_FLAT;
bool color0_interp_mode_set = false;
bool color1_interp_mode_set = false;
nir_builder b = nir_builder_create(impl);
@ -61,17 +59,21 @@ bool si_nir_lower_color_inputs_to_sysvals(nir_shader *nir)
if (sem.location == VARYING_SLOT_COL0) {
load = nir_load_color0(&b);
if (interp != INTERP_MODE_FLAT)
/* If both flat and non-flat are used, set non-flat. */
if (!color0_interp_mode_set || interp != INTERP_MODE_FLAT)
nir->info.fs.color0_interp = interp;
nir->info.fs.color0_sample = sample;
nir->info.fs.color0_centroid = centroid;
color0_interp_mode_set = true;
} else {
assert(sem.location == VARYING_SLOT_COL1);
load = nir_load_color1(&b);
if (interp != INTERP_MODE_FLAT)
/* If both flat and non-flat are used, set non-flat. */
if (!color1_interp_mode_set || interp != INTERP_MODE_FLAT)
nir->info.fs.color1_interp = interp;
nir->info.fs.color1_sample = sample;
nir->info.fs.color1_centroid = centroid;
color1_interp_mode_set = true;
}
if (intrin->num_components != 4) {