vc4: Don't let pairing happen with badly mismatched unpack flags.
authorEric Anholt <eric@anholt.net>
Sun, 11 Jan 2015 06:31:59 +0000 (19:31 +1300)
committerEric Anholt <eric@anholt.net>
Thu, 15 Jan 2015 09:19:25 +0000 (22:19 +1300)
No difference on shader-db, but prevents definite regressions in the
blending changes.

src/gallium/drivers/vc4/vc4_qpu.c

index 6bdb395..434e664 100644 (file)
@@ -403,6 +403,15 @@ writes_a_file(uint64_t inst)
                 return QPU_GET_FIELD(inst, QPU_WADDR_MUL) < 32;
 }
 
+static bool
+reads_r4(uint64_t inst)
+{
+        return (QPU_GET_FIELD(inst, QPU_ADD_A) == QPU_MUX_R4 ||
+                QPU_GET_FIELD(inst, QPU_ADD_B) == QPU_MUX_R4 ||
+                QPU_GET_FIELD(inst, QPU_MUL_A) == QPU_MUX_R4 ||
+                QPU_GET_FIELD(inst, QPU_MUL_B) == QPU_MUX_R4);
+}
+
 uint64_t
 qpu_merge_inst(uint64_t a, uint64_t b)
 {
@@ -509,6 +518,36 @@ qpu_merge_inst(uint64_t a, uint64_t b)
                         return 0;
         }
 
+        /* unpacking: Make sure that non-NOP unpacks agree, then deal with
+         * special-case failing of adding a non-NOP unpack to something with a
+         * NOP unpack.
+         */
+        if (!merge_fields(&merge, a, b, QPU_UNPACK_MASK, 0))
+                return 0;
+        bool new_a_unpack = (QPU_GET_FIELD(a, QPU_UNPACK) !=
+                             QPU_GET_FIELD(merge, QPU_UNPACK));
+        bool new_b_unpack = (QPU_GET_FIELD(b, QPU_UNPACK) !=
+                             QPU_GET_FIELD(merge, QPU_UNPACK));
+        if (!(merge & QPU_PM)) {
+                /* Make sure we're not going to be putting a new
+                 * a-file packing on either half.
+                 */
+                if (new_a_unpack && QPU_GET_FIELD(a, QPU_RADDR_A) != QPU_R_NOP)
+                        return 0;
+
+                if (new_b_unpack && QPU_GET_FIELD(b, QPU_RADDR_A) != QPU_R_NOP)
+                        return 0;
+        } else {
+                /* Make sure we're not going to be putting new r4 unpack on
+                 * either half.
+                 */
+                if (new_a_unpack && reads_r4(a))
+                        return 0;
+
+                if (new_b_unpack && reads_r4(b))
+                        return 0;
+        }
+
         if (ok)
                 return merge;
         else