diff options
author | Mike Blumenkrantz <michael.blumenkrantz@gmail.com> | 2021-02-12 14:15:27 -0500 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-04-01 13:25:51 +0000 |
commit | 9a13add12e1cb3e71d7fc851a49ca3305c33c9f1 (patch) | |
tree | bc1b08617610b7a0ff6cf3c7dd31015eb3453bb2 | |
parent | 2d38fb7e612713b5ca485a27fcd5a18e84d7deac (diff) |
zink: hook up timeline semaphore signalling during batch submission
just basic parts, no waiting on semaphores yet
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9963>
-rw-r--r-- | src/gallium/drivers/zink/zink_batch.c | 43 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_batch.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_context.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_context.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_device_info.py | 1 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_screen.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_screen.h | 2 |
7 files changed, 62 insertions, 1 deletions
diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index 6e01b9162b3..13463c24cb2 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -154,6 +154,9 @@ 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; @@ -244,12 +247,41 @@ 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) { struct zink_screen *screen = zink_screen(ctx->base.screen); 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 || do_reset) + init_semaphore(ctx, batch); + } + batch->state = get_batch_state(ctx, batch); assert(batch->state); @@ -298,6 +330,7 @@ submit_queue(void *data, int thread_index) { struct zink_batch_state *bs = data; VkSubmitInfo si = {}; + uint64_t batch_id = bs->fence.batch_id; si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; si.waitSemaphoreCount = 0; si.pWaitSemaphores = NULL; @@ -307,6 +340,16 @@ submit_queue(void *data, int thread_index) si.commandBufferCount = 1; si.pCommandBuffers = &bs->cmdbuf; + VkTimelineSemaphoreSubmitInfo tsi = {}; + if (bs->have_timelines) { + tsi.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO; + si.pNext = &tsi; + tsi.signalSemaphoreValueCount = 1; + tsi.pSignalSemaphoreValues = &batch_id; + si.signalSemaphoreCount = 1; + si.pSignalSemaphores = &bs->sem; + } + struct wsi_memory_signal_submit_info mem_signal = { .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA, .pNext = si.pNext, diff --git a/src/gallium/drivers/zink/zink_batch.h b/src/gallium/drivers/zink/zink_batch.h index fdc67016f8c..d0d49676673 100644 --- a/src/gallium/drivers/zink/zink_batch.h +++ b/src/gallium/drivers/zink/zink_batch.h @@ -55,7 +55,9 @@ struct zink_batch_state { struct zink_context *ctx; VkCommandPool cmdpool; VkCommandBuffer cmdbuf; + VkQueue queue; //duplicated from batch for threading + VkSemaphore sem; struct util_queue_fence flush_completed; @@ -78,6 +80,7 @@ struct zink_batch_state { VkDeviceSize resource_size; bool is_device_lost; + bool have_timelines; }; struct zink_batch { @@ -86,6 +89,8 @@ 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 ba78cf37cb3..cb706a0aac0 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -301,6 +301,11 @@ 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); @@ -2692,11 +2697,12 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) else ctx->batch.thread_queue = ctx->batch.queue; + ctx->have_timelines = screen->info.have_KHR_timeline_semaphore; + simple_mtx_init(&ctx->batch_mtx, mtx_plain); incr_curr_batch(ctx); zink_start_batch(ctx, &ctx->batch); if (!ctx->batch.state) goto fail; - simple_mtx_init(&ctx->batch_mtx, mtx_plain); ctx->program_cache = _mesa_hash_table_create(NULL, hash_gfx_program, diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 1abbb900be4..fd78a85ab45 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -222,6 +222,7 @@ struct zink_context { bool dirty_so_targets; bool xfb_barrier; bool first_frame_done; + bool have_timelines; }; static inline struct zink_context * diff --git a/src/gallium/drivers/zink/zink_device_info.py b/src/gallium/drivers/zink/zink_device_info.py index a0f69f6c69b..97e8b3f2d44 100644 --- a/src/gallium/drivers/zink/zink_device_info.py +++ b/src/gallium/drivers/zink/zink_device_info.py @@ -123,6 +123,7 @@ EXTENSIONS = [ properties=True, features=True, guard=True), + Extension("VK_KHR_timeline_semaphore"), Extension("VK_EXT_4444_formats", alias="format_4444", features=True), diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 000dd0e2d61..79ceaaeea53 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -1174,6 +1174,9 @@ load_device_extensions(struct zink_screen *screen) GET_PROC_ADDR(CmdBindVertexBuffers2EXT); } + if (screen->info.have_KHR_timeline_semaphore) + GET_PROC_ADDR_KHR(WaitSemaphores); + screen->have_triangle_fans = true; #if defined(VK_EXTX_PORTABILITY_SUBSET_EXTENSION_NAME) if (screen->info.have_EXTX_portability_subset) { diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h index d44415a5fe1..2114be352d8 100644 --- a/src/gallium/drivers/zink/zink_screen.h +++ b/src/gallium/drivers/zink/zink_screen.h @@ -107,6 +107,8 @@ struct zink_screen { PFN_vkCmdDrawIndirectCount vk_CmdDrawIndirectCount; PFN_vkCmdDrawIndexedIndirectCount vk_CmdDrawIndexedIndirectCount; + PFN_vkWaitSemaphores vk_WaitSemaphores; + PFN_vkGetMemoryFdKHR vk_GetMemoryFdKHR; PFN_vkCmdBeginConditionalRenderingEXT vk_CmdBeginConditionalRenderingEXT; PFN_vkCmdEndConditionalRenderingEXT vk_CmdEndConditionalRenderingEXT; |