Mesa (main): zink: move sparse buffer commit to screen queue

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 22 21:08:01 UTC 2021


Module: Mesa
Branch: main
Commit: 97f82493367004c6c73747000b331f8140095bfe
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=97f82493367004c6c73747000b331f8140095bfe

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Sun May  9 12:56:06 2021 -0400

zink: move sparse buffer commit to screen queue

all queue submission must be serialized with the dispatch thread

Acked-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11437>

---

 src/gallium/drivers/zink/zink_context.c | 86 +++++++++++++++++++++++----------
 1 file changed, 60 insertions(+), 26 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 31933128976..836794724c3 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -3137,6 +3137,29 @@ out:
                                 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
 }
 
+static inline struct zink_screen **
+get_screen_ptr_for_commit(uint8_t *mem)
+{
+   return (struct zink_screen**)(mem + sizeof(VkBindSparseInfo) + sizeof(VkSparseBufferMemoryBindInfo) + sizeof(VkSparseMemoryBind));
+}
+
+static bool
+resource_commit(struct zink_screen *screen, VkBindSparseInfo *sparse)
+{
+   VkQueue queue = screen->threaded ? screen->thread_queue : screen->queue;
+
+   VkResult ret = vkQueueBindSparse(queue, 1, sparse, VK_NULL_HANDLE);
+   return zink_screen_handle_vkresult(screen, ret);
+}
+
+static void
+submit_resource_commit(void *data, void *gdata, int thread_index)
+{
+   struct zink_screen **screen = get_screen_ptr_for_commit(data);
+   resource_commit(*screen, data);
+   free(data);
+}
+
 static bool
 zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsigned level, struct pipe_box *box, bool commit)
 {
@@ -3149,37 +3172,48 @@ zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsi
        zink_batch_usage_is_unflushed(res->obj->writes))
       zink_flush_queue(ctx);
 
-   VkBindSparseInfo sparse;
-   sparse.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
-   sparse.pNext = NULL;
-   sparse.waitSemaphoreCount = 0;
-   sparse.bufferBindCount = 1;
-   sparse.imageOpaqueBindCount = 0;
-   sparse.imageBindCount = 0;
-   sparse.signalSemaphoreCount = 0;
-
-   VkSparseBufferMemoryBindInfo sparse_bind;
-   sparse_bind.buffer = res->obj->buffer;
-   sparse_bind.bindCount = 1;
-   sparse.pBufferBinds = &sparse_bind;
-
-   VkSparseMemoryBind mem_bind;
-   mem_bind.resourceOffset = box->x;
-   mem_bind.size = box->width;
-   mem_bind.memory = commit ? res->obj->mem : VK_NULL_HANDLE;
+   uint8_t *mem = malloc(sizeof(VkBindSparseInfo) + sizeof(VkSparseBufferMemoryBindInfo) + sizeof(VkSparseMemoryBind) + sizeof(void*));
+   if (!mem)
+      return false;
+   VkBindSparseInfo *sparse = (void*)mem;
+   sparse->sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
+   sparse->pNext = NULL;
+   sparse->waitSemaphoreCount = 0;
+   sparse->bufferBindCount = 1;
+   sparse->imageOpaqueBindCount = 0;
+   sparse->imageBindCount = 0;
+   sparse->signalSemaphoreCount = 0;
+
+   VkSparseBufferMemoryBindInfo *sparse_bind = (void*)(mem + sizeof(VkBindSparseInfo));
+   sparse_bind->buffer = res->obj->buffer;
+   sparse_bind->bindCount = 1;
+   sparse->pBufferBinds = sparse_bind;
+
+   VkSparseMemoryBind *mem_bind = (void*)(mem + sizeof(VkBindSparseInfo) + sizeof(VkSparseBufferMemoryBindInfo));
+   mem_bind->resourceOffset = box->x;
+   mem_bind->size = box->width;
+   mem_bind->memory = commit ? res->obj->mem : VK_NULL_HANDLE;
    /* currently sparse buffers allocate memory 1:1 for the max sparse size,
     * but probably it should dynamically allocate the committed regions;
     * if this ever changes, update the below line
     */
-   mem_bind.memoryOffset = box->x;
-   mem_bind.flags = 0;
-   sparse_bind.pBinds = &mem_bind;
-   VkQueue queue = screen->threaded ? screen->thread_queue : screen->queue;
+   mem_bind->memoryOffset = box->x;
+   mem_bind->flags = 0;
+   sparse_bind->pBinds = mem_bind;
 
-   VkResult ret = vkQueueBindSparse(queue, 1, &sparse, VK_NULL_HANDLE);
-   if (!zink_screen_handle_vkresult(screen, ret)) {
-      check_device_lost(ctx);
-      return false;
+   struct zink_screen **ptr = get_screen_ptr_for_commit(mem);
+   *ptr = screen;
+
+   if (screen->threaded) {
+      /* this doesn't need any kind of fencing because any access to this resource
+       * will be automagically synchronized by queue dispatch */
+      util_queue_add_job(&screen->flush_queue, mem, NULL, submit_resource_commit, NULL, 0);
+   } else {
+      bool ret = resource_commit(screen, sparse);
+      if (!ret)
+         check_device_lost(ctx);
+      free(sparse);
+      return ret;
    }
    return true;
 }



More information about the mesa-commit mailing list