Mesa (main): pvr: Move transfer logic to pvr_job_transfer.[ch]

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 7 14:02:37 UTC 2022


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

Author: Rajnesh Kanwal <rajnesh.kanwal at imgtec.com>
Date:   Tue Apr 19 17:21:16 2022 +0100

pvr: Move transfer logic to pvr_job_transfer.[ch]

Signed-off-by: Rajnesh Kanwal <rajnesh.kanwal at imgtec.com>
Reviewed-by: Frank Binns <frank.binns at imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16897>

---

 src/imagination/vulkan/meson.build        |   1 +
 src/imagination/vulkan/pvr_job_transfer.c | 111 ++++++++++++++++++++++++++++++
 src/imagination/vulkan/pvr_job_transfer.h |  43 ++++++++++++
 src/imagination/vulkan/pvr_queue.c        |  93 ++++++++-----------------
 4 files changed, 184 insertions(+), 64 deletions(-)

diff --git a/src/imagination/vulkan/meson.build b/src/imagination/vulkan/meson.build
index 547de3afc2c..3b978dd4f33 100644
--- a/src/imagination/vulkan/meson.build
+++ b/src/imagination/vulkan/meson.build
@@ -49,6 +49,7 @@ pvr_files = files(
   'pvr_job_compute.c',
   'pvr_job_context.c',
   'pvr_job_render.c',
+  'pvr_job_transfer.c',
   'pvr_pass.c',
   'pvr_pipeline.c',
   'pvr_pipeline_cache.c',
diff --git a/src/imagination/vulkan/pvr_job_transfer.c b/src/imagination/vulkan/pvr_job_transfer.c
new file mode 100644
index 00000000000..840478d56cc
--- /dev/null
+++ b/src/imagination/vulkan/pvr_job_transfer.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2022 Imagination Technologies Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <vulkan/vulkan.h>
+
+#include "pvr_job_common.h"
+#include "pvr_job_context.h"
+#include "pvr_job_transfer.h"
+#include "pvr_private.h"
+#include "pvr_winsys.h"
+#include "util/list.h"
+#include "util/macros.h"
+#include "vk_sync.h"
+
+/* FIXME: Implement gpu based transfer support. */
+VkResult pvr_transfer_job_submit(struct pvr_device *device,
+                                 struct pvr_transfer_ctx *ctx,
+                                 struct pvr_sub_cmd *sub_cmd,
+                                 struct vk_sync **waits,
+                                 uint32_t wait_count,
+                                 uint32_t *stage_flags,
+                                 struct vk_sync *signal_sync)
+{
+   /* Wait for transfer semaphores here before doing any transfers. */
+   for (uint32_t i = 0U; i < wait_count; i++) {
+      if (stage_flags[i] & PVR_PIPELINE_STAGE_TRANSFER_BIT) {
+         VkResult result = vk_sync_wait(&device->vk,
+                                        waits[i],
+                                        0U,
+                                        VK_SYNC_WAIT_COMPLETE,
+                                        UINT64_MAX);
+         if (result != VK_SUCCESS)
+            return result;
+
+         stage_flags[i] &= ~PVR_PIPELINE_STAGE_TRANSFER_BIT;
+      }
+   }
+
+   list_for_each_entry_safe (struct pvr_transfer_cmd,
+                             transfer_cmd,
+                             &sub_cmd->transfer.transfer_cmds,
+                             link) {
+      bool src_mapped = false;
+      bool dst_mapped = false;
+      void *src_addr;
+      void *dst_addr;
+      void *ret_ptr;
+
+      /* Map if bo is not mapped. */
+      if (!transfer_cmd->src->vma->bo->map) {
+         src_mapped = true;
+         ret_ptr = device->ws->ops->buffer_map(transfer_cmd->src->vma->bo);
+         if (!ret_ptr)
+            return vk_error(device, VK_ERROR_MEMORY_MAP_FAILED);
+      }
+
+      if (!transfer_cmd->dst->vma->bo->map) {
+         dst_mapped = true;
+         ret_ptr = device->ws->ops->buffer_map(transfer_cmd->dst->vma->bo);
+         if (!ret_ptr)
+            return vk_error(device, VK_ERROR_MEMORY_MAP_FAILED);
+      }
+
+      src_addr =
+         transfer_cmd->src->vma->bo->map + transfer_cmd->src->vma->bo_offset;
+      dst_addr =
+         transfer_cmd->dst->vma->bo->map + transfer_cmd->dst->vma->bo_offset;
+
+      for (uint32_t i = 0; i < transfer_cmd->region_count; i++) {
+         VkBufferCopy2 *region = &transfer_cmd->regions[i];
+
+         memcpy(dst_addr + region->dstOffset,
+                src_addr + region->srcOffset,
+                region->size);
+      }
+
+      if (src_mapped)
+         device->ws->ops->buffer_unmap(transfer_cmd->src->vma->bo);
+
+      if (dst_mapped)
+         device->ws->ops->buffer_unmap(transfer_cmd->dst->vma->bo);
+   }
+
+   /* Given we are doing CPU based copy, completion fence should always be
+    * signaled. This should be fixed when GPU based copy is implemented.
+    */
+   return vk_sync_signal(&device->vk, signal_sync, 0);
+}
diff --git a/src/imagination/vulkan/pvr_job_transfer.h b/src/imagination/vulkan/pvr_job_transfer.h
new file mode 100644
index 00000000000..2f509ebeaf0
--- /dev/null
+++ b/src/imagination/vulkan/pvr_job_transfer.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2022 Imagination Technologies Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef PVR_JOB_TRANSFER_H
+#define PVR_JOB_TRANSFER_H
+
+#include <stdint.h>
+#include <vulkan/vulkan.h>
+
+struct pvr_device;
+struct pvr_sub_cmd;
+struct pvr_transfer_ctx;
+struct vk_sync;
+
+VkResult pvr_transfer_job_submit(struct pvr_device *device,
+                                 struct pvr_transfer_ctx *ctx,
+                                 struct pvr_sub_cmd *sub_cmd,
+                                 struct vk_sync **waits,
+                                 uint32_t wait_count,
+                                 uint32_t *stage_flags,
+                                 struct vk_sync *signal_sync);
+
+#endif /* PVR_JOB_TRANSFER_H */
diff --git a/src/imagination/vulkan/pvr_queue.c b/src/imagination/vulkan/pvr_queue.c
index e58023eaec2..11e01fae47e 100644
--- a/src/imagination/vulkan/pvr_queue.c
+++ b/src/imagination/vulkan/pvr_queue.c
@@ -39,6 +39,7 @@
 #include "pvr_job_compute.h"
 #include "pvr_job_context.h"
 #include "pvr_job_render.h"
+#include "pvr_job_transfer.h"
 #include "pvr_limits.h"
 #include "pvr_private.h"
 #include "util/macros.h"
@@ -358,83 +359,46 @@ pvr_process_compute_cmd(struct pvr_device *device,
    return result;
 }
 
-/* FIXME: Implement gpu based transfer support. */
 static VkResult
 pvr_process_transfer_cmds(struct pvr_device *device,
+                          struct pvr_queue *queue,
                           struct pvr_sub_cmd *sub_cmd,
                           struct vk_sync **waits,
                           uint32_t wait_count,
                           uint32_t *stage_flags,
                           struct vk_sync *completions[static PVR_JOB_TYPE_MAX])
 {
-   /* Wait for transfer semaphores here before doing any transfers. */
-   for (uint32_t i = 0U; i < wait_count; i++) {
-      if (stage_flags[i] & PVR_PIPELINE_STAGE_TRANSFER_BIT) {
-         VkResult result = vk_sync_wait(&device->vk,
-                                        waits[i],
-                                        0U,
-                                        VK_SYNC_WAIT_COMPLETE,
-                                        UINT64_MAX);
-         if (result != VK_SUCCESS)
-            return result;
-
-         stage_flags[i] &= ~PVR_PIPELINE_STAGE_TRANSFER_BIT;
-      }
-   }
-
-   list_for_each_entry_safe (struct pvr_transfer_cmd,
-                             transfer_cmd,
-                             &sub_cmd->transfer.transfer_cmds,
-                             link) {
-      bool src_mapped = false;
-      bool dst_mapped = false;
-      void *src_addr;
-      void *dst_addr;
-      void *ret_ptr;
-
-      /* Map if bo is not mapped. */
-      if (!transfer_cmd->src->vma->bo->map) {
-         src_mapped = true;
-         ret_ptr = device->ws->ops->buffer_map(transfer_cmd->src->vma->bo);
-         if (!ret_ptr)
-            return vk_error(device, VK_ERROR_MEMORY_MAP_FAILED);
-      }
-
-      if (!transfer_cmd->dst->vma->bo->map) {
-         dst_mapped = true;
-         ret_ptr = device->ws->ops->buffer_map(transfer_cmd->dst->vma->bo);
-         if (!ret_ptr)
-            return vk_error(device, VK_ERROR_MEMORY_MAP_FAILED);
-      }
-
-      src_addr =
-         transfer_cmd->src->vma->bo->map + transfer_cmd->src->vma->bo_offset;
-      dst_addr =
-         transfer_cmd->dst->vma->bo->map + transfer_cmd->dst->vma->bo_offset;
+   struct vk_sync *sync;
+   VkResult result;
 
-      for (uint32_t i = 0; i < transfer_cmd->region_count; i++) {
-         VkBufferCopy2 *region = &transfer_cmd->regions[i];
+   result = vk_sync_create(&device->vk,
+                           &device->pdevice->ws->syncobj_type,
+                           0U,
+                           0UL,
+                           &sync);
+   if (result != VK_SUCCESS)
+      return result;
 
-         memcpy(dst_addr + region->dstOffset,
-                src_addr + region->srcOffset,
-                region->size);
-      }
+   /* This passes ownership of the wait fences to pvr_transfer_job_submit(). */
+   result = pvr_transfer_job_submit(device,
+                                    queue->transfer_ctx,
+                                    sub_cmd,
+                                    waits,
+                                    wait_count,
+                                    stage_flags,
+                                    sync);
+   if (result != VK_SUCCESS) {
+      vk_sync_destroy(&device->vk, sync);
+      return result;
+   }
 
-      if (src_mapped)
-         device->ws->ops->buffer_unmap(transfer_cmd->src->vma->bo);
+   /* Replace the completion fences. */
+   if (completions[PVR_JOB_TYPE_TRANSFER])
+      vk_sync_destroy(&device->vk, completions[PVR_JOB_TYPE_TRANSFER]);
 
-      if (dst_mapped)
-         device->ws->ops->buffer_unmap(transfer_cmd->dst->vma->bo);
-   }
+   completions[PVR_JOB_TYPE_TRANSFER] = sync;
 
-   /* Given we are doing CPU based copy, completion fence should always be
-    * signaled. This should be fixed when GPU based copy is implemented.
-    */
-   return vk_sync_create(&device->vk,
-                         &device->pdevice->ws->syncobj_type,
-                         0U,
-                         1UL,
-                         &completions[PVR_JOB_TYPE_TRANSFER]);
+   return result;
 }
 
 static VkResult
@@ -571,6 +535,7 @@ pvr_process_cmd_buffer(struct pvr_device *device,
 
       case PVR_SUB_CMD_TYPE_TRANSFER:
          result = pvr_process_transfer_cmds(device,
+                                            queue,
                                             sub_cmd,
                                             waits,
                                             wait_count,



More information about the mesa-commit mailing list