Module: Mesa Branch: master Commit: fa36a16c68489c7a8a7223c39fb0078f7d745bcb URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=fa36a16c68489c7a8a7223c39fb0078f7d745bcb
Author: Mike Blumenkrantz <michael.blumenkra...@gmail.com> Date: Thu Apr 8 10:52:55 2021 -0400 zink: make timeline semaphores per-screen I misread the spec, and it turns out timeline ids can't be reused across semaphores. This is obvious in retrospect, but what can be done? Reviewed-by: Erik Faye-Lund <erik.faye-l...@collabora.com> Tested-by: Erik Faye-Lund <erik.faye-l...@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10115> --- src/gallium/drivers/zink/zink_batch.c | 34 ++++++--------------------------- src/gallium/drivers/zink/zink_batch.h | 2 -- src/gallium/drivers/zink/zink_context.c | 6 +----- src/gallium/drivers/zink/zink_screen.c | 30 +++++++++++++++++++++++++++++ src/gallium/drivers/zink/zink_screen.h | 6 ++++++ 5 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index 45cac57fa39..e0a8decda94 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -154,8 +154,6 @@ create_batch_state(struct zink_context *ctx) struct zink_screen *screen = zink_screen(ctx->base.screen); struct zink_batch_state *bs = rzalloc(NULL, struct zink_batch_state); bs->have_timelines = ctx->have_timelines; - if (ctx->have_timelines) - bs->sem = ctx->batch.sem; VkCommandPoolCreateInfo cpci = {}; cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cpci.queueFamilyIndex = screen->gfx_queue; @@ -252,20 +250,6 @@ get_batch_state(struct zink_context *ctx, struct zink_batch *batch) return bs; } -static void -init_semaphore(struct zink_context *ctx, struct zink_batch *batch) -{ - struct zink_screen *screen = zink_screen(ctx->base.screen); - VkSemaphoreCreateInfo sci = {}; - VkSemaphoreTypeCreateInfo tci = {}; - sci.pNext = &tci; - sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - tci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO; - tci.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; - if (vkCreateSemaphore(screen->dev, &sci, NULL, &batch->sem) != VK_SUCCESS) - ctx->have_timelines = false; -} - void zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch) { @@ -273,18 +257,12 @@ zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch) bool fresh = !batch->state; if (ctx->have_timelines) { - bool do_reset = false; - if (screen->last_finished > ctx->curr_batch && ctx->curr_batch == 1) { - do_reset = true; - /* semaphore signal values can never decrease, - * so we need a new semaphore anytime we overflow - */ - if (ctx->batch.prev_sem) - vkDestroySemaphore(screen->dev, ctx->batch.prev_sem, NULL); - ctx->batch.prev_sem = ctx->batch.sem; + if (fresh || (screen->last_finished > ctx->curr_batch && ctx->curr_batch == 1)) { + if (!zink_screen_init_semaphore(screen)) { + debug_printf("timeline init failed, things are about to go dramatically wrong."); + ctx->have_timelines = false; + } } - if (fresh || do_reset) - init_semaphore(ctx, batch); } batch->state = get_batch_state(ctx, batch); @@ -351,7 +329,7 @@ submit_queue(void *data, int thread_index) tsi.signalSemaphoreValueCount = 1; tsi.pSignalSemaphoreValues = &batch_id; si.signalSemaphoreCount = 1; - si.pSignalSemaphores = &bs->sem; + si.pSignalSemaphores = &zink_screen(bs->ctx->base.screen)->sem; } struct wsi_memory_signal_submit_info mem_signal = { diff --git a/src/gallium/drivers/zink/zink_batch.h b/src/gallium/drivers/zink/zink_batch.h index d0d49676673..6c1c2fd2bee 100644 --- a/src/gallium/drivers/zink/zink_batch.h +++ b/src/gallium/drivers/zink/zink_batch.h @@ -89,8 +89,6 @@ struct zink_batch { uint32_t last_batch_id; VkQueue queue; //gfx+compute VkQueue thread_queue; //gfx+compute - VkSemaphore sem; - VkSemaphore prev_sem; struct util_queue flush_queue; //TODO: move to wsi bool has_work; diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 8f27200076c..68c997debeb 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -301,10 +301,6 @@ zink_context_destroy(struct pipe_context *pctx) pipe_resource_reference(&ctx->dummy_vertex_buffer, NULL); pipe_resource_reference(&ctx->dummy_xfb_buffer, NULL); - if (ctx->batch.sem) - vkDestroySemaphore(screen->dev, ctx->batch.sem, NULL); - if (ctx->batch.prev_sem) - vkDestroySemaphore(screen->dev, ctx->batch.prev_sem, NULL); if (ctx->tc) util_queue_destroy(&ctx->batch.flush_queue); @@ -2028,7 +2024,7 @@ timeline_wait(struct zink_context *ctx, uint32_t batch_id, uint64_t timeout) wi.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO; wi.semaphoreCount = 1; /* handle batch_id overflow */ - wi.pSemaphores = batch_id > ctx->curr_batch ? &ctx->batch.prev_sem : &ctx->batch.sem; + wi.pSemaphores = batch_id > ctx->curr_batch ? &screen->prev_sem : &screen->sem; uint64_t batch_id64 = batch_id; wi.pValues = &batch_id64; bool success = false; diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index db639d56af5..d0d55f5d396 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -956,6 +956,12 @@ zink_destroy_screen(struct pipe_screen *pscreen) simple_mtx_destroy(&screen->mem_cache_mtx); vkDestroyPipelineCache(screen->dev, screen->pipeline_cache, NULL); + if (screen->sem) + vkDestroySemaphore(screen->dev, screen->sem, NULL); + if (screen->prev_sem) + vkDestroySemaphore(screen->dev, screen->prev_sem, NULL); + + vkDestroyDevice(screen->dev, NULL); vkDestroyInstance(screen->instance, NULL); @@ -1325,6 +1331,30 @@ populate_format_props(struct zink_screen *screen) } } +bool +zink_screen_init_semaphore(struct zink_screen *screen) +{ + VkSemaphoreCreateInfo sci = {}; + VkSemaphoreTypeCreateInfo tci = {}; + VkSemaphore sem; + sci.pNext = &tci; + sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + tci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO; + tci.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; + + if (vkCreateSemaphore(screen->dev, &sci, NULL, &sem) == VK_SUCCESS) { + /* semaphore signal values can never decrease, + * so we need a new semaphore anytime we overflow + */ + if (screen->prev_sem) + vkDestroySemaphore(screen->dev, screen->prev_sem, NULL); + screen->sem = sem; + return true; + } + screen->info.have_KHR_timeline_semaphore = false; + return false; +} + static uint32_t zink_get_loader_version(void) { diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h index 2e667a9d312..4a2e88d968c 100644 --- a/src/gallium/drivers/zink/zink_screen.h +++ b/src/gallium/drivers/zink/zink_screen.h @@ -54,6 +54,8 @@ struct zink_screen { bool threaded; uint32_t curr_batch; //the current batch id uint32_t last_finished; //this is racy but ultimately doesn't matter + VkSemaphore sem; + VkSemaphore prev_sem; bool device_lost; struct sw_winsys *winsys; @@ -191,6 +193,10 @@ zink_screen_check_last_finished(struct zink_screen *screen, uint32_t batch_id) return screen->last_finished >= batch_id; } +bool +zink_screen_init_semaphore(struct zink_screen *screen); + + static inline struct zink_screen * zink_screen(struct pipe_screen *pipe) { _______________________________________________ mesa-commit mailing list mesa-commit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-commit