Module: Mesa Branch: main Commit: b8252784cf01fddad4cb9885d1cdb0ef7da04973 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b8252784cf01fddad4cb9885d1cdb0ef7da04973
Author: Mike Blumenkrantz <[email protected]> Date: Thu Jan 12 14:21:20 2023 -0500 zink: add a binary semaphore cache after being waited upon, a binary semaphore can be reused, which saves tons of present-related ioctls when fps is high Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20681> --- src/gallium/drivers/zink/zink_batch.c | 9 +++++++-- src/gallium/drivers/zink/zink_screen.c | 15 +++++++++++++++ src/gallium/drivers/zink/zink_types.h | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index b7149d54acd..9b358cc5c52 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -198,8 +198,13 @@ unref_resources(struct zink_screen *screen, struct zink_batch_state *bs) /* this is typically where resource objects get destroyed */ zink_resource_object_reference(screen, &obj, NULL); } - while (util_dynarray_contains(&bs->unref_semaphores, VkSemaphore)) - VKSCR(DestroySemaphore)(screen->dev, util_dynarray_pop(&bs->unref_semaphores, VkSemaphore), NULL); + /* check the arrays first to avoid locking unnecessarily */ + if (!util_dynarray_contains(&bs->unref_semaphores, VkSemaphore)) + return; + simple_mtx_lock(&screen->semaphores_lock); + util_dynarray_append_dynarray(&screen->semaphores, &bs->unref_semaphores); + util_dynarray_clear(&bs->unref_semaphores); + simple_mtx_unlock(&screen->semaphores_lock); } /* utility for resetting a batch state; called on context destruction */ diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 2ab4e708f5c..0cdc0543a5d 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -1434,6 +1434,10 @@ zink_destroy_screen(struct pipe_screen *pscreen) if (screen->threaded) util_queue_destroy(&screen->flush_queue); + simple_mtx_destroy(&screen->semaphores_lock); + while (util_dynarray_contains(&screen->semaphores, VkSemaphore)) + VKSCR(DestroySemaphore)(screen->dev, util_dynarray_pop(&screen->semaphores, VkSemaphore), NULL); + simple_mtx_destroy(&screen->queue_lock); VKSCR(DestroyDevice)(screen->dev, NULL); VKSCR(DestroyInstance)(screen->instance, NULL); @@ -2520,6 +2524,14 @@ zink_create_semaphore(struct zink_screen *screen) 0 }; VkSemaphore sem = VK_NULL_HANDLE; + if (util_dynarray_contains(&screen->semaphores, VkSemaphore)) { + simple_mtx_lock(&screen->semaphores_lock); + if (util_dynarray_contains(&screen->semaphores, VkSemaphore)) + sem = util_dynarray_pop(&screen->semaphores, VkSemaphore); + simple_mtx_unlock(&screen->semaphores_lock); + } + if (sem) + return sem; VkResult ret = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &sem); return ret == VK_SUCCESS ? sem : VK_NULL_HANDLE; } @@ -2830,6 +2842,9 @@ zink_internal_create_screen(const struct pipe_screen_config *config) util_idalloc_mt_init_tc(&screen->buffer_ids); + simple_mtx_init(&screen->semaphores_lock, mtx_plain); + util_dynarray_init(&screen->semaphores, screen); + util_vertex_state_cache_init(&screen->vertex_state_cache, zink_create_vertex_state, zink_vertex_state_destroy); screen->base.create_vertex_state = zink_cache_create_vertex_state; diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index b7a7dcf7d29..b470912babd 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1226,6 +1226,9 @@ struct zink_screen { struct util_queue flush_queue; struct zink_context *copy_context; + simple_mtx_t semaphores_lock; + struct util_dynarray semaphores; + unsigned buffer_rebind_counter; unsigned image_rebind_counter; unsigned robust_ctx_count;
