vc4: Refuse to merge two ops that both access shared functions.
authorEric Anholt <eric@anholt.net>
Wed, 3 Dec 2014 00:23:40 +0000 (16:23 -0800)
committerEric Anholt <eric@anholt.net>
Fri, 5 Dec 2014 18:43:14 +0000 (10:43 -0800)
Avoids assertion failures in vc4_qpu_validate.c if we happen to find the
right set of operations available.

src/gallium/drivers/vc4/vc4_qpu.c
src/gallium/drivers/vc4/vc4_qpu.h
src/gallium/drivers/vc4/vc4_qpu_validate.c

index 54c79e9d4f1493ddd62060d3d501a21d91a286d7..fc5d4b09dc23c2e563709307765bced43bcf3688 100644 (file)
@@ -209,6 +209,56 @@ merge_fields(uint64_t *merge,
         return true;
 }
 
+int
+qpu_num_sf_accesses(uint64_t inst)
+{
+        int accesses = 0;
+        static const uint32_t specials[] = {
+                QPU_W_TLB_COLOR_MS,
+                QPU_W_TLB_COLOR_ALL,
+                QPU_W_TLB_Z,
+                QPU_W_TMU0_S,
+                QPU_W_TMU0_T,
+                QPU_W_TMU0_R,
+                QPU_W_TMU0_B,
+                QPU_W_TMU1_S,
+                QPU_W_TMU1_T,
+                QPU_W_TMU1_R,
+                QPU_W_TMU1_B,
+                QPU_W_SFU_RECIP,
+                QPU_W_SFU_RECIPSQRT,
+                QPU_W_SFU_EXP,
+                QPU_W_SFU_LOG,
+        };
+        uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD);
+        uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL);
+        uint32_t raddr_a = QPU_GET_FIELD(inst, QPU_RADDR_A);
+        uint32_t raddr_b = QPU_GET_FIELD(inst, QPU_RADDR_B);
+
+        for (int j = 0; j < ARRAY_SIZE(specials); j++) {
+                if (waddr_add == specials[j])
+                        accesses++;
+                if (waddr_mul == specials[j])
+                        accesses++;
+        }
+
+        if (raddr_a == QPU_R_MUTEX_ACQUIRE)
+                accesses++;
+        if (raddr_b == QPU_R_MUTEX_ACQUIRE)
+                accesses++;
+
+        /* XXX: semaphore, combined color read/write? */
+        switch (QPU_GET_FIELD(inst, QPU_SIG)) {
+        case QPU_SIG_COLOR_LOAD:
+        case QPU_SIG_COLOR_LOAD_END:
+        case QPU_SIG_LOAD_TMU0:
+        case QPU_SIG_LOAD_TMU1:
+                accesses++;
+        }
+
+        return accesses;
+}
+
 uint64_t
 qpu_merge_inst(uint64_t a, uint64_t b)
 {
@@ -223,6 +273,9 @@ qpu_merge_inst(uint64_t a, uint64_t b)
             QPU_GET_FIELD(b, QPU_OP_MUL) != QPU_M_NOP)
                 return 0;
 
+        if (qpu_num_sf_accesses(a) && qpu_num_sf_accesses(b))
+                return 0;
+
         ok = ok && merge_fields(&merge, a, b, QPU_SIG_MASK,
                                 QPU_SET_FIELD(QPU_SIG_NONE, QPU_SIG));
 
index eb06d1a07205eaa0905275cfe9a9f8787f68a061..e1307ebb57b00f30c5775ac65695354f0e4054f0 100644 (file)
@@ -137,6 +137,7 @@ uint64_t qpu_set_cond_mul(uint64_t inst, uint32_t cond);
 
 bool qpu_waddr_is_tlb(uint32_t waddr);
 bool qpu_inst_is_tlb(uint64_t inst);
+int qpu_num_sf_accesses(uint64_t inst);
 void qpu_serialize_one_inst(struct vc4_compile *c, uint64_t inst);
 
 static inline uint64_t
index 16de82ae7b9cd80f4bc1a3feafb1f294ee73ed18..ffd1b4767b3a79ef7d470196eac3bd996474c38e 100644 (file)
@@ -255,42 +255,7 @@ vc4_qpu_validate(uint64_t *insts, uint32_t num_inst)
          */
         for (int i = 0; i < num_inst - 1; i++) {
                 uint64_t inst = insts[i];
-                int accesses = 0;
-                static const uint32_t specials[] = {
-                        QPU_W_TLB_COLOR_MS,
-                        QPU_W_TLB_COLOR_ALL,
-                        QPU_W_TLB_Z,
-                        QPU_W_TMU0_S,
-                        QPU_W_TMU0_T,
-                        QPU_W_TMU0_R,
-                        QPU_W_TMU0_B,
-                        QPU_W_TMU1_S,
-                        QPU_W_TMU1_T,
-                        QPU_W_TMU1_R,
-                        QPU_W_TMU1_B,
-                        QPU_W_SFU_RECIP,
-                        QPU_W_SFU_RECIPSQRT,
-                        QPU_W_SFU_EXP,
-                        QPU_W_SFU_LOG,
-                };
-
-                for (int j = 0; j < ARRAY_SIZE(specials); j++) {
-                        if (writes_reg(inst, specials[j]))
-                                accesses++;
-                }
-
-                if (reads_reg(inst, QPU_R_MUTEX_ACQUIRE))
-                        accesses++;
-
-                /* XXX: semaphore, combined color read/write? */
-                switch (QPU_GET_FIELD(inst, QPU_SIG)) {
-                case QPU_SIG_COLOR_LOAD:
-                case QPU_SIG_COLOR_LOAD_END:
-                case QPU_SIG_LOAD_TMU0:
-                case QPU_SIG_LOAD_TMU1:
-                        accesses++;
-                }
 
-                assert(accesses <= 1);
+                assert(qpu_num_sf_accesses(inst) <= 1);
         }
 }