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.
This commit is contained in:
Eric Anholt 2014-12-02 16:23:40 -08:00
parent dadc32ac80
commit bd4057a5d7
3 changed files with 55 additions and 36 deletions

View 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));

View 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

View 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);
}
}