summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-12-02 16:23:40 -0800
committerEric Anholt <[email protected]>2014-12-05 10:43:14 -0800
commitbd4057a5d74fd12222801c55ee98346af9c1095d (patch)
treeae385eb79977ee52da125022b1fe5656efdca32a
parentdadc32ac8072cf78b405d1b54414e1f020b0de41 (diff)
vc4: Refuse to merge two ops that both access shared functions.
Avoids assertion failures in vc4_qpu_validate.c if we happen to find the right set of operations available.
-rw-r--r--src/gallium/drivers/vc4/vc4_qpu.c53
-rw-r--r--src/gallium/drivers/vc4/vc4_qpu.h1
-rw-r--r--src/gallium/drivers/vc4/vc4_qpu_validate.c37
3 files changed, 55 insertions, 36 deletions
diff --git a/src/gallium/drivers/vc4/vc4_qpu.c b/src/gallium/drivers/vc4/vc4_qpu.c
index 54c79e9d4f1..fc5d4b09dc2 100644
--- a/src/gallium/drivers/vc4/vc4_qpu.c
+++ b/src/gallium/drivers/vc4/vc4_qpu.c
@@ -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));
diff --git a/src/gallium/drivers/vc4/vc4_qpu.h b/src/gallium/drivers/vc4/vc4_qpu.h
index eb06d1a0720..e1307ebb57b 100644
--- a/src/gallium/drivers/vc4/vc4_qpu.h
+++ b/src/gallium/drivers/vc4/vc4_qpu.h
@@ -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
diff --git a/src/gallium/drivers/vc4/vc4_qpu_validate.c b/src/gallium/drivers/vc4/vc4_qpu_validate.c
index 16de82ae7b9..ffd1b4767b3 100644
--- a/src/gallium/drivers/vc4/vc4_qpu_validate.c
+++ b/src/gallium/drivers/vc4/vc4_qpu_validate.c
@@ -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);
}
}