pan/nir: Improve collect_noperspective_varyings_fs()

We can easily handle indirect loads by looking at sem.num_slots.
Because noperspective is declared on the entire variable and not
individual slots of an array, we can smash noperspective on for the
whole range if we see an indirect.  We also add collect from variables,
which is probably redundant when run late because variables are left
around after lowering I/O but it lets us run the pass before I/O is
lowered.

Reviewed-by: Lorenzo Rossi <lorenzo.rossi@collabora.com>
Acked-by: Eric R. Smith <eric.smith@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38681>
This commit is contained in:
Faith Ekstrand 2025-12-03 21:18:22 -05:00 committed by Marge Bot
parent f2f792996d
commit 78da1e4249

View file

@ -177,8 +177,10 @@ collect_noperspective_varyings_fs(UNUSED nir_builder *b,
nir_intrinsic_instr *bary_instr = nir_src_as_intrinsic(intr->src[0]);
assert(bary_instr);
if (nir_intrinsic_interp_mode(bary_instr) == INTERP_MODE_NOPERSPECTIVE)
*noperspective_varyings |= BITFIELD_BIT(sem.location - VARYING_SLOT_VAR0);
if (nir_intrinsic_interp_mode(bary_instr) == INTERP_MODE_NOPERSPECTIVE) {
unsigned loc = sem.location - VARYING_SLOT_VAR0;
*noperspective_varyings |= BITFIELD_RANGE(loc, sem.num_slots);
}
return false;
}
@ -189,6 +191,21 @@ pan_nir_collect_noperspective_varyings_fs(nir_shader *s)
assert(s->info.stage == MESA_SHADER_FRAGMENT);
uint32_t noperspective_varyings = 0;
/* Collect from variables */
nir_foreach_shader_in_variable(var, s) {
if (var->data.location < VARYING_SLOT_VAR0)
continue;
if (var->data.interpolation != INTERP_MODE_NOPERSPECTIVE)
continue;
unsigned loc = var->data.location - VARYING_SLOT_VAR0;
unsigned slots = glsl_count_attribute_slots(var->type, false);
noperspective_varyings |= BITFIELD_RANGE(loc, slots);
}
/* And collect from load_interpolated_input intrinsics */
nir_shader_intrinsics_pass(s, collect_noperspective_varyings_fs,
nir_metadata_all,
(void *)&noperspective_varyings);