Mesa (master): zink: hook up timeline semaphore signalling during batch submission

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Apr 1 13:33:53 UTC 2021


Module: Mesa
Branch: master
Commit: 9a13add12e1cb3e71d7fc851a49ca3305c33c9f1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9a13add12e1cb3e71d7fc851a49ca3305c33c9f1

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Fri Feb 12 14:15:27 2021 -0500

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 at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9963>

---

 src/gallium/drivers/zink/zink_batch.c        | 43 ++++++++++++++++++++++++++++
 src/gallium/drivers/zink/zink_batch.h        |  5 ++++
 src/gallium/drivers/zink/zink_context.c      |  8 +++++-
 src/gallium/drivers/zink/zink_context.h      |  1 +
 src/gallium/drivers/zink/zink_device_info.py |  1 +
 src/gallium/drivers/zink/zink_screen.c       |  3 ++
 src/gallium/drivers/zink/zink_screen.h       |  2 ++
 7 files changed, 62 insertions(+), 1 deletion(-)

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;



More information about the mesa-commit mailing list