mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 04:50:11 +01:00
pan/mdg: Treat inot as a modifier
With this, we may remove all invert passes and simply look at the src modifier on NIR->MIR and fixup at pack time. No shader-db changes. Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5102>
This commit is contained in:
parent
b124f5315c
commit
449e5ded93
5 changed files with 105 additions and 8 deletions
|
|
@ -136,6 +136,9 @@ typedef struct midgard_instruction {
|
||||||
|
|
||||||
bool invert;
|
bool invert;
|
||||||
|
|
||||||
|
/* For accepting ALU ops - invert the nth source */
|
||||||
|
bool src_invert[MIR_SRC_COUNT];
|
||||||
|
|
||||||
/* Hint for the register allocator not to spill the destination written
|
/* Hint for the register allocator not to spill the destination written
|
||||||
* from this instruction (because it is a spill/unspill node itself).
|
* from this instruction (because it is a spill/unspill node itself).
|
||||||
* Bitmask of spilled classes */
|
* Bitmask of spilled classes */
|
||||||
|
|
|
||||||
|
|
@ -486,6 +486,7 @@ optimise_nir(nir_shader *nir, unsigned quirks)
|
||||||
|
|
||||||
/* Now that booleans are lowered, we can run out late opts */
|
/* Now that booleans are lowered, we can run out late opts */
|
||||||
NIR_PASS(progress, nir, midgard_nir_lower_algebraic_late);
|
NIR_PASS(progress, nir, midgard_nir_lower_algebraic_late);
|
||||||
|
NIR_PASS(progress, nir, midgard_nir_cancel_inot);
|
||||||
|
|
||||||
NIR_PASS(progress, nir, nir_copy_prop);
|
NIR_PASS(progress, nir, nir_copy_prop);
|
||||||
NIR_PASS(progress, nir, nir_opt_dce);
|
NIR_PASS(progress, nir, nir_opt_dce);
|
||||||
|
|
@ -599,8 +600,25 @@ reg_mode_for_nir(nir_alu_instr *instr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compare mir_lower_invert */
|
||||||
|
static bool
|
||||||
|
nir_accepts_inot(nir_op op, unsigned src)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case nir_op_ior:
|
||||||
|
case nir_op_iand:
|
||||||
|
case nir_op_ixor:
|
||||||
|
return true;
|
||||||
|
case nir_op_b32csel:
|
||||||
|
/* Only the condition */
|
||||||
|
return (src == 0);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mir_copy_src(midgard_instruction *ins, nir_alu_instr *instr, unsigned i, unsigned to, bool *abs, bool *neg, bool is_int, unsigned bcast_count)
|
mir_copy_src(midgard_instruction *ins, nir_alu_instr *instr, unsigned i, unsigned to, bool *abs, bool *neg, bool *not, bool is_int, unsigned bcast_count)
|
||||||
{
|
{
|
||||||
nir_alu_src src = instr->src[i];
|
nir_alu_src src = instr->src[i];
|
||||||
|
|
||||||
|
|
@ -612,6 +630,9 @@ mir_copy_src(midgard_instruction *ins, nir_alu_instr *instr, unsigned i, unsigne
|
||||||
*abs = true;
|
*abs = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nir_accepts_inot(instr->op, i) && pan_has_source_mod(&src, nir_op_inot))
|
||||||
|
*not = true;
|
||||||
|
|
||||||
unsigned bits = nir_src_bit_size(src.src);
|
unsigned bits = nir_src_bit_size(src.src);
|
||||||
|
|
||||||
ins->src[to] = nir_src_index(NULL, &src.src);
|
ins->src[to] = nir_src_index(NULL, &src.src);
|
||||||
|
|
@ -750,8 +771,9 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
|
||||||
ALU_CASE(fsin, fsin);
|
ALU_CASE(fsin, fsin);
|
||||||
ALU_CASE(fcos, fcos);
|
ALU_CASE(fcos, fcos);
|
||||||
|
|
||||||
/* We'll set invert */
|
/* We'll get 0 in the second arg, so:
|
||||||
ALU_CASE(inot, imov);
|
* ~a = ~(a | 0) = nor(a, 0) */
|
||||||
|
ALU_CASE(inot, inor);
|
||||||
ALU_CASE(iand, iand);
|
ALU_CASE(iand, iand);
|
||||||
ALU_CASE(ior, ior);
|
ALU_CASE(ior, ior);
|
||||||
ALU_CASE(ixor, ixor);
|
ALU_CASE(ixor, ixor);
|
||||||
|
|
@ -899,7 +921,7 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
|
||||||
|
|
||||||
if (quirk_flipped_r24) {
|
if (quirk_flipped_r24) {
|
||||||
ins.src[0] = ~0;
|
ins.src[0] = ~0;
|
||||||
mir_copy_src(&ins, instr, 0, 1, &abs[1], &neg[1], is_int, broadcast_swizzle);
|
mir_copy_src(&ins, instr, 0, 1, &abs[1], &neg[1], &ins.src_invert[1], is_int, broadcast_swizzle);
|
||||||
} else {
|
} else {
|
||||||
for (unsigned i = 0; i < nr_inputs; ++i) {
|
for (unsigned i = 0; i < nr_inputs; ++i) {
|
||||||
unsigned to = i;
|
unsigned to = i;
|
||||||
|
|
@ -912,13 +934,21 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
to = 2;
|
to = 2;
|
||||||
|
else if (flip_src12)
|
||||||
|
to = 2 - i;
|
||||||
else
|
else
|
||||||
to = i - 1;
|
to = i - 1;
|
||||||
} else if (flip_src12) {
|
} else if (flip_src12) {
|
||||||
to = 1 - to;
|
to = 1 - to;
|
||||||
}
|
}
|
||||||
|
|
||||||
mir_copy_src(&ins, instr, i, to, &abs[to], &neg[to], is_int, broadcast_swizzle);
|
mir_copy_src(&ins, instr, i, to, &abs[to], &neg[to], &ins.src_invert[to], is_int, broadcast_swizzle);
|
||||||
|
|
||||||
|
/* (!c) ? a : b = c ? b : a */
|
||||||
|
if (instr->op == nir_op_b32csel && ins.src_invert[2]) {
|
||||||
|
ins.src_invert[2] = false;
|
||||||
|
flip_src12 ^= true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -952,6 +982,13 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
|
||||||
|
|
||||||
ins.alu = alu;
|
ins.alu = alu;
|
||||||
|
|
||||||
|
/* Arrange for creation of iandnot/iornot */
|
||||||
|
if (ins.src_invert[0] && !ins.src_invert[1]) {
|
||||||
|
mir_flip(&ins);
|
||||||
|
ins.src_invert[0] = false;
|
||||||
|
ins.src_invert[1] = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Late fixup for emulated instructions */
|
/* Late fixup for emulated instructions */
|
||||||
|
|
||||||
if (instr->op == nir_op_b2f32 || instr->op == nir_op_b2i32) {
|
if (instr->op == nir_op_b2f32 || instr->op == nir_op_b2i32) {
|
||||||
|
|
@ -982,8 +1019,6 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
|
||||||
|
|
||||||
for (unsigned c = 0; c < 16; ++c)
|
for (unsigned c = 0; c < 16; ++c)
|
||||||
ins.swizzle[1][c] = 0;
|
ins.swizzle[1][c] = 0;
|
||||||
} else if (instr->op == nir_op_inot) {
|
|
||||||
ins.invert = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((opcode_props & UNITS_ALL) == UNIT_VLUT) {
|
if ((opcode_props & UNITS_ALL) == UNIT_VLUT) {
|
||||||
|
|
@ -2494,18 +2529,20 @@ midgard_compile_shader_nir(nir_shader *nir, panfrost_program *program, bool is_b
|
||||||
progress |= midgard_opt_dead_code_eliminate(ctx, block);
|
progress |= midgard_opt_dead_code_eliminate(ctx, block);
|
||||||
progress |= midgard_opt_combine_projection(ctx, block);
|
progress |= midgard_opt_combine_projection(ctx, block);
|
||||||
progress |= midgard_opt_varying_projection(ctx, block);
|
progress |= midgard_opt_varying_projection(ctx, block);
|
||||||
|
#if 0
|
||||||
progress |= midgard_opt_not_propagate(ctx, block);
|
progress |= midgard_opt_not_propagate(ctx, block);
|
||||||
progress |= midgard_opt_fuse_src_invert(ctx, block);
|
progress |= midgard_opt_fuse_src_invert(ctx, block);
|
||||||
progress |= midgard_opt_fuse_dest_invert(ctx, block);
|
progress |= midgard_opt_fuse_dest_invert(ctx, block);
|
||||||
progress |= midgard_opt_csel_invert(ctx, block);
|
progress |= midgard_opt_csel_invert(ctx, block);
|
||||||
progress |= midgard_opt_drop_cmp_invert(ctx, block);
|
progress |= midgard_opt_drop_cmp_invert(ctx, block);
|
||||||
progress |= midgard_opt_invert_branch(ctx, block);
|
progress |= midgard_opt_invert_branch(ctx, block);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} while (progress);
|
} while (progress);
|
||||||
|
|
||||||
mir_foreach_block(ctx, _block) {
|
mir_foreach_block(ctx, _block) {
|
||||||
midgard_block *block = (midgard_block *) _block;
|
midgard_block *block = (midgard_block *) _block;
|
||||||
midgard_lower_invert(ctx, block);
|
//midgard_lower_invert(ctx, block);
|
||||||
midgard_lower_derivatives(ctx, block);
|
midgard_lower_derivatives(ctx, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -328,6 +328,51 @@ mir_pack_ldst_mask(midgard_instruction *ins)
|
||||||
ins->load_store.mask = packed;
|
ins->load_store.mask = packed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mir_lower_inverts(midgard_instruction *ins)
|
||||||
|
{
|
||||||
|
bool inv[3] = {
|
||||||
|
ins->src_invert[0],
|
||||||
|
ins->src_invert[1],
|
||||||
|
ins->src_invert[2]
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (ins->alu.op) {
|
||||||
|
case midgard_alu_op_iand:
|
||||||
|
/* a & ~b = iandnot(a, b) */
|
||||||
|
/* ~a & ~b = ~(a | b) = inor(a, b) */
|
||||||
|
|
||||||
|
if (inv[0] && inv[1])
|
||||||
|
ins->alu.op = midgard_alu_op_inor;
|
||||||
|
else if (inv[1])
|
||||||
|
ins->alu.op = midgard_alu_op_iandnot;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case midgard_alu_op_ior:
|
||||||
|
/* a | ~b = iornot(a, b) */
|
||||||
|
/* ~a | ~b = ~(a & b) = inand(a, b) */
|
||||||
|
|
||||||
|
if (inv[0] && inv[1])
|
||||||
|
ins->alu.op = midgard_alu_op_inand;
|
||||||
|
else if (inv[1])
|
||||||
|
ins->alu.op = midgard_alu_op_iornot;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case midgard_alu_op_ixor:
|
||||||
|
/* ~a ^ b = a ^ ~b = ~(a ^ b) = inxor(a, b) */
|
||||||
|
/* ~a ^ ~b = a ^ b */
|
||||||
|
|
||||||
|
if (inv[0] ^ inv[1])
|
||||||
|
ins->alu.op = midgard_alu_op_inxor;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_alu_bundle(compiler_context *ctx,
|
emit_alu_bundle(compiler_context *ctx,
|
||||||
midgard_bundle *bundle,
|
midgard_bundle *bundle,
|
||||||
|
|
@ -361,6 +406,9 @@ emit_alu_bundle(compiler_context *ctx,
|
||||||
/* In case we demote to a scalar */
|
/* In case we demote to a scalar */
|
||||||
midgard_scalar_alu scalarized;
|
midgard_scalar_alu scalarized;
|
||||||
|
|
||||||
|
if (!ins->compact_branch)
|
||||||
|
mir_lower_inverts(ins);
|
||||||
|
|
||||||
if (ins->unit & UNITS_ANY_VECTOR) {
|
if (ins->unit & UNITS_ANY_VECTOR) {
|
||||||
mir_pack_mask_alu(ins);
|
mir_pack_mask_alu(ins);
|
||||||
mir_pack_swizzle_alu(ins);
|
mir_pack_swizzle_alu(ins);
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@
|
||||||
|
|
||||||
bool midgard_nir_lower_algebraic_late(nir_shader *shader);
|
bool midgard_nir_lower_algebraic_late(nir_shader *shader);
|
||||||
bool midgard_nir_scale_trig(nir_shader *shader);
|
bool midgard_nir_scale_trig(nir_shader *shader);
|
||||||
|
bool midgard_nir_cancel_inot(nir_shader *shader);
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,11 @@ constant_switch = [
|
||||||
(('ult32', '#a', 'b'), ('inot', ('uge32', a, b)))
|
(('ult32', '#a', 'b'), ('inot', ('uge32', a, b)))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# ..since the above switching happens after algebraic stuff is done
|
||||||
|
cancel_inot = [
|
||||||
|
(('inot', ('inot', a)), a)
|
||||||
|
]
|
||||||
|
|
||||||
# Midgard scales fsin/fcos arguments by pi.
|
# Midgard scales fsin/fcos arguments by pi.
|
||||||
# Pass must be run only once, after the main loop
|
# Pass must be run only once, after the main loop
|
||||||
|
|
||||||
|
|
@ -140,6 +145,9 @@ def run():
|
||||||
print(nir_algebraic.AlgebraicPass("midgard_nir_scale_trig",
|
print(nir_algebraic.AlgebraicPass("midgard_nir_scale_trig",
|
||||||
scale_trig).render())
|
scale_trig).render())
|
||||||
|
|
||||||
|
print(nir_algebraic.AlgebraicPass("midgard_nir_cancel_inot",
|
||||||
|
cancel_inot).render())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue