From: Eric Anholt Date: Wed, 3 Dec 2014 00:23:40 +0000 (-0800) Subject: vc4: Refuse to merge two ops that both access shared functions. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bd4057a5d74fd12222801c55ee98346af9c1095d;p=mesa.git 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. --- 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); } }