diff options
author | Eric Anholt <[email protected]> | 2014-12-02 16:23:40 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2014-12-05 10:43:14 -0800 |
commit | bd4057a5d74fd12222801c55ee98346af9c1095d (patch) | |
tree | ae385eb79977ee52da125022b1fe5656efdca32a /src/gallium/drivers/vc4/vc4_qpu.c | |
parent | dadc32ac8072cf78b405d1b54414e1f020b0de41 (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.
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_qpu.c')
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qpu.c | 53 |
1 files changed, 53 insertions, 0 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)); |