pan: Switch to nir_intrinsic_load_blend_input_pan

It's a lot more explicit to just have an intrinsic for this than to
treat blend shaders as their own weird stage.  Also, the new intrinsic
uses the same io_semantics as a fragment store so the back-end code is a
little easier to read because it now checks sem.dual_source_blend_index
instead of the generic load_input offset.

Reviewed-by: Christoph Pillmayer <christoph.pillmayer@arm.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39244>
This commit is contained in:
Faith Ekstrand 2026-01-09 17:30:36 -05:00 committed by Marge Bot
parent f53751159a
commit 80bdd7019a
3 changed files with 27 additions and 20 deletions

View file

@ -907,7 +907,7 @@ static void
bi_emit_load_blend_input(bi_builder *b, nir_intrinsic_instr *instr)
{
nir_io_semantics sem = nir_intrinsic_io_semantics(instr);
unsigned base = (sem.location == VARYING_SLOT_VAR0) ? 4 : 0;
unsigned base = sem.dual_source_blend_index * 4;
unsigned size = nir_alu_type_get_type_size(nir_intrinsic_dest_type(instr));
assert(size == 16 || size == 32);
@ -2194,11 +2194,14 @@ bi_emit_intrinsic(bi_builder *b, nir_intrinsic_instr *instr)
bi_emit_load_attr(b, instr);
break;
case nir_intrinsic_load_blend_input_pan:
bi_emit_load_blend_input(b, instr);
break;
case nir_intrinsic_load_interpolated_input:
case nir_intrinsic_load_input:
if (b->shader->inputs->is_blend)
bi_emit_load_blend_input(b, instr);
else if (stage == MESA_SHADER_FRAGMENT)
assert(!b->shader->inputs->is_blend);
if (stage == MESA_SHADER_FRAGMENT)
bi_emit_load_vary(b, instr);
else if (stage == MESA_SHADER_VERTEX)
bi_emit_load_attr(b, instr);

View file

@ -1727,18 +1727,6 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
} else if (ctx->stage == MESA_SHADER_FRAGMENT && !ctx->inputs->is_blend) {
emit_varying_read(ctx, reg, offset, nr_comp, component,
indirect_offset, t | instr->def.bit_size, is_flat);
} else if (ctx->inputs->is_blend) {
/* ctx->blend_input will be precoloured to r0/r2, where
* the input is preloaded */
unsigned *input = offset ? &ctx->blend_src1 : &ctx->blend_input;
if (*input == ~0)
*input = reg;
else {
struct midgard_instruction ins = v_mov(*input, reg);
emit_mir_instruction(ctx, &ins);
}
} else if (ctx->stage == MESA_SHADER_VERTEX) {
emit_attr_read(ctx, reg, offset, nr_comp, t);
} else {
@ -1748,6 +1736,21 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
break;
}
case nir_intrinsic_load_blend_input_pan: {
nir_io_semantics sem = nir_intrinsic_io_semantics(instr);
unsigned *input = sem.dual_source_blend_index ? &ctx->blend_src1
: &ctx->blend_input;
reg = nir_def_index(&instr->def);
if (*input == ~0) {
*input = reg;
} else {
struct midgard_instruction ins = v_mov(*input, reg);
emit_mir_instruction(ctx, &ins);
}
break;
}
/* Handled together with load_interpolated_input */
case nir_intrinsic_load_barycentric_pixel:
case nir_intrinsic_load_barycentric_centroid:

View file

@ -918,10 +918,11 @@ GENX(pan_blend_create_shader)(const struct pan_blend_state *state,
src_type = nir_alu_type_get_base_type(nir_type) |
nir_alu_type_get_type_size(src_type);
nir_def *src = nir_load_input(
&b, 4, nir_alu_type_get_type_size(src_type), zero,
.io_semantics.location = i ? VARYING_SLOT_VAR0 : VARYING_SLOT_COL0,
.io_semantics.num_slots = 1, .base = i, .dest_type = src_type);
nir_def *src = nir_load_blend_input_pan(
&b, 4, nir_alu_type_get_type_size(src_type),
.io_semantics.location = FRAG_RESULT_DATA0 + rt,
.io_semantics.dual_source_blend_index = i,
.io_semantics.num_slots = 1, .dest_type = src_type);
if (state->alpha_to_one && src_type == nir_type_float32) {
/* force alpha to 1 */