tu: Restore PC_TESS_BASE after BIN preemption save/restore

Preamble save/restore for BINs doesn't handle PC_TESS_BASE, so we
assume that PC_TESS_BASE is invalid after any GMEM pass.

In addition on A7XX PC_TESS_BASE doesn't require WFI.

Fixes misrendering on A750 in "Industria", "Resident Evil 2" and
any other game that uses tesselation.

Cc: mesa-stable

Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
(cherry picked from commit 12416c9fca)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39462>
This commit is contained in:
Danylo Piliaiev 2026-01-09 15:16:35 +01:00 committed by Dylan Baker
parent 92544a389b
commit df3d834bd3
2 changed files with 13 additions and 7 deletions

View file

@ -1334,7 +1334,7 @@
"description": "tu: Restore PC_TESS_BASE after BIN preemption save/restore",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View file

@ -152,10 +152,10 @@ tu_emit_event_write(struct tu_cmd_buffer *cmd,
}
TU_GENX(tu_emit_event_write);
/* Emits the tessfactor address to the top-level CS if it hasn't been already.
* Updating this register requires a WFI if outstanding drawing is using it, but
* tu6_init_hardware() will have WFIed before we started and no other draws
* could be using the tessfactor address yet since we only emit one per cmdbuf.
/* Emits the tessfactor address to the top-level CS if it may be invalid.
* On A6XX updating PC_TESS_BASE requires a WFI if outstanding drawing is
* using it, but tu6_init_hardware() will have WFIed before we started and
* no other draws could be using PC_TESS_BASE with different address.
*/
template <chip CHIP>
static void
@ -163,11 +163,12 @@ tu6_lazy_emit_tessfactor_addr(struct tu_cmd_buffer *cmd)
{
if (cmd->state.tessfactor_addr_set)
return;
cmd->state.tessfactor_addr_set = true;
tu_cs_emit_regs(&cmd->cs, PC_TESS_BASE(CHIP, .qword = cmd->device->tess_bo->iova));
/* Updating PC_TESS_BASE could race with the next draw which uses it. */
cmd->state.cache.flush_bits |= TU_CMD_FLAG_WAIT_FOR_IDLE;
cmd->state.tessfactor_addr_set = true;
if (CHIP == A6XX)
cmd->state.cache.flush_bits |= TU_CMD_FLAG_WAIT_FOR_IDLE;
}
static void
@ -3153,6 +3154,11 @@ tu_cmd_render_tiles(struct tu_cmd_buffer *cmd,
const struct tu_vsc_config *vsc = tu_vsc_config(cmd, tiling);
const struct tu_image_view *fdm = NULL;
/* Preamble save/restore for BINs doesn't handle PC_TESS_BASE, so we
* assume that PC_TESS_BASE is invalid after any GMEM pass.
*/
cmd->state.tessfactor_addr_set = false;
VkResult result = tu_allocate_transient_attachments(cmd, false);
if (result != VK_SUCCESS) {
vk_command_buffer_set_error(&cmd->vk, result);