freedreno/a6xx: Workaround early preamble HW bug

Port of the previous commit.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27462>
This commit is contained in:
Connor Abbott
2024-01-24 09:16:40 -05:00
committed by Marge Bot
parent 472ce31e56
commit d35c1e5051

View File

@@ -959,6 +959,25 @@ fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring)
OUT_PKT4(ring, REG_A6XX_SP_PS_TP_BORDER_COLOR_BASE_ADDR, 2);
OUT_RELOC(ring, bcolor_mem, 0, 0, 0);
/* There is an optimization to skip executing draw states for draws with no
* instances. Instead of simply skipping the draw, internally the firmware
* sets a bit in PC_DRAW_INITIATOR that seemingly skips the draw. However
* there is a hardware bug where this bit does not always cause the FS
* early preamble to be skipped. Because the draw states were skipped,
* SP_FS_CTRL_REG0, SP_FS_OBJ_START and so on are never updated and a
* random FS preamble from the last draw is executed. If the last visible
* draw is from the same submit, it shouldn't be a problem because we just
* re-execute the same preamble and preambles don't have side effects, but
* if it's from another process then we could execute a garbage preamble
* leading to hangs and faults. To make sure this doesn't happen, we reset
* SP_FS_CTRL_REG0 here, making sure that the EARLYPREAMBLE bit isn't set
* so any leftover early preamble doesn't get executed. Other stages don't
* seem to be affected.
*/
if (screen->info->a6xx.has_early_preamble) {
WRITE(REG_A6XX_SP_FS_CTRL_REG0, 0);
}
if (!batch->nondraw) {
trace_end_state_restore(&batch->trace, ring);
}