mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
panfrost: ensure sample_mask is written before color
The ATEST instruction needs sample_mask as an input, but if the shader writes to color before sample_mask we could emit them in the wrong order. Fix this in pan_nir_lower_zs_store by deferring the color write until after the sample_mask write. Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Benjamin Lee <benjamin.lee@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32879>
This commit is contained in:
parent
115eb1d5f3
commit
03a1a5009f
1 changed files with 29 additions and 2 deletions
|
|
@ -108,6 +108,8 @@ pan_nir_lower_zs_store(nir_shader *nir)
|
|||
|
||||
nir_foreach_function_impl(impl, nir) {
|
||||
nir_intrinsic_instr *stores[3] = {NULL};
|
||||
nir_intrinsic_instr *last_mask_store = NULL;
|
||||
nir_block *mask_block = NULL;
|
||||
unsigned writeout = 0;
|
||||
|
||||
nir_foreach_block(block, impl) {
|
||||
|
|
@ -130,14 +132,17 @@ pan_nir_lower_zs_store(nir_shader *nir)
|
|||
assert(!stores[2]); /* there should be only 1 source for dual blending */
|
||||
stores[2] = intr;
|
||||
writeout |= PAN_WRITEOUT_2;
|
||||
} else if (sem.location == FRAG_RESULT_SAMPLE_MASK) {
|
||||
last_mask_store = intr;
|
||||
mask_block = intr->instr.block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!writeout)
|
||||
if (!writeout && !last_mask_store)
|
||||
continue;
|
||||
|
||||
nir_block *common_block = NULL;
|
||||
nir_block *common_block = mask_block;
|
||||
|
||||
/* Ensure all stores are in the same block */
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(stores); ++i) {
|
||||
|
|
@ -152,6 +157,28 @@ pan_nir_lower_zs_store(nir_shader *nir)
|
|||
common_block = block;
|
||||
}
|
||||
|
||||
/* move data stores in the common block to after the last mask store */
|
||||
if (last_mask_store) {
|
||||
nir_cursor insert_point = nir_after_instr(&last_mask_store->instr);
|
||||
nir_foreach_instr_safe(instr, mask_block) {
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
continue;
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
|
||||
/* stop when we've reached the last store to mask */
|
||||
if (intr == last_mask_store)
|
||||
break;
|
||||
if (intr->intrinsic != nir_intrinsic_store_output)
|
||||
continue;
|
||||
nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
|
||||
if (sem.location >= FRAG_RESULT_DATA0 &&
|
||||
sem.location <= FRAG_RESULT_DATA7) {
|
||||
nir_instr_move(insert_point, instr);
|
||||
insert_point = nir_after_instr(instr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool replaced = false;
|
||||
|
||||
nir_foreach_block(block, impl) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue