From 726bbb352e5f6d4cf54920fa43cd9ef7b9c6e195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 5 Nov 2025 20:06:24 -0500 Subject: [PATCH] nir/opt_constant_folding: add nir_io_add_const_offset_to_base behavior We almost always call both passes next to each other. The code is copied from nir_io_add_const_offset_to_base. No changes. Acked-by: Alyssa Rosenzweig Part-of: --- src/compiler/nir/nir_opt_constant_folding.c | 71 +++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/compiler/nir/nir_opt_constant_folding.c b/src/compiler/nir/nir_opt_constant_folding.c index 93255944813..211dc8c5249 100644 --- a/src/compiler/nir/nir_opt_constant_folding.c +++ b/src/compiler/nir/nir_opt_constant_folding.c @@ -161,6 +161,21 @@ fail: return NULL; } +static bool +is_dual_slot_io(nir_intrinsic_instr *intrin) +{ + if (intrin->intrinsic == nir_intrinsic_store_output || + intrin->intrinsic == nir_intrinsic_store_per_vertex_output || + intrin->intrinsic == nir_intrinsic_store_per_view_output || + intrin->intrinsic == nir_intrinsic_store_per_primitive_output) { + return nir_src_bit_size(intrin->src[0]) == 64 && + nir_src_num_components(intrin->src[0]) >= 3; + } + + return intrin->def.bit_size == 64 && + intrin->def.num_components >= 3; +} + static nir_def * try_fold_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin, struct constant_fold_state *state) @@ -301,6 +316,62 @@ try_fold_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin, return nir_imm_bool(b, constant_true); } + case nir_intrinsic_load_input: + case nir_intrinsic_load_per_primitive_input: + case nir_intrinsic_load_input_vertex: + case nir_intrinsic_load_per_vertex_input: + case nir_intrinsic_load_interpolated_input: + case nir_intrinsic_load_fs_input_interp_deltas: + case nir_intrinsic_load_output: + case nir_intrinsic_load_per_vertex_output: + case nir_intrinsic_load_per_view_output: + case nir_intrinsic_load_per_primitive_output: + case nir_intrinsic_store_output: + case nir_intrinsic_store_per_vertex_output: + case nir_intrinsic_store_per_view_output: + case nir_intrinsic_store_per_primitive_output: { + if (nir_is_input_load(intrin) ? + b->shader->info.disable_input_offset_src_constant_folding : + b->shader->info.disable_output_offset_src_constant_folding) + return NULL; + + nir_io_semantics sem = nir_intrinsic_io_semantics(intrin); + + /* NV_mesh_shader: ignore MS primitive indices. */ + if (b->shader->info.stage == MESA_SHADER_MESH && + sem.location == VARYING_SLOT_PRIMITIVE_INDICES && + !(b->shader->info.per_primitive_outputs & + VARYING_BIT_PRIMITIVE_INDICES)) + return NULL; + + nir_src *offset = nir_get_io_offset_src(intrin); + + /* TODO: Better handling of per-view variables here */ + if (!nir_src_is_const(*offset) || + nir_intrinsic_io_semantics(intrin).per_view) + return NULL; + + unsigned off = nir_src_as_uint(*offset); + bool progress = false; + + if (off) { + nir_intrinsic_set_base(intrin, nir_intrinsic_base(intrin) + off); + + sem.location += off; + b->cursor = nir_before_instr(&intrin->instr); + nir_src_rewrite(offset, nir_imm_int(b, 0)); + progress = true; + } + + /* non-indirect indexing should reduce num_slots */ + sem.num_slots = is_dual_slot_io(intrin) ? 2 : 1; + + nir_io_semantics original = nir_intrinsic_io_semantics(intrin); + progress |= memcmp(&original, &sem, sizeof(sem)); + nir_intrinsic_set_io_semantics(intrin, sem); + return progress ? NIR_LOWER_INSTR_PROGRESS : NULL; + } + default: return NULL; }