From caabd41cd14e3e562e0ee36212bb431a70689f16 Mon Sep 17 00:00:00 2001 From: "Eric R. Smith" Date: Thu, 7 Mar 2024 16:55:20 -0400 Subject: [PATCH] panfrost: make sure blends always have 4 components bi_emit_blend_op has a hardcoded assumption that 4 components were used for blending. This causes validation errors in some situations where fewer components were actually used, because the number of staging registers did not match the number of registers in the actual input. Fix this by extending the source to 4 components. Signed-off-by: Eric R. Smith Part-of: --- src/panfrost/compiler/bifrost_compile.c | 32 +++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/panfrost/compiler/bifrost_compile.c b/src/panfrost/compiler/bifrost_compile.c index dbbae9339e1..9f2f404d61c 100644 --- a/src/panfrost/compiler/bifrost_compile.c +++ b/src/panfrost/compiler/bifrost_compile.c @@ -860,6 +860,33 @@ bi_emit_atest(bi_builder *b, bi_index alpha) b->shader->emitted_atest = true; } +static bi_index +bi_src_color_vec4(bi_builder *b, nir_src *src, nir_alu_type T) +{ + unsigned num_components = nir_src_num_components(*src); + bi_index base = bi_src_index(src); + + /* short-circuit the common case */ + if (num_components == 4) + return base; + + unsigned size = nir_alu_type_get_type_size(T); + assert(size == 16 || size == 32); + + bi_index src_vals[4]; + + unsigned i; + for (i = 0; i < num_components; i++) + src_vals[i] = bi_extract(b, base, i); + + for(; i < 3; i++) + src_vals[i] = (size == 16) ? bi_imm_f16(0.0) : bi_imm_f32(0.0); + src_vals[3] = (size == 16) ? bi_imm_f16(1.0) : bi_imm_f32(1.0); + bi_index temp = bi_temp(b->shader); + bi_make_vec_to(b, temp, src_vals, NULL, 4, size); + return temp; +} + static void bi_emit_fragment_out(bi_builder *b, nir_intrinsic_instr *instr) { @@ -922,9 +949,10 @@ bi_emit_fragment_out(bi_builder *b, nir_intrinsic_instr *instr) if (emit_blend) { unsigned rt = loc ? (loc - FRAG_RESULT_DATA0) : 0; bool dual = (writeout & PAN_WRITEOUT_2); - bi_index color = bi_src_index(&instr->src[0]); - bi_index color2 = dual ? bi_src_index(&instr->src[4]) : bi_null(); + nir_alu_type T = nir_intrinsic_src_type(instr); nir_alu_type T2 = dual ? nir_intrinsic_dest_type(instr) : 0; + bi_index color = bi_src_color_vec4(b, &instr->src[0], T); + bi_index color2 = dual ? bi_src_color_vec4(b, &instr->src[4], T2) : bi_null(); /* Explicit copy since BLEND inputs are precoloured to R0-R3, * TODO: maybe schedule around this or implement in RA as a