pan/bi: Make sure we never branch to an non-existing clause

Branch instructions can point to the last shader block, which might be
empty. In this case, the branch points to a clause that doesn't exists,
leading to INVALID_ENC faults when the GPU tries to jump to this clause.

Check if the block is a terminal block before updating the branch
offset: jumping/branching to NULL is equivalent to a shader termination,
so the default value of 0 works just fine for terminal branches.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8848>
This commit is contained in:
Boris Brezillon 2021-01-25 12:08:15 +01:00 committed by Marge Bot
parent dbce99a809
commit 855e29cd78
1 changed files with 16 additions and 11 deletions

View File

@ -561,23 +561,28 @@ bi_pack_constants(bi_context *ctx, bi_clause *clause,
};
/* Compute branch offset instead of a dummy 0 */
bool terminal_branch = true;
if (branches) {
bi_instr *br = clause->tuples[clause->tuple_count - 1].add;
assert(br && br->branch_target);
/* Put it in the high place */
int32_t qwords = bi_block_offset(ctx, clause, br->branch_target);
int32_t bytes = qwords * 16;
if (!bi_is_terminal_block(ctx, br->branch_target)) {
/* Put it in the high place */
int32_t qwords = bi_block_offset(ctx, clause, br->branch_target);
int32_t bytes = qwords * 16;
/* Copy so we get proper sign behaviour */
uint32_t raw = 0;
memcpy(&raw, &bytes, sizeof(raw));
/* Copy so we get proper sign behaviour */
uint32_t raw = 0;
memcpy(&raw, &bytes, sizeof(raw));
/* Clear off top bits for the magic bits */
raw &= ~0xF0000000;
/* Clear off top bits for the magic bits */
raw &= ~0xF0000000;
terminal_branch = false;
/* Put in top 32-bits */
clause->constants[index + 0] = ((uint64_t) raw) << 32ull;
/* Put in top 32-bits */
clause->constants[index + 0] = ((uint64_t) raw) << 32ull;
}
}
uint64_t hi = clause->constants[index + 0] >> 60ull;
@ -589,7 +594,7 @@ bi_pack_constants(bi_context *ctx, bi_clause *clause,
.imm_2 = ((hi < 8) ? (hi << 60ull) : 0) >> 4,
};
if (branches) {
if (branches && !terminal_branch) {
/* Branch offsets are less than 60-bits so this should work at
* least for now */
quad.imm_1 |= (4ull << 60ull) >> 4;