Mesa (main): radv: Add new submission path for use by the common sync framework.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Dec 31 15:40:22 UTC 2021


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

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Sun Nov 28 18:55:47 2021 +0100

radv: Add new submission path for use by the common sync framework.

Basically just a copy of radv's internal deferred submission handler.

This uses the new winsys submit2 to later be able to move the sem_info
to the winsys.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13974>

---

 src/amd/vulkan/radv_device.c | 126 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 116 insertions(+), 10 deletions(-)

diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 17c05ec7032..b82735dc60c 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -81,6 +81,8 @@ typedef void *drmDevicePtr;
 #define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC_FAST
 #endif
 
+static VkResult radv_queue_submit2(struct vk_queue *vqueue, struct vk_queue_submit *submission);
+
 static struct radv_timeline_point *
 radv_timeline_find_point_at_least_locked(struct radv_device *device, struct radv_timeline *timeline,
                                          uint64_t p);
@@ -2673,6 +2675,8 @@ radv_queue_init(struct radv_device *device, struct radv_queue *queue,
    if (result != VK_SUCCESS)
       return result;
 
+   queue->vk.driver_submit = radv_queue_submit2;
+
    list_inithead(&queue->pending_submissions);
    mtx_init(&queue->pending_mutex, mtx_plain);
 
@@ -4739,6 +4743,115 @@ radv_queue_submission_update_queue(struct radv_deferred_queue_submission *submis
    u_cnd_monotonic_broadcast(&submission->queue->device->timeline_cond);
 }
 
+static VkResult
+radv_queue_submit2(struct vk_queue *vqueue, struct vk_queue_submit *submission)
+{
+   struct radv_queue *queue = (struct radv_queue *)vqueue;
+   struct radeon_winsys_ctx *ctx = queue->hw_ctx;
+   uint32_t max_cs_submission = queue->device->trace_bo ? 1 : RADV_MAX_IBS_PER_SUBMIT;
+   bool can_patch = true;
+   uint32_t advance;
+   VkResult result;
+   struct radeon_cmdbuf *initial_preamble_cs = NULL;
+   struct radeon_cmdbuf *initial_flush_preamble_cs = NULL;
+   struct radeon_cmdbuf *continue_preamble_cs = NULL;
+
+   result =
+      radv_get_preambles(queue, submission->command_buffers, submission->command_buffer_count,
+                         &initial_preamble_cs, &initial_flush_preamble_cs, &continue_preamble_cs);
+   if (result != VK_SUCCESS)
+      goto fail;
+
+   for (uint32_t i = 0; i < submission->buffer_bind_count; ++i) {
+      result = radv_sparse_buffer_bind_memory(queue->device, submission->buffer_binds + i);
+      if (result != VK_SUCCESS)
+         goto fail;
+   }
+
+   for (uint32_t i = 0; i < submission->image_opaque_bind_count; ++i) {
+      result =
+         radv_sparse_image_opaque_bind_memory(queue->device, submission->image_opaque_binds + i);
+      if (result != VK_SUCCESS)
+         goto fail;
+   }
+
+   for (uint32_t i = 0; i < submission->image_bind_count; ++i) {
+      result = radv_sparse_image_bind_memory(queue->device, submission->image_binds + i);
+      if (result != VK_SUCCESS)
+         goto fail;
+   }
+
+   if (!submission->command_buffer_count && !submission->wait_count && !submission->signal_count)
+      return VK_SUCCESS;
+
+   if (!submission->command_buffer_count) {
+      result = queue->device->ws->cs_submit2(ctx, queue->vk.queue_family_index,
+                                             queue->vk.index_in_family, NULL, 0, NULL, NULL,
+                                             submission->wait_count, submission->waits,
+                                             submission->signal_count, submission->signals, false);
+      if (result != VK_SUCCESS)
+         goto fail;
+   } else {
+      struct radeon_cmdbuf **cs_array =
+         malloc(sizeof(struct radeon_cmdbuf *) * (submission->command_buffer_count));
+
+      for (uint32_t j = 0; j < submission->command_buffer_count; j++) {
+         struct radv_cmd_buffer *cmd_buffer =
+            (struct radv_cmd_buffer *)submission->command_buffers[j];
+         assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+         cs_array[j] = cmd_buffer->cs;
+         if ((cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT))
+            can_patch = false;
+
+         cmd_buffer->status = RADV_CMD_BUFFER_STATUS_PENDING;
+      }
+
+      for (uint32_t j = 0; j < submission->command_buffer_count; j += advance) {
+         struct radeon_cmdbuf *initial_preamble =
+            !j ? initial_flush_preamble_cs : initial_preamble_cs;
+         advance = MIN2(max_cs_submission, submission->command_buffer_count - j);
+         bool last_submit = j + advance == submission->command_buffer_count;
+
+         if (queue->device->trace_bo)
+            *queue->device->trace_id_ptr = 0;
+
+         result = queue->device->ws->cs_submit2(
+            ctx, queue->vk.queue_family_index, queue->vk.index_in_family, cs_array + j, advance,
+            initial_preamble, continue_preamble_cs, j == 0 ? submission->wait_count : 0,
+            submission->waits, last_submit ? submission->signal_count : 0, submission->signals,
+            can_patch);
+         if (result != VK_SUCCESS) {
+            free(cs_array);
+            goto fail;
+         }
+
+         if (queue->device->trace_bo) {
+            radv_check_gpu_hangs(queue, cs_array[j]);
+         }
+
+         if (queue->device->tma_bo) {
+            radv_check_trap_handler(queue);
+         }
+      }
+
+      free(cs_array);
+   }
+
+fail:
+   if (result != VK_SUCCESS && result != VK_ERROR_DEVICE_LOST) {
+      /* When something bad happened during the submission, such as
+       * an out of memory issue, it might be hard to recover from
+       * this inconsistent state. To avoid this sort of problem, we
+       * assume that we are in a really bad situation and return
+       * VK_ERROR_DEVICE_LOST to ensure the clients do not attempt
+       * to submit the same job again to this device.
+       */
+      result = vk_device_set_lost(&queue->device->vk, "vkQueueSubmit() failed");
+   }
+   return result;
+}
+
 static VkResult
 radv_queue_submit_deferred(struct radv_deferred_queue_submission *submission,
                            struct list_head *processing_list)
@@ -5036,17 +5149,10 @@ bool
 radv_queue_internal_submit(struct radv_queue *queue, struct radeon_cmdbuf *cs)
 {
    struct radeon_winsys_ctx *ctx = queue->hw_ctx;
-   struct radv_winsys_sem_info sem_info = {0};
-   VkResult result;
 
-   result = radv_alloc_sem_info(queue->device, &sem_info, 0, NULL, 0, 0, 0, NULL, VK_NULL_HANDLE);
-   if (result != VK_SUCCESS)
-      return false;
-
-   result =
-      queue->device->ws->cs_submit(ctx, queue->vk.queue_family_index, queue->vk.index_in_family,
-                                   &cs, 1, NULL, NULL, &sem_info, false);
-   radv_free_sem_info(&sem_info);
+   VkResult result =
+      queue->device->ws->cs_submit2(ctx, queue->vk.queue_family_index, queue->vk.index_in_family,
+                                    &cs, 1, NULL, NULL, 0, NULL, 0, NULL, false);
    if (result != VK_SUCCESS)
       return false;
 



More information about the mesa-commit mailing list