From 0ff16506628216e06d876aab5cc498f71067b2af Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 4 May 2026 11:29:33 +0200 Subject: [PATCH] ac/nir/lower_tex_coord: fix moving wqm coordinates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even if they are in the same block, we might still need to move the source instructions if they are otherwise after our insert location. This can happen in the case where we insert strict_wqm_coord before terminate_if. Fixes: ac33f82d54b ("ac/nir/lower_tex_coords: move input loads instead of cloning them") Reviewed-by: Marek Olšák Part-of: --- src/amd/common/nir/ac_nir_lower_tex_coords.c | 35 ++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/amd/common/nir/ac_nir_lower_tex_coords.c b/src/amd/common/nir/ac_nir_lower_tex_coords.c index 4af0335aa29..f1dfe87156c 100644 --- a/src/amd/common/nir/ac_nir_lower_tex_coords.c +++ b/src/amd/common/nir/ac_nir_lower_tex_coords.c @@ -289,6 +289,30 @@ struct loop_if_state { unsigned prev_break_continue; }; +static bool +instr_needs_move(nir_cursor cursor, nir_instr *instr) +{ + nir_block *cursor_block = nir_cursor_current_block(cursor); + + if (instr->block->index > cursor_block->index) + return true; + if (instr->block->index < cursor_block->index) + return false; + + switch (cursor.option) { + case nir_cursor_before_block: return true; + case nir_cursor_after_block: return false; + case nir_cursor_before_instr: + case nir_cursor_after_instr: + foreach_list_typed_from(nir_instr, other, node, &(block)->instr_list, &cursor.instr->node) { + if (instr == other) + return true; + } + return false; + default: UNREACHABLE("unhandled cursor mode"); + } +} + static nir_def * build_coordinate(struct move_tex_coords_state *state, nir_scalar scalar, coord_info info) { @@ -302,18 +326,17 @@ build_coordinate(struct move_tex_coords_state *state, nir_scalar scalar, coord_i ASSERTED nir_src offset = *nir_get_io_offset_src(info.load); assert(nir_src_is_const(offset) && !nir_src_as_uint(offset)); - nir_block *cursor_block = nir_cursor_current_block(b->cursor); - /* Move load_*input(barycentric, imm) to the cursor block if it's after that block. */ - if (info.load->instr.block->index > cursor_block->index) { + /* Move load_*input(barycentric, imm) to the cursor location if nessecary. */ + if (instr_needs_move(b->cursor, &info.load->instr)) { nir_instr_move(b->cursor, &info.load->instr); unsigned num_srcs = nir_intrinsic_infos[info.load->intrinsic].num_srcs; for (unsigned i = 0; i < num_srcs; i++) { - if (nir_def_instr(info.load->src[i].ssa)->block->index > cursor_block->index) { - nir_instr_move(nir_before_instr(&info.load->instr), - nir_def_instr(info.load->src[i].ssa)); + nir_cursor cursor = nir_before_instr(&info.load->instr); + if (instr_needs_move(cursor, nir_def_instr(info.load->src[i].ssa))) { + nir_instr_move(cursor, nir_def_instr(info.load->src[i].ssa)); } } }