Module: Mesa Branch: staging/22.2 Commit: ac210811e859a392f93dce77e8a20cc9acff620f URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=ac210811e859a392f93dce77e8a20cc9acff620f
Author: Yiwei Zhang <[email protected]> Date: Wed Sep 7 00:06:37 2022 +0000 zink: fix in-fence lifecycle For in-fence handling, dri2 has this below sequence in a row: 1. create_fence_fd: import external fence fd 2. fence_server_sync: import the pipe fence into the driver ctx 3. fence_reference: deref the created pipe fence Before this change, zink pushed the wrapped external semaphore to the wait semaphores of the next batch but the followed fence_reference will destroy the imported semaphore immediately. Instead of extending the lifecycle of the pipe fence throughout the batch state, we can simply transfer the semaphore ownership to the batch and destroy it upon batch reset. Fixes: 32597e116d7 ("zink: implement GL semaphores") Signed-off-by: Yiwei Zhang <[email protected]> Reviewed-By: Mike Blumenkrantz <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18453> (cherry picked from commit 6d1e214238276e86e979cebef7eb4c8982a357ea) --- .pick_status.json | 2 +- src/gallium/drivers/zink/zink_batch.c | 3 ++- src/gallium/drivers/zink/zink_fence.c | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index e2f77718b4a..1523b201c66 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -3028,7 +3028,7 @@ "description": "zink: fix in-fence lifecycle", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "32597e116d7317127ef8a7caf8dc75b50f48b8e1" }, diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index 8a459f219a6..bcfc2db2226 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -91,7 +91,8 @@ zink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs) bs->resource_size = 0; bs->signal_semaphore = VK_NULL_HANDLE; - util_dynarray_clear(&bs->wait_semaphores); + while (util_dynarray_contains(&bs->wait_semaphores, VkSemaphore)) + VKSCR(DestroySemaphore)(screen->dev, util_dynarray_pop(&bs->wait_semaphores, VkSemaphore), NULL); util_dynarray_clear(&bs->wait_semaphore_stages); bs->present = VK_NULL_HANDLE; diff --git a/src/gallium/drivers/zink/zink_fence.c b/src/gallium/drivers/zink/zink_fence.c index 425136f6e10..28dfded9136 100644 --- a/src/gallium/drivers/zink/zink_fence.c +++ b/src/gallium/drivers/zink/zink_fence.c @@ -37,7 +37,8 @@ destroy_fence(struct zink_screen *screen, struct zink_tc_fence *mfence) { mfence->fence = NULL; tc_unflushed_batch_token_reference(&mfence->tc_token, NULL); - VKSCR(DestroySemaphore)(screen->dev, mfence->sem, NULL); + if (mfence->sem) + VKSCR(DestroySemaphore)(screen->dev, mfence->sem, NULL); FREE(mfence); } @@ -221,6 +222,9 @@ zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfen VkPipelineStageFlags flag = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; util_dynarray_append(&ctx->batch.state->wait_semaphores, VkSemaphore, mfence->sem); util_dynarray_append(&ctx->batch.state->wait_semaphore_stages, VkPipelineStageFlags, flag); + + /* transfer the external wait sempahore ownership to the next submit */ + mfence->sem = VK_NULL_HANDLE; } void
