mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-01 11:50:09 +01:00
pan/mdg: Dual source blend input/writeout support
We write to r2, which is preseved through to the blend shader, from where it is read. We won't worry about MRT to keep things simple. Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5620>
This commit is contained in:
parent
0ff6263534
commit
85954ecfef
9 changed files with 54 additions and 7 deletions
|
|
@ -246,6 +246,9 @@ typedef struct compiler_context {
|
|||
/* Index to precolour to r0 for an input blend colour */
|
||||
unsigned blend_input;
|
||||
|
||||
/* Index to precolour to r2 for a dual-source blend colour */
|
||||
unsigned blend_src1;
|
||||
|
||||
/* Tracking for blend constant patching */
|
||||
int blend_constant_offset;
|
||||
|
||||
|
|
|
|||
|
|
@ -1767,13 +1767,15 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
|
|||
} else if (ctx->stage == MESA_SHADER_FRAGMENT && !ctx->is_blend) {
|
||||
emit_varying_read(ctx, reg, offset, nr_comp, component, indirect_offset, t | nir_dest_bit_size(instr->dest), is_flat);
|
||||
} else if (ctx->is_blend) {
|
||||
/* ctx->blend_input will be precoloured to r0, where
|
||||
/* ctx->blend_input will be precoloured to r0/r2, where
|
||||
* the input is preloaded */
|
||||
|
||||
if (ctx->blend_input == ~0)
|
||||
ctx->blend_input = reg;
|
||||
unsigned *input = offset ? &ctx->blend_src1 : &ctx->blend_input;
|
||||
|
||||
if (*input == ~0)
|
||||
*input = reg;
|
||||
else
|
||||
emit_mir_instruction(ctx, v_mov(ctx->blend_input, reg));
|
||||
emit_mir_instruction(ctx, v_mov(*input, reg));
|
||||
} else if (ctx->stage == MESA_SHADER_VERTEX) {
|
||||
emit_attr_read(ctx, reg, offset, nr_comp, t);
|
||||
} else {
|
||||
|
|
@ -1867,11 +1869,30 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
|
|||
nir_intrinsic_store_combined_output_pan;
|
||||
|
||||
const nir_variable *var;
|
||||
enum midgard_rt_id rt;
|
||||
|
||||
var = search_var(&ctx->nir->outputs,
|
||||
nir_intrinsic_base(instr));
|
||||
assert(var);
|
||||
|
||||
/* 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);
|
||||
|
||||
unsigned out = make_compiler_temp(ctx);
|
||||
|
||||
midgard_instruction ins = v_mov(reg, out);
|
||||
emit_mir_instruction(ctx, ins);
|
||||
|
||||
ctx->blend_src1 = out;
|
||||
} else {
|
||||
ctx->blend_src1 = reg;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
enum midgard_rt_id rt;
|
||||
if (var->data.location == FRAG_RESULT_COLOR)
|
||||
rt = MIDGARD_COLOR_RT0;
|
||||
else if (var->data.location >= FRAG_RESULT_DATA0)
|
||||
|
|
@ -2818,6 +2839,7 @@ midgard_compile_shader_nir(nir_shader *nir, panfrost_program *program, bool is_b
|
|||
ctx->alpha_ref = program->alpha_ref;
|
||||
ctx->blend_rt = MIDGARD_COLOR_RT0 + blend_rt;
|
||||
ctx->blend_input = ~0;
|
||||
ctx->blend_src1 = ~0;
|
||||
ctx->quirks = midgard_get_quirks(gpu_id);
|
||||
|
||||
/* Start off with a safe cutoff, allowing usage of all 16 work
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@ midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block)
|
|||
if (skip)
|
||||
continue;
|
||||
|
||||
if (ctx->blend_src1 == to)
|
||||
ctx->blend_src1 = from;
|
||||
|
||||
/* We're clear -- rewrite, composing the swizzle */
|
||||
mir_rewrite_index_src_swizzle(ctx, to, from, ins->swizzle[1]);
|
||||
mir_remove_instruction(ins);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ can_cull_mask(compiler_context *ctx, midgard_instruction *ins)
|
|||
if (ins->dest >= ctx->temp_count)
|
||||
return false;
|
||||
|
||||
if (ins->dest == ctx->blend_src1)
|
||||
return false;
|
||||
|
||||
if (ins->type == TAG_LOAD_STORE_4)
|
||||
if (load_store_opcode_props[ins->load_store.op].props & LDST_SPECIAL_MASK)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -630,6 +630,15 @@ allocate_registers(compiler_context *ctx, bool *spilled)
|
|||
l->solutions[ctx->blend_input] = 0;
|
||||
}
|
||||
|
||||
/* Same for the dual-source blend input/output, except here we use r2,
|
||||
* which is also set in the fragment shader. */
|
||||
|
||||
if (ctx->blend_src1 != ~0) {
|
||||
assert(ctx->blend_src1 < ctx->temp_count);
|
||||
l->solutions[ctx->blend_src1] = (16 * 2);
|
||||
ctx->work_registers = MAX2(ctx->work_registers, 2);
|
||||
}
|
||||
|
||||
mir_compute_interference(ctx, l);
|
||||
|
||||
*spilled = !lcra_solve(l);
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ mir_pipeline_ins(
|
|||
if (node >= SSA_FIXED_MINIMUM)
|
||||
return false;
|
||||
|
||||
if (node == ctx->blend_src1)
|
||||
return false;
|
||||
|
||||
/* Analyze the bundle for a per-byte read mask */
|
||||
|
||||
for (unsigned j = 0; j < bundle->instruction_count; ++j) {
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ mir_rewrite_index_dst(compiler_context *ctx, unsigned old, unsigned new)
|
|||
/* Implicitly written before the shader */
|
||||
if (ctx->blend_input == old)
|
||||
ctx->blend_input = new;
|
||||
|
||||
if (ctx->blend_src1 == old)
|
||||
ctx->blend_src1 = new;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ midgard_promote_uniforms(compiler_context *ctx)
|
|||
/* We do need the move for safety for a non-SSA dest, or if
|
||||
* we're being fed into a special class */
|
||||
|
||||
bool needs_move = ins->dest & PAN_IS_REG;
|
||||
bool needs_move = ins->dest & PAN_IS_REG || ins->dest == ctx->blend_src1;
|
||||
|
||||
if (ins->dest < ctx->temp_count)
|
||||
needs_move |= BITSET_TEST(special, ins->dest);
|
||||
|
|
|
|||
|
|
@ -80,4 +80,5 @@ mir_squeeze_index(compiler_context *ctx)
|
|||
}
|
||||
|
||||
ctx->blend_input = find_or_allocate_temp(ctx, ctx->blend_input);
|
||||
ctx->blend_src1 = find_or_allocate_temp(ctx, ctx->blend_src1);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue