pan/midgard: Partially fix 64-bit swizzle alignment
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 27 Feb 2020 14:15:00 +0000 (09:15 -0500)
committerMarge Bot <eric+marge@anholt.net>
Thu, 27 Feb 2020 21:02:35 +0000 (21:02 +0000)
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 <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3978>

src/panfrost/midgard/midgard_emit.c
src/panfrost/midgard/midgard_ra.c

index 4d58217ceeb96fab140f28e4528009b31cb82f1c..2b18aac3553f7965fb7f53f5d1fa439eac74a77c 100644 (file)
@@ -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");
                         }
index 09354f3eb5367351856d734f6889faaa89b34b2f..ef3e79280441ee19aa5ee3226e6d9386f047e342 100644 (file)
@@ -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 */