pan/va: fix FAU validation

Validation was checking that if an instruction was accessing FAU RAM,
only one 64-bit slot was accessed, and if it was accessing a FAU special
value, only one was accessed, however it was not checking if both  RAM
and special were used, which is only allowed in messaging instructions
except ATEST and BLEND.

Fixes Piglit:
spec/ati_fragment_shader/ati_fragment_shader-render-ops/mov c0.r

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Fixes: fd1906afea ("pan/va: Add FAU validation")
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33608>
(cherry picked from commit e504825813)
This commit is contained in:
Iago Toral Quiroga 2025-01-21 18:35:24 +01:00 committed by Eric Engestrom
parent 7b38cf8b5e
commit 5e76850ce3
2 changed files with 42 additions and 18 deletions

View file

@ -904,7 +904,7 @@
"description": "pan/va: fix FAU validation",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "fd1906afea59073780939810e0e46094264677d3",
"notes": null

View file

@ -60,18 +60,16 @@ fau_state_buffer(struct fau_state *fau, bi_index idx)
return false;
}
/* Instructions executed in the execution engine may only encode one FAU index.
* Instructions executed by the message unit may encode two FAU indices,
* except for ATEST and BLEND which may sometimes run in the execution engine.
*/
static bool
fau_state_uniform(struct fau_state *fau, bi_index idx)
can_use_two_fau_indices(enum bi_opcode op)
{
/* Each slot is 64-bits. The low/high half is encoded as the offset of the
* bi_index, which we want to ignore.
*/
unsigned slot = (idx.value & 63);
if (fau->uniform_slot < 0)
fau->uniform_slot = slot;
return fau->uniform_slot == slot;
return bi_opcode_props[op].message != BIFROST_MESSAGE_NONE &&
op != BI_OPCODE_ATEST &&
op != BI_OPCODE_BLEND;
}
static bool
@ -81,7 +79,32 @@ fau_is_special(enum bir_fau fau)
}
static bool
fau_state_special(struct fau_state *fau, bi_index idx)
fau_state_uniform(struct fau_state *fau, bi_index idx, enum bi_opcode op)
{
/* Each slot is 64-bits. The low/high half is encoded as the offset of the
* bi_index, which we want to ignore.
*/
unsigned slot = (idx.value & 63);
if (fau->uniform_slot < 0)
fau->uniform_slot = slot;
if (fau->uniform_slot != slot)
return false;
if (!can_use_two_fau_indices(op)) {
for (unsigned i = 0; i < ARRAY_SIZE(fau->buffer); ++i) {
bi_index buf = fau->buffer[i];
if (!bi_is_null(buf) && fau_is_special(buf.value))
return false;
}
}
return true;
}
static bool
fau_state_special(struct fau_state *fau, bi_index idx, enum bi_opcode op)
{
for (unsigned i = 0; i < ARRAY_SIZE(fau->buffer); ++i) {
bi_index buf = fau->buffer[i];
@ -91,11 +114,12 @@ fau_state_special(struct fau_state *fau, bi_index idx)
return false;
}
return true;
return fau->uniform_slot == -1 || can_use_two_fau_indices(op);
}
static bool
valid_src(struct fau_state *fau, unsigned fau_page, bi_index src)
valid_src(struct fau_state *fau, unsigned fau_page, bi_index src,
enum bi_opcode op)
{
if (src.type != BI_INDEX_FAU)
return true;
@ -104,9 +128,9 @@ valid_src(struct fau_state *fau, unsigned fau_page, bi_index src)
valid &= fau_state_buffer(fau, src);
if (src.value & BIR_FAU_UNIFORM)
valid &= fau_state_uniform(fau, src);
valid &= fau_state_uniform(fau, src, op);
else if (fau_is_special(src.value))
valid &= fau_state_special(fau, src);
valid &= fau_state_special(fau, src, op);
return valid;
}
@ -119,7 +143,7 @@ va_validate_fau(bi_instr *I)
unsigned fau_page = va_select_fau_page(I);
bi_foreach_src(I, s) {
valid &= valid_src(&fau, fau_page, I->src[s]);
valid &= valid_src(&fau, fau_page, I->src[s], I->op);
}
return valid;
@ -135,7 +159,7 @@ va_repair_fau(bi_builder *b, bi_instr *I)
struct fau_state push = fau;
bi_index src = I->src[s];
if (!valid_src(&fau, fau_page, src)) {
if (!valid_src(&fau, fau_page, src, I->op)) {
bi_replace_src(I, s, bi_mov_i32(b, bi_strip_index(src)));
/* Rollback update. Since the replacement move doesn't affect FAU