From 66740d9c91b2e498423bca9f069225389124a23c Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 31 Jul 2025 14:48:34 -0400 Subject: [PATCH] nir: gather interpolation qualifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit we'll want this to be able to link interpolation qualifiers in a simple way with nir_opt_varyings. add the metadata for it and the FS gathering pass. Signed-off-by: Alyssa Rosenzweig Reviewed-by: Marek Olšák Part-of: --- src/compiler/nir/nir_gather_info.c | 22 ++++++++++++++++++++++ src/compiler/nir/nir_print.c | 3 +++ src/compiler/shader_info.h | 11 +++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index c555a1219d4..47e8d223d4b 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -573,6 +573,25 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader, else shader->info.tess.tcs_cross_invocation_inputs_read |= slot_mask; } + + if (shader->info.stage == MESA_SHADER_FRAGMENT && + instr->intrinsic == nir_intrinsic_load_interpolated_input) { + nir_intrinsic_instr *bary = nir_src_as_intrinsic(instr->src[0]); + + if (bary && nir_intrinsic_has_interp_mode(bary)) { + enum glsl_interp_mode mode = nir_intrinsic_interp_mode(bary); + + if (mode == INTERP_MODE_NOPERSPECTIVE) + shader->info.linear_varyings |= slot_mask; + else + shader->info.perspective_varyings |= slot_mask; + } else { + /* If the driver is lowering barycentrics, we can't recover the + * interpolation qualifiers. Bail. + */ + shader->info.known_interpolation_qualifiers = false; + } + } break; case nir_intrinsic_load_output: @@ -1035,6 +1054,9 @@ nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint) shader->info.fs.uses_fbfetch_output = false; shader->info.fs.needs_coarse_quad_helper_invocations = false; shader->info.fs.needs_full_quad_helper_invocations = false; + + /* By definition the fragment shader knows, unless we fail to gather. */ + shader->info.known_interpolation_qualifiers = true; } if (shader->info.stage == MESA_SHADER_TESS_CTRL) { shader->info.tess.tcs_same_invocation_inputs_read = 0; diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index 8fed1ce2229..ad68014a882 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -2676,6 +2676,8 @@ print_shader_info(const struct shader_info *info, FILE *fp) print_nz_x64(fp, "dual_slot_inputs", info->dual_slot_inputs); print_nz_x64(fp, "outputs_written", info->outputs_written); print_nz_x64(fp, "outputs_read", info->outputs_read); + print_nz_x64(fp, "perspective_varyings", info->perspective_varyings); + print_nz_x64(fp, "linear_varyings", info->linear_varyings); print_nz_bitset(fp, "system_values_read", info->system_values_read, ARRAY_SIZE(info->system_values_read)); @@ -2750,6 +2752,7 @@ print_shader_info(const struct shader_info *info, FILE *fp) print_nz_bool(fp, "first_ubo_is_default_ubo", info->first_ubo_is_default_ubo); print_nz_bool(fp, "separate_shader", info->separate_shader); + print_nz_bool(fp, "known_interpolation_qualifiers", info->known_interpolation_qualifiers); print_nz_bool(fp, "has_transform_feedback_varyings", info->has_transform_feedback_varyings); print_nz_bool(fp, "flrp_lowered", info->flrp_lowered); print_nz_bool(fp, "io_lowered", info->io_lowered); diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h index 265b84718fe..03b33c1a257 100644 --- a/src/compiler/shader_info.h +++ b/src/compiler/shader_info.h @@ -87,6 +87,12 @@ typedef struct shader_info { /* Which system values are actually read */ BITSET_DECLARE(system_values_read, SYSTEM_VALUE_MAX); + /* If known_interpolation_qualifiers is set, bitsets mapping locations to + * interpolation qualifiers perspective/linear/flat. + */ + uint64_t perspective_varyings; + uint64_t linear_varyings; + /* Which I/O is per-primitive, for read/written information combine with * the fields above. */ @@ -202,6 +208,11 @@ typedef struct shader_info { /* Whether or not separate shader objects were used */ bool separate_shader:1; + /* Whether perspective_varyings/linear_varyings can be trusted. This depends + * on what this shader was linked with, as well as the API. + */ + bool known_interpolation_qualifiers:1; + /** Was this shader linked with any transform feedback varyings? */ bool has_transform_feedback_varyings:1;