From: Alyssa Rosenzweig Date: Thu, 27 Feb 2020 14:15:00 +0000 (-0500) Subject: pan/midgard: Partially fix 64-bit swizzle alignment X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4e60dc8f486554656d51d541e10911b7a82a5e80;p=mesa.git pan/midgard: Partially fix 64-bit swizzle alignment When mixing 32/64-bit, we need to align the 32-bit registers to get the required alignment. This isn't quite enough yet, though, since user swizzles could bypass and will need to be lowered to 32-bit moves (outstanding todo). Signed-off-by: Alyssa Rosenzweig Part-of: --- diff --git a/src/panfrost/midgard/midgard_emit.c b/src/panfrost/midgard/midgard_emit.c index 4d58217ceeb..2b18aac3553 100644 --- a/src/panfrost/midgard/midgard_emit.c +++ b/src/panfrost/midgard/midgard_emit.c @@ -196,11 +196,17 @@ mir_pack_swizzle_alu(midgard_instruction *ins) if (mode == midgard_reg_mode_32) { bool lo = ins->swizzle[i][0] >= COMPONENT_Z; bool hi = ins->swizzle[i][1] >= COMPONENT_Z; + unsigned mask = mir_bytemask(ins); - /* TODO: can we mix halves? */ - assert(lo == hi); + if (mask & 0xFF) { + /* We can't mix halves... */ + if (mask & 0xFF00) + assert(lo == hi); - src[i].rep_low |= lo; + src[i].rep_low |= lo; + } else { + src[i].rep_low |= hi; + } } else if (mode < midgard_reg_mode_32) { unreachable("Cannot encode 8/16 swizzle in 64-bit"); } diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c index 09354f3eb53..ef3e7928044 100644 --- a/src/panfrost/midgard/midgard_ra.c +++ b/src/panfrost/midgard/midgard_ra.c @@ -477,6 +477,21 @@ allocate_registers(compiler_context *ctx, bool *spilled) unsigned *min_alignment = calloc(sizeof(unsigned), ctx->temp_count); mir_foreach_instr_global(ctx, ins) { + /* Swizzles of 32-bit sources on 64-bit instructions need to be + * aligned to either bottom (xy) or top (zw). More general + * swizzle lowering should happen prior to scheduling (TODO), + * but once we get RA we shouldn't disrupt this further. Align + * sources of 64-bit instructions. */ + + if (ins->type == TAG_ALU_4 && ins->alu.reg_mode == midgard_reg_mode_64) { + mir_foreach_src(ins, v) { + unsigned s = ins->src[v]; + + if (s < ctx->temp_count) + min_alignment[s] = 3; + } + } + if (ins->dest >= SSA_FIXED_MINIMUM) continue; /* 0 for x, 1 for xy, 2 for xyz, 3 for xyzw */