From d3fb341b4a696678dd6b7f26c8fa743656715631 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 29 Oct 2021 09:41:05 -0400 Subject: [PATCH] panfrost: Combine dual source blends Reuse the store_combined_output_pan infrastructure for dual source blending as well. This simplifies ordering. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/panfrost/bifrost/bifrost_compile.c | 15 ++++++------- src/panfrost/midgard/midgard_compile.c | 30 +++++++++++++------------- src/panfrost/util/pan_ir.h | 1 + src/panfrost/util/pan_lower_writeout.c | 15 ++++++++----- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index ba641185f8e..f863c0f1490 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -574,11 +574,11 @@ bi_emit_fragment_out(bi_builder *b, nir_intrinsic_instr *instr) bool emit_blend = writeout & (PAN_WRITEOUT_C); bool emit_zs = writeout & (PAN_WRITEOUT_Z | PAN_WRITEOUT_S); - const nir_variable *var = NULL; unsigned loc = ~0; if (!combined) { - var = nir_find_variable_with_driver_location(b->shader->nir, + const nir_variable *var = + nir_find_variable_with_driver_location(b->shader->nir, nir_var_shader_out, nir_intrinsic_base(instr)); assert(var); @@ -586,6 +586,7 @@ bi_emit_fragment_out(bi_builder *b, nir_intrinsic_instr *instr) } bi_index src0 = bi_src_index(&instr->src[0]); + bi_index src1 = combined ? bi_src_index(&instr->src[4]) : bi_null(); /* By ISA convention, the coverage mask is stored in R60. The store * itself will be handled by a subsequent ATEST instruction */ @@ -600,16 +601,14 @@ bi_emit_fragment_out(bi_builder *b, nir_intrinsic_instr *instr) /* Dual-source blending is implemented by putting the color in * registers r4-r7. */ - if (var && var->data.index) { - unsigned count = nir_src_num_components(instr->src[0]); + if (writeout & PAN_WRITEOUT_2) { + unsigned count = nir_src_num_components(instr->src[4]); for (unsigned i = 0; i < count; ++i) - bi_mov_i32_to(b, bi_register(4 + i), bi_word(src0, i)); + bi_mov_i32_to(b, bi_register(4 + i), bi_word(src1, i)); b->shader->info.bifrost->blend_src1_type = - nir_intrinsic_src_type(instr); - - return; + nir_intrinsic_dest_type(instr); } /* Emit ATEST if we have to, note ATEST requires a floating-point alpha diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index ca2915ddf10..0c8d9d18501 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -1875,13 +1875,15 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr) enum midgard_rt_id rt; - unsigned reg_z = ~0, reg_s = ~0; + unsigned reg_z = ~0, reg_s = ~0, reg_2 = ~0; if (combined) { unsigned writeout = nir_intrinsic_component(instr); if (writeout & PAN_WRITEOUT_Z) reg_z = nir_src_index(ctx, &instr->src[2]); if (writeout & PAN_WRITEOUT_S) reg_s = nir_src_index(ctx, &instr->src[3]); + if (writeout & PAN_WRITEOUT_2) + reg_2 = nir_src_index(ctx, &instr->src[4]); if (writeout & PAN_WRITEOUT_C) rt = MIDGARD_COLOR_RT0; @@ -1897,24 +1899,22 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr) rt = MIDGARD_COLOR_RT0 + var->data.location - FRAG_RESULT_DATA0; + } - /* Dual-source blend writeout is done by leaving the - * value in r2 for the blend shader to use. */ - if (var->data.index) { - if (instr->src[0].is_ssa) { - emit_explicit_constant(ctx, reg, reg); + /* Dual-source blend writeout is done by leaving the + * value in r2 for the blend shader to use. */ + if (~reg_2) { + if (instr->src[4].is_ssa) { + emit_explicit_constant(ctx, reg_2, reg_2); - unsigned out = make_compiler_temp(ctx); + unsigned out = make_compiler_temp(ctx); - midgard_instruction ins = v_mov(reg, out); - emit_mir_instruction(ctx, ins); + midgard_instruction ins = v_mov(reg_2, out); + emit_mir_instruction(ctx, ins); - ctx->blend_src1 = out; - } else { - ctx->blend_src1 = reg; - } - - break; + ctx->blend_src1 = out; + } else { + ctx->blend_src1 = reg_2; } } diff --git a/src/panfrost/util/pan_ir.h b/src/panfrost/util/pan_ir.h index 9d7b38a2ecd..fb4f4c6e507 100644 --- a/src/panfrost/util/pan_ir.h +++ b/src/panfrost/util/pan_ir.h @@ -398,6 +398,7 @@ bool pan_has_dest_mod(nir_dest **dest, nir_op op); #define PAN_WRITEOUT_C 1 #define PAN_WRITEOUT_Z 2 #define PAN_WRITEOUT_S 4 +#define PAN_WRITEOUT_2 8 bool pan_nir_reorder_writeout(nir_shader *nir); bool pan_nir_lower_zs_store(nir_shader *nir); diff --git a/src/panfrost/util/pan_lower_writeout.c b/src/panfrost/util/pan_lower_writeout.c index 2c3a3f9bb5e..1afdf8dd5f7 100644 --- a/src/panfrost/util/pan_lower_writeout.c +++ b/src/panfrost/util/pan_lower_writeout.c @@ -56,6 +56,7 @@ pan_nir_emit_combined_store(nir_builder *b, intr->num_components = rt0_store ? rt0_store->src[0].ssa->num_components : 4; nir_intrinsic_set_src_type(intr, pan_nir_rt_store_type(rt0_store)); + nir_intrinsic_set_dest_type(intr, pan_nir_rt_store_type(stores[2])); nir_intrinsic_set_component(intr, writeout); nir_ssa_def *zero = nir_imm_int(b, 0); @@ -66,7 +67,7 @@ pan_nir_emit_combined_store(nir_builder *b, rt0_store ? rt0_store->src[1].ssa : zero, stores[0] ? stores[0]->src[0].ssa : zero, stores[1] ? stores[1]->src[0].ssa : zero, - zero4, + stores[2] ? stores[2]->src[0].ssa : zero4, }; for (int i = 0; i < ARRAY_SIZE(src); ++i) @@ -80,16 +81,18 @@ pan_nir_lower_zs_store(nir_shader *nir) if (nir->info.stage != MESA_SHADER_FRAGMENT) return false; - nir_variable *vars[2] = { NULL }; + nir_variable *vars[3] = { NULL }; nir_foreach_shader_out_variable(var, nir) { if (var->data.location == FRAG_RESULT_DEPTH) vars[0] = var; else if (var->data.location == FRAG_RESULT_STENCIL) vars[1] = var; + else if (var->data.index) + vars[2] = var; } - if (!vars[0] && !vars[1]) + if (!vars[0] && !vars[1] && !vars[2]) return false; bool progress = false; @@ -97,7 +100,7 @@ pan_nir_lower_zs_store(nir_shader *nir) nir_foreach_function(function, nir) { if (!function->impl) continue; - nir_intrinsic_instr *stores[2] = { NULL }; + nir_intrinsic_instr *stores[3] = { NULL }; nir_foreach_block(block, function->impl) { nir_foreach_instr_safe(instr, block) { @@ -117,7 +120,7 @@ pan_nir_lower_zs_store(nir_shader *nir) } } - if (!stores[0] && !stores[1]) continue; + if (!stores[0] && !stores[1] && !stores[2]) continue; nir_block *common_block = NULL; @@ -139,6 +142,8 @@ pan_nir_lower_zs_store(nir_shader *nir) writeout |= PAN_WRITEOUT_Z; if (stores[1]) writeout |= PAN_WRITEOUT_S; + if (stores[2]) + writeout |= PAN_WRITEOUT_2; bool replaced = false;