pan/midgard: Extend swizzle packing for vec4/16-bit
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 31 Oct 2019 18:56:45 +0000 (14:56 -0400)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 4 Nov 2019 20:36:08 +0000 (15:36 -0500)
We would like to pack not just xyzw swizzles but also efgh swizzles.
This should work for vec4/16-bit. More work will be needed to pack
swizzles for vec8/16-bit and even more work for 8-bit, of course.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/panfrost/midgard/midgard_emit.c

index f3f38c418d4f7d8ca42789c1b21ca2e9953e8446..8bc4bb0e0dddddfbe1a0fd955caa7724417b8b50 100644 (file)
@@ -136,17 +136,38 @@ mir_pack_swizzle_alu(midgard_instruction *ins)
         for (unsigned i = 0; i < 2; ++i) {
                 unsigned packed = 0;
 
-                /* TODO: non-32-bit, non-vec4 */
+                /* For 32-bit, swizzle packing is stupid-simple. For 16-bit,
+                 * the strategy is to check whether the nibble we're on is
+                 * upper or lower. We need all components to be on the same
+                 * "side"; that much is enforced by the ISA and should have
+                 * been lowered. TODO: 8-bit/64-bit packing. TODO: vec8 */
+
+                unsigned first = ins->mask ? ffs(ins->mask) - 1 : 0;
+                bool upper = ins->swizzle[i][first] > 3;
+
+                if (upper && ins->mask)
+                        assert(mir_srcsize(ins, i) <= midgard_reg_mode_16);
+
                 for (unsigned c = 0; c < 4; ++c) {
                         unsigned v = ins->swizzle[i][c];
 
-                        /* Check vec4 */
-                        assert(v <= 3);
+                        bool t_upper = v > 3;
+
+                        /* Ensure we're doing something sane */
+
+                        if (ins->mask & (1 << c)) {
+                                assert(t_upper == upper);
+                                assert(v <= 7);
+                        }
+
+                        /* Use the non upper part */
+                        v &= 0x3;
 
                         packed |= v << (2 * c);
                 }
 
                 src[i].swizzle = packed;
+                src[i].rep_high = upper;
         }
 
         ins->alu.src1 = vector_alu_srco_unsigned(src[0]);