summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGert Wollny <gert.wollny@collabora.com>2024-04-08 22:28:52 +0200
committerEric Engestrom <eric@engestrom.ch>2024-05-07 16:54:10 +0200
commitc6aed9753641f77506b7e06747eba9a8cf936fa6 (patch)
tree6af008a33e7432bce253b10fe038e7527ee34ffc
parent90c4fa8a8f60c3e3064784b1976ced2877b967e1 (diff)
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 <gert.wollny@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28127> (cherry picked from commit 811ed6286590bed340a73d3115a283a027d9091b)
-rw-r--r--.pick_status.json2
-rw-r--r--src/gallium/drivers/zink/zink_kopper.c17
2 files changed, 16 insertions, 3 deletions
diff --git a/.pick_status.json b/.pick_status.json
index 482d2ce69d6..def2e923dde 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 b4f3e71a4bd..f936d47c61f 100644
--- a/src/gallium/drivers/zink/zink_kopper.c
+++ b/src/gallium/drivers/zink/zink_kopper.c
@@ -884,8 +884,21 @@ zink_kopper_acquire_readback(struct zink_context *ctx, struct zink_resource *res
kopper_ensure_readback(screen, 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);