From 80af43b9be6ccea5dc13d113260d8e76cee50f65 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Mon, 8 Apr 2024 22:28:52 +0200 Subject: [PATCH] zink/kopper: Wait for last QueuePresentKHR to finish before acquiring for readback When a job is submitted to the flush_queue the resource dt_idx is reset, and if a readback is requested then we have to make sure that the corresponding kopper_preset has finished before we can acquire the image for readback, so wait for the according fence in this case. This fixes the validation error UNASSIGNED-Threading-MultipleThreads-Write triggered by piglit "read-front" lavapipe. Fixes: 8ade5588e39d736bdeab9bdd8ffa7cbfb6a5191e zink: add kopper api Signed-off-by: Gert Wollny Part-of: (cherry picked from commit 811ed6286590bed340a73d3115a283a027d9091b) --- .pick_status.json | 2 +- src/gallium/drivers/zink/zink_kopper.c | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 9aa5c42d487..0487bce28d7 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -124,7 +124,7 @@ "description": "zink/kopper: Wait for last QueuePresentKHR to finish before acquiring for readback", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "8ade5588e39d736bdeab9bdd8ffa7cbfb6a5191e", "notes": null diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c index f919ff98e83..afa7bb48907 100644 --- a/src/gallium/drivers/zink/zink_kopper.c +++ b/src/gallium/drivers/zink/zink_kopper.c @@ -944,8 +944,21 @@ zink_kopper_acquire_readback(struct zink_context *ctx, struct zink_resource *res } while (res->obj->dt_idx != last_dt_idx) { cdt->age_locked = true; - if (res->obj->dt_idx != UINT32_MAX && !zink_kopper_present_readback(ctx, res)) - break; + if (res->obj->dt_idx != UINT32_MAX) { + if (!zink_kopper_present_readback(ctx, res)) + break; + } else if (util_queue_is_initialized(&screen->flush_queue)) { + /* AcquireNextImageKHR and QueuePresentKHR both access the swapchain, and + * if res->obj->dt_idx == UINT32_MAX then zink_kopper_present_readback is + * not called and we don't wait for the cdt->swapchain->present_fence. + * Still, a kopper_present might have been called in another thread, like + * e.g. with spec@!opengl 1.1@read-front, so we have to wait until the + * last call to QueuePresentKHR is finished to avoid an + * UNASSIGNED-Threading-MultipleThreads-Write + * validation error that indicats a race condition when accessing the swapchain. + */ + util_queue_fence_wait(&cdt->swapchain->present_fence); + } cdt->age_locked = true; do { ret = kopper_acquire(screen, res, 0);