Mesa (main): turnip: Copy command buffers to deferred submit request

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 15 02:34:15 UTC 2021


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

Author: Hyunjun Ko <zzoon at igalia.com>
Date:   Tue Jun  8 06:49:45 2021 +0000

turnip: Copy command buffers to deferred submit request

To make sure the index of global bo table in drm_msm_gem_submit_cmd is
valid at actual submit time.

v1. Move the entry_count calculation into the submit request creation
function.

Fixes: #4877
Fixes: 3f229e34 ("turnip: Implement VK_KHR_timeline_semaphore.")

Signed-off-by: Hyunjun Ko <zzoon at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11260>

---

 src/freedreno/vulkan/tu_drm.c | 125 +++++++++++++++++++++++++++---------------
 1 file changed, 80 insertions(+), 45 deletions(-)

diff --git a/src/freedreno/vulkan/tu_drm.c b/src/freedreno/vulkan/tu_drm.c
index 839956a6eca..14bced0e2fa 100644
--- a/src/freedreno/vulkan/tu_drm.c
+++ b/src/freedreno/vulkan/tu_drm.c
@@ -83,6 +83,9 @@ struct tu_queue_submit
 {
    struct   list_head link;
 
+   VkCommandBuffer *cmd_buffers;
+   uint32_t cmd_buffer_count;
+
    struct   tu_syncobj **wait_semaphores;
    uint32_t wait_semaphore_count;
    struct   tu_syncobj **signal_semaphores;
@@ -106,6 +109,7 @@ struct tu_queue_submit
 
    bool     last_submit;
    uint32_t entry_count;
+   uint32_t counter_pass_index;
 };
 
 static int
@@ -837,10 +841,10 @@ tu_queue_submit_add_timeline_signal_locked(struct tu_queue_submit* submit,
 static VkResult
 tu_queue_submit_create_locked(struct tu_queue *queue,
                               const VkSubmitInfo *submit_info,
-                              const uint32_t entry_count,
                               const uint32_t nr_in_syncobjs,
                               const uint32_t nr_out_syncobjs,
                               const bool last_submit,
+                              const VkPerformanceQuerySubmitInfoKHR *perf_info,
                               struct tu_queue_submit **submit)
 {
    VkResult result;
@@ -862,6 +866,19 @@ tu_queue_submit_create_locked(struct tu_queue *queue,
    struct tu_queue_submit *new_submit = vk_zalloc(&queue->device->vk.alloc,
                sizeof(*new_submit), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
 
+   new_submit->cmd_buffer_count = submit_info->commandBufferCount;
+   new_submit->cmd_buffers = vk_zalloc(&queue->device->vk.alloc,
+         new_submit->cmd_buffer_count * sizeof(*new_submit->cmd_buffers), 8,
+         VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+
+   if (new_submit->cmd_buffers == NULL) {
+      result = vk_error(queue->device->instance, VK_ERROR_OUT_OF_HOST_MEMORY)
+      goto fail_cmd_buffers;
+   }
+
+   memcpy(new_submit->cmd_buffers, submit_info->pCommandBuffers,
+          new_submit->cmd_buffer_count * sizeof(*new_submit->cmd_buffers));
+
    new_submit->wait_semaphores = vk_zalloc(&queue->device->vk.alloc,
          submit_info->waitSemaphoreCount * sizeof(*new_submit->wait_semaphores),
          8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
@@ -904,6 +921,16 @@ tu_queue_submit_create_locked(struct tu_queue *queue,
       }
    }
 
+   uint32_t entry_count = 0;
+   for (uint32_t j = 0; j < new_submit->cmd_buffer_count; ++j) {
+      TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, new_submit->cmd_buffers[j]);
+
+      if (perf_info)
+         entry_count++;
+
+      entry_count += cmdbuf->cs.entry_count;
+   }
+
    new_submit->cmds = vk_zalloc(&queue->device->vk.alloc,
          entry_count * sizeof(*new_submit->cmds), 8,
          VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
@@ -937,6 +964,8 @@ tu_queue_submit_create_locked(struct tu_queue *queue,
    new_submit->nr_in_syncobjs = nr_in_syncobjs;
    new_submit->nr_out_syncobjs = nr_out_syncobjs;
    new_submit->last_submit = last_submit;
+   new_submit->counter_pass_index = perf_info ? perf_info->counterPassIndex : ~0;
+
    list_inithead(&new_submit->link);
 
    *submit = new_submit;
@@ -954,6 +983,8 @@ fail_wait_timelines:
 fail_signal_semaphores:
    vk_free(&queue->device->vk.alloc, new_submit->wait_semaphores);
 fail_wait_semaphores:
+   vk_free(&queue->device->vk.alloc, new_submit->cmd_buffers);
+fail_cmd_buffers:
    return result;
 }
 
@@ -971,9 +1002,49 @@ tu_queue_submit_free(struct tu_queue *queue, struct tu_queue_submit *submit)
    vk_free(&queue->device->vk.alloc, submit->cmds);
    vk_free(&queue->device->vk.alloc, submit->in_syncobjs);
    vk_free(&queue->device->vk.alloc, submit->out_syncobjs);
+   vk_free(&queue->device->vk.alloc, submit->cmd_buffers);
    vk_free(&queue->device->vk.alloc, submit);
 }
 
+static void
+tu_queue_build_msm_gem_submit_cmds(struct tu_queue *queue,
+                                   struct tu_queue_submit *submit)
+{
+   struct drm_msm_gem_submit_cmd *cmds = submit->cmds;
+
+   uint32_t entry_idx = 0;
+   for (uint32_t j = 0; j < submit->cmd_buffer_count; ++j) {
+      TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, submit->cmd_buffers[j]);
+      struct tu_cs *cs = &cmdbuf->cs;
+      struct tu_device *dev = queue->device;
+
+      if (submit->counter_pass_index != ~0) {
+         struct tu_cs_entry *perf_cs_entry =
+            &dev->perfcntrs_pass_cs_entries[submit->counter_pass_index];
+
+         cmds[entry_idx].type = MSM_SUBMIT_CMD_BUF;
+         cmds[entry_idx].submit_idx =
+            dev->bo_idx[perf_cs_entry->bo->gem_handle];
+         cmds[entry_idx].submit_offset = perf_cs_entry->offset;
+         cmds[entry_idx].size = perf_cs_entry->size;
+         cmds[entry_idx].pad = 0;
+         cmds[entry_idx].nr_relocs = 0;
+         cmds[entry_idx++].relocs = 0;
+      }
+
+      for (unsigned i = 0; i < cs->entry_count; ++i, ++entry_idx) {
+         cmds[entry_idx].type = MSM_SUBMIT_CMD_BUF;
+         cmds[entry_idx].submit_idx =
+            dev->bo_idx[cs->entries[i].bo->gem_handle];
+         cmds[entry_idx].submit_offset = cs->entries[i].offset;
+         cmds[entry_idx].size = cs->entries[i].size;
+         cmds[entry_idx].pad = 0;
+         cmds[entry_idx].nr_relocs = 0;
+         cmds[entry_idx].relocs = 0;
+      }
+   }
+}
+
 static VkResult
 tu_queue_submit_locked(struct tu_queue *queue, struct tu_queue_submit *submit)
 {
@@ -990,6 +1061,12 @@ tu_queue_submit_locked(struct tu_queue *queue, struct tu_queue_submit *submit)
 
    mtx_lock(&queue->device->bo_mutex);
 
+   /* drm_msm_gem_submit_cmd requires index of bo which could change at any
+    * time when bo_mutex is not locked. So we build submit cmds here the real
+    * place to submit.
+    */
+   tu_queue_build_msm_gem_submit_cmds(queue, submit);
+
    struct drm_msm_gem_submit req = {
       .flags = flags,
       .queueid = queue->msm_queue_id,
@@ -1186,22 +1263,12 @@ tu_QueueSubmit(VkQueue _queue,
       if (last_submit && fence)
          out_syncobjs_size += 1;
 
-      uint32_t entry_count = 0;
-      for (uint32_t j = 0; j < submit->commandBufferCount; ++j) {
-         TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, submit->pCommandBuffers[j]);
-
-         if (perf_info)
-            entry_count++;
-
-         entry_count += cmdbuf->cs.entry_count;
-      }
-
       pthread_mutex_lock(&queue->device->submit_mutex);
       struct tu_queue_submit *submit_req = NULL;
 
       VkResult ret = tu_queue_submit_create_locked(queue, submit,
-            entry_count, submit->waitSemaphoreCount, out_syncobjs_size,
-            last_submit, &submit_req);
+            submit->waitSemaphoreCount, out_syncobjs_size,
+            last_submit, perf_info, &submit_req);
 
       if (ret != VK_SUCCESS) {
          pthread_mutex_unlock(&queue->device->submit_mutex);
@@ -1246,38 +1313,6 @@ tu_QueueSubmit(VkQueue _queue,
          };
       }
 
-      struct drm_msm_gem_submit_cmd *cmds = submit_req->cmds;
-
-      uint32_t entry_idx = 0;
-      for (uint32_t j = 0; j < submit->commandBufferCount; ++j) {
-         TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, submit->pCommandBuffers[j]);
-         struct tu_cs *cs = &cmdbuf->cs;
-
-         if (perf_info) {
-            struct tu_cs_entry *perf_cs_entry =
-               &cmdbuf->device->perfcntrs_pass_cs_entries[perf_info->counterPassIndex];
-            cmds[entry_idx].type = MSM_SUBMIT_CMD_BUF;
-            cmds[entry_idx].submit_idx =
-               queue->device->bo_idx[perf_cs_entry->bo->gem_handle];
-            cmds[entry_idx].submit_offset = perf_cs_entry->offset;
-            cmds[entry_idx].size = perf_cs_entry->size;
-            cmds[entry_idx].pad = 0;
-            cmds[entry_idx].nr_relocs = 0;
-            cmds[entry_idx++].relocs = 0;
-         }
-
-         for (unsigned i = 0; i < cs->entry_count; ++i, ++entry_idx) {
-            cmds[entry_idx].type = MSM_SUBMIT_CMD_BUF;
-            cmds[entry_idx].submit_idx =
-               queue->device->bo_idx[cs->entries[i].bo->gem_handle];
-            cmds[entry_idx].submit_offset = cs->entries[i].offset;
-            cmds[entry_idx].size = cs->entries[i].size;
-            cmds[entry_idx].pad = 0;
-            cmds[entry_idx].nr_relocs = 0;
-            cmds[entry_idx].relocs = 0;
-         }
-      }
-
       /* Queue the current submit */
       list_addtail(&submit_req->link, &queue->queued_submits);
       ret = tu_device_submit_deferred_locked(queue->device);



More information about the mesa-commit mailing list