From fa9b2e7404157ae58700d86eb04df68bbaf35d8e Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 12 Jan 2026 16:56:28 -0500 Subject: [PATCH] pan/bi: Add a bi_instr::blend_target On Bifrost, we have to return the blend return offset in the compiled shader info and that means we need to be able to index into an array by blend target deep inside the compiler. Instead of assuming bound blend targets and subtracting BIR_FAU_BLEND_0 from fau_idx, add a separte blend_target to bi_instr and use that. This way what we return will be based on the nir_io_semantics::location, regardless of where the actual blend descriptor comes from. Reviewed-by: Lars-Ivar Hesselberg Simonsen Part-of: --- src/panfrost/compiler/bifrost/bifrost/bi_pack.c | 2 +- src/panfrost/compiler/bifrost/bifrost_compile.c | 9 +++++---- src/panfrost/compiler/bifrost/compiler.h | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/panfrost/compiler/bifrost/bifrost/bi_pack.c b/src/panfrost/compiler/bifrost/bifrost/bi_pack.c index 3bf1202ca99..97c09abe685 100644 --- a/src/panfrost/compiler/bifrost/bifrost/bi_pack.c +++ b/src/panfrost/compiler/bifrost/bifrost/bi_pack.c @@ -693,7 +693,7 @@ bi_collect_blend_ret_addr(bi_context *ctx, struct util_dynarray *emission, if (!ins || ins->op != BI_OPCODE_BLEND) return; - unsigned loc = tuple->regs.fau_idx - BIR_FAU_BLEND_0; + unsigned loc = ins->blend_target; assert(loc < ARRAY_SIZE(ctx->info.bifrost->blend)); assert(!ctx->info.bifrost->blend[loc].return_offset); ctx->info.bifrost->blend[loc].return_offset = diff --git a/src/panfrost/compiler/bifrost/bifrost_compile.c b/src/panfrost/compiler/bifrost/bifrost_compile.c index e2620793a1e..26db679dfd4 100644 --- a/src/panfrost/compiler/bifrost/bifrost_compile.c +++ b/src/panfrost/compiler/bifrost/bifrost_compile.c @@ -2168,15 +2168,16 @@ bi_emit_intrinsic(bi_builder *b, nir_intrinsic_instr *instr) bi_make_vec_to(b, rgba, srcs, channels, 4, size); } - bi_blend_to(b, bi_temp(b->shader), rgba, coverage, - bi_extract(b, desc, 0), bi_extract(b, desc, 1), - rgba2, regfmt, sr_count, sr_count_2); - nir_io_semantics io = nir_intrinsic_io_semantics(instr); assert(io.location >= FRAG_RESULT_DATA0); assert(io.location <= FRAG_RESULT_DATA7); unsigned rt = io.location - FRAG_RESULT_DATA0; + bi_instr *I = bi_blend_to(b, bi_temp(b->shader), rgba, coverage, + bi_extract(b, desc, 0), bi_extract(b, desc, 1), + rgba2, regfmt, sr_count, sr_count_2); + I->blend_target = rt; + b->shader->info.bifrost->blend[rt].type = T; if (instr->intrinsic == nir_intrinsic_blend2_pan) { assert(b->shader->info.bifrost->blend_src1_type == nir_type_invalid); diff --git a/src/panfrost/compiler/bifrost/compiler.h b/src/panfrost/compiler/bifrost/compiler.h index 6936948bd5d..b95ee5e7319 100644 --- a/src/panfrost/compiler/bifrost/compiler.h +++ b/src/panfrost/compiler/bifrost/compiler.h @@ -629,6 +629,7 @@ typedef struct { bool format; /* LEA_TEX */ bool z_stencil; /* LD_TILE */ bool scheduling_barrier; /* NOP */ + unsigned blend_target; /* BLEND */ struct { enum bi_special special; /* FADD_RSCALE, FMA_RSCALE */