From 78da1e42498b19b8416d4623043f835d078b22c8 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Wed, 3 Dec 2025 21:18:22 -0500 Subject: [PATCH] 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 Acked-by: Eric R. Smith Part-of: --- .../compiler/pan_nir_collect_varyings.c | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/panfrost/compiler/pan_nir_collect_varyings.c b/src/panfrost/compiler/pan_nir_collect_varyings.c index a242c59b22d..7bb545b26cd 100644 --- a/src/panfrost/compiler/pan_nir_collect_varyings.c +++ b/src/panfrost/compiler/pan_nir_collect_varyings.c @@ -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);