pan/mdg: Separately pack constants to the upper half
[mesa.git] / src / panfrost / midgard / midgard_schedule.c
index 93e7e9bb87a9e22c8931f4241ff6bb6683ffae2a..a365cfaf09ea76eb9db2006ab732468dcd48b8e9 100644 (file)
@@ -351,7 +351,8 @@ static bool
 mir_adjust_constant(midgard_instruction *ins, unsigned src,
                 unsigned *bundle_constant_mask,
                 unsigned *comp_mapping,
-                uint8_t *bundle_constants)
+                uint8_t *bundle_constants,
+                bool upper)
 {
         unsigned type_size = nir_alu_type_get_type_size(ins->src_types[src]) / 8;
         unsigned max_comp = 16 / type_size;
@@ -361,6 +362,15 @@ mir_adjust_constant(midgard_instruction *ins, unsigned src,
                                                type_size * 8);
         unsigned type_mask = (1 << type_size) - 1;
 
+        /* Upper only makes sense for 16-bit */
+        if (type_size != 16 && upper)
+                return false;
+
+        /* For 16-bit, we need to stay on either upper or lower halves to avoid
+         * disrupting the swizzle */
+        unsigned start = upper ? 8 : 0;
+        unsigned length = (type_size == 2) ? 8 : 16;
+
         for (unsigned comp = 0; comp < max_comp; comp++) {
                 if (!(comp_mask & (1 << comp)))
                         continue;
@@ -370,7 +380,7 @@ mir_adjust_constant(midgard_instruction *ins, unsigned src,
                 signed best_place = -1;
                 unsigned i, j;
 
-                for (i = 0; i < 16; i += type_size) {
+                for (i = start; i < (start + length); i += type_size) {
                         unsigned reuse_bytes = 0;
 
                         for (j = 0; j < type_size; j++) {
@@ -378,6 +388,8 @@ mir_adjust_constant(midgard_instruction *ins, unsigned src,
                                         continue;
                                 if (constantp[j] != bundle_constants[i + j])
                                         break;
+                                if ((i + j) > (start + length))
+                                        break;
 
                                 reuse_bytes++;
                         }
@@ -444,9 +456,18 @@ mir_adjust_constants(midgard_instruction *ins,
                 if (ins->src[src] != SSA_FIXED_REGISTER(REGISTER_CONSTANT))
                         continue;
 
-                if (!mir_adjust_constant(ins, src, &bundle_constant_mask,
-                                comp_mapping[src], bundle_constants))
-                        return false;
+                /* First, try lower half (or whole for !16) */
+                if (mir_adjust_constant(ins, src, &bundle_constant_mask,
+                                comp_mapping[src], bundle_constants, false))
+                        continue;
+
+                /* Next, try upper half */
+                if (mir_adjust_constant(ins, src, &bundle_constant_mask,
+                                comp_mapping[src], bundle_constants, true))
+                        continue;
+
+                /* Otherwise bail */
+                return false;
         }
 
         /* If non-destructive, we're done */