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 <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13714>
This commit is contained in:
Alyssa Rosenzweig
2021-10-29 09:41:05 -04:00
committed by Marge Bot
parent 24ea7cbb06
commit d3fb341b4a
4 changed files with 33 additions and 28 deletions
+7 -8
View File
@@ -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
+15 -15
View File
@@ -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;
}
}
+1
View File
@@ -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);
+10 -5
View File
@@ -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;