Mesa (main): panvk: Convert to the common sync/submit framework

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Mar 17 16:43:47 UTC 2022


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

Author: Jason Ekstrand <jason.ekstrand at collabora.com>
Date:   Tue Mar  8 22:13:20 2022 -0600

panvk: Convert to the common sync/submit framework

Acked-by: Boris Brezillon <boris.brezillon at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15296>

---

 src/panfrost/vulkan/meson.build       |   1 -
 src/panfrost/vulkan/panvk_device.c    |  22 ++
 src/panfrost/vulkan/panvk_private.h   |  33 +--
 src/panfrost/vulkan/panvk_sync.c      | 420 ----------------------------------
 src/panfrost/vulkan/panvk_vX_device.c | 160 +++++++------
 src/panfrost/vulkan/panvk_vX_device.h |  34 +++
 src/panfrost/vulkan/panvk_wsi.c       |  27 ++-
 7 files changed, 166 insertions(+), 531 deletions(-)

diff --git a/src/panfrost/vulkan/meson.build b/src/panfrost/vulkan/meson.build
index 2471fd4641a..026a4d55e76 100644
--- a/src/panfrost/vulkan/meson.build
+++ b/src/panfrost/vulkan/meson.build
@@ -47,7 +47,6 @@ libpanvk_files = files(
   'panvk_private.h',
   'panvk_query.c',
   'panvk_shader.c',
-  'panvk_sync.c',
   'panvk_util.c',
   'panvk_wsi.c',
 )
diff --git a/src/panfrost/vulkan/panvk_device.c b/src/panfrost/vulkan/panvk_device.c
index c790fc87910..c49f9c9b098 100644
--- a/src/panfrost/vulkan/panvk_device.c
+++ b/src/panfrost/vulkan/panvk_device.c
@@ -47,6 +47,7 @@
 #include "util/disk_cache.h"
 #include "util/strtod.h"
 #include "vk_format.h"
+#include "vk_drm_syncobj.h"
 #include "vk_util.h"
 
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
@@ -340,6 +341,17 @@ panvk_physical_device_init(struct panvk_physical_device *device,
    panvk_get_driver_uuid(&device->device_uuid);
    panvk_get_device_uuid(&device->device_uuid);
 
+   device->drm_syncobj_type = vk_drm_syncobj_get_type(device->pdev.fd);
+   /* We don't support timelines in the uAPI yet and we don't want it getting
+    * suddenly turned on by vk_drm_syncobj_get_type() without us adding panvk
+    * code for it first.
+    */
+   device->drm_syncobj_type.features &= ~VK_SYNC_FEATURE_TIMELINE;
+
+   device->sync_types[0] = &device->drm_syncobj_type;
+   device->sync_types[1] = NULL;
+   device->vk.supported_sync_types = device->sync_types;
+
    result = panvk_wsi_init(device);
    if (result != VK_SUCCESS) {
       vk_error(instance, result);
@@ -943,6 +955,13 @@ panvk_queue_init(struct panvk_device *device,
       return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
 
+   switch (pdev->arch) {
+   case 5: queue->vk.driver_submit = panvk_v5_queue_submit; break;
+   case 6: queue->vk.driver_submit = panvk_v6_queue_submit; break;
+   case 7: queue->vk.driver_submit = panvk_v7_queue_submit; break;
+   default: unreachable("Invalid arch");
+   }
+
    queue->sync = create.handle;
    return VK_SUCCESS;
 }
@@ -1004,6 +1023,9 @@ panvk_CreateDevice(VkPhysicalDevice physicalDevice,
    device->instance = physical_device->instance;
    device->physical_device = physical_device;
 
+   const struct panfrost_device *pdev = &physical_device->pdev;
+   vk_device_set_drm_fd(&device->vk, pdev->fd);
+
    for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
       const VkDeviceQueueCreateInfo *queue_create =
          &pCreateInfo->pQueueCreateInfos[i];
diff --git a/src/panfrost/vulkan/panvk_private.h b/src/panfrost/vulkan/panvk_private.h
index d4dbd74c935..c21caa3b4ed 100644
--- a/src/panfrost/vulkan/panvk_private.h
+++ b/src/panfrost/vulkan/panvk_private.h
@@ -58,6 +58,7 @@
 #include "vk_object.h"
 #include "vk_physical_device.h"
 #include "vk_queue.h"
+#include "vk_sync.h"
 #include "wsi_common.h"
 
 #include "drm-uapi/panfrost_drm.h"
@@ -185,6 +186,9 @@ struct panvk_physical_device {
    uint8_t device_uuid[VK_UUID_SIZE];
    uint8_t cache_uuid[VK_UUID_SIZE];
 
+   struct vk_sync_type drm_syncobj_type;
+   const struct vk_sync_type *sync_types[2];
+
    struct wsi_device wsi_device;
    struct panvk_meta meta;
 
@@ -289,10 +293,6 @@ struct panvk_batch {
    bool issued;
 };
 
-struct panvk_syncobj {
-   uint32_t permanent, temporary;
-};
-
 enum panvk_event_op_type {
    PANVK_EVENT_OP_SET,
    PANVK_EVENT_OP_RESET,
@@ -304,25 +304,6 @@ struct panvk_event_op {
    struct panvk_event *event;
 };
 
-struct panvk_fence {
-   struct vk_object_base base;
-   struct panvk_syncobj syncobj;
-};
-
-struct panvk_semaphore {
-   struct vk_object_base base;
-   struct panvk_syncobj syncobj;
-};
-
-int
-panvk_signal_syncobjs(struct panvk_device *device,
-                      struct panvk_syncobj *syncobj1,
-                      struct panvk_syncobj *syncobj2);
-
-int
-panvk_syncobj_to_fd(struct panvk_device *device,
-                    struct panvk_syncobj *sync);
-
 struct panvk_device_memory {
    struct vk_object_base base;
    struct panfrost_bo *bo;
@@ -1054,7 +1035,6 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_descriptor_set, base, VkDescriptorSet, VK_O
 VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_descriptor_set_layout, base,
                                VkDescriptorSetLayout, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
 VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_device_memory, base, VkDeviceMemory, VK_OBJECT_TYPE_DEVICE_MEMORY)
-VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_fence, base, VkFence, VK_OBJECT_TYPE_FENCE)
 VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_event, base, VkEvent, VK_OBJECT_TYPE_EVENT)
 VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_framebuffer, base, VkFramebuffer, VK_OBJECT_TYPE_FRAMEBUFFER)
 VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
@@ -1064,7 +1044,6 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline, base, VkPipeline, VK_OBJECT_TYPE_
 VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline_layout, base, VkPipelineLayout, VK_OBJECT_TYPE_PIPELINE_LAYOUT)
 VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_render_pass, base, VkRenderPass, VK_OBJECT_TYPE_RENDER_PASS)
 VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_sampler, base, VkSampler, VK_OBJECT_TYPE_SAMPLER)
-VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_semaphore, base, VkSemaphore, VK_OBJECT_TYPE_SEMAPHORE)
 
 #define panvk_arch_name(name, version) panvk_## version ## _ ## name
 
@@ -1088,12 +1067,14 @@ do { \
 #endif
 #include "panvk_vX_cmd_buffer.h"
 #include "panvk_vX_cs.h"
+#include "panvk_vX_device.h"
 #include "panvk_vX_meta.h"
 #else
 #define PAN_ARCH 5
 #define panvk_per_arch(name) panvk_arch_name(name, v5)
 #include "panvk_vX_cmd_buffer.h"
 #include "panvk_vX_cs.h"
+#include "panvk_vX_device.h"
 #include "panvk_vX_meta.h"
 #undef PAN_ARCH
 #undef panvk_per_arch
@@ -1101,6 +1082,7 @@ do { \
 #define panvk_per_arch(name) panvk_arch_name(name, v6)
 #include "panvk_vX_cmd_buffer.h"
 #include "panvk_vX_cs.h"
+#include "panvk_vX_device.h"
 #include "panvk_vX_meta.h"
 #undef PAN_ARCH
 #undef panvk_per_arch
@@ -1108,6 +1090,7 @@ do { \
 #define panvk_per_arch(name) panvk_arch_name(name, v7)
 #include "panvk_vX_cmd_buffer.h"
 #include "panvk_vX_cs.h"
+#include "panvk_vX_device.h"
 #include "panvk_vX_meta.h"
 #undef PAN_ARCH
 #undef panvk_per_arch
diff --git a/src/panfrost/vulkan/panvk_sync.c b/src/panfrost/vulkan/panvk_sync.c
deleted file mode 100644
index 91f905bd589..00000000000
--- a/src/panfrost/vulkan/panvk_sync.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * Copyright (C) 2021 Collabora Ltd.
- *
- * Derived from tu_drm.c which is:
- * Copyright © 2018 Google, Inc.
- * Copyright © 2015 Intel Corporation
- *
- * 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 <xf86drm.h>
-
-#include "panvk_private.h"
-
-static VkResult
-sync_create(struct panvk_device *device,
-            struct panvk_syncobj *sync,
-            bool signaled)
-{
-   const struct panfrost_device *pdev = &device->physical_device->pdev;
-
-   struct drm_syncobj_create create = {
-      .flags = signaled ? DRM_SYNCOBJ_CREATE_SIGNALED : 0,
-   };
-
-   int ret = drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_CREATE, &create);
-   if (ret)
-      return VK_ERROR_OUT_OF_HOST_MEMORY;
-
-   sync->permanent = create.handle;
-
-   return VK_SUCCESS;
-}
-
-static void
-sync_set_temporary(struct panvk_device *device, struct panvk_syncobj *sync,
-                   uint32_t syncobj)
-{
-   const struct panfrost_device *pdev = &device->physical_device->pdev;
-
-   if (sync->temporary) {
-      struct drm_syncobj_destroy destroy = { .handle = sync->temporary };
-      drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_DESTROY, &destroy);
-   }
-
-   sync->temporary = syncobj;
-}
-
-static void
-sync_destroy(struct panvk_device *device, struct panvk_syncobj *sync)
-{
-   const struct panfrost_device *pdev = &device->physical_device->pdev;
-
-   if (!sync)
-      return;
-
-   sync_set_temporary(device, sync, 0);
-   struct drm_syncobj_destroy destroy = { .handle = sync->permanent };
-   drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_DESTROY, &destroy);
-}
-
-static VkResult
-sync_import(struct panvk_device *device, struct panvk_syncobj *sync,
-            bool temporary, bool sync_fd, int fd)
-{
-   const struct panfrost_device *pdev = &device->physical_device->pdev;
-   int ret;
-
-   if (!sync_fd) {
-      uint32_t *dst = temporary ? &sync->temporary : &sync->permanent;
-
-      struct drm_syncobj_handle handle = { .fd = fd };
-      ret = drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &handle);
-      if (ret)
-         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
-
-      if (*dst) {
-         struct drm_syncobj_destroy destroy = { .handle = *dst };
-         drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_DESTROY, &destroy);
-      }
-      *dst = handle.handle;
-      close(fd);
-   } else {
-      assert(temporary);
-
-      struct drm_syncobj_create create = {};
-
-      if (fd == -1)
-         create.flags |= DRM_SYNCOBJ_CREATE_SIGNALED;
-
-      ret = drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_CREATE, &create);
-      if (ret)
-         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
-
-      if (fd != -1) {
-         struct drm_syncobj_handle handle = {
-            .fd = fd,
-            .handle = create.handle,
-            .flags = DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE,
-         };
-
-         ret = drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &handle);
-         if (ret) {
-            struct drm_syncobj_destroy destroy = { .handle = create.handle };
-            drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_DESTROY, &destroy);
-            return VK_ERROR_INVALID_EXTERNAL_HANDLE;
-         }
-         close(fd);
-      }
-
-      sync_set_temporary(device, sync, create.handle);
-   }
-
-   return VK_SUCCESS;
-}
-
-static VkResult
-sync_export(struct panvk_device *device, struct panvk_syncobj *sync,
-            bool sync_fd, int *p_fd)
-{
-   const struct panfrost_device *pdev = &device->physical_device->pdev;
-
-   struct drm_syncobj_handle handle = {
-      .handle = sync->temporary ? : sync->permanent,
-      .flags = sync_fd ? DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE : 0,
-      .fd = -1,
-   };
-   int ret = drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &handle);
-   if (ret)
-      return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
-
-   /* restore permanent payload on export */
-   sync_set_temporary(device, sync, 0);
-
-   *p_fd = handle.fd;
-   return VK_SUCCESS;
-}
-
-VkResult
-panvk_CreateSemaphore(VkDevice _device,
-                      const VkSemaphoreCreateInfo *pCreateInfo,
-                      const VkAllocationCallbacks *pAllocator,
-                      VkSemaphore *pSemaphore)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-   struct panvk_semaphore *sem =
-         vk_object_zalloc(&device->vk, pAllocator, sizeof(*sem),
-                          VK_OBJECT_TYPE_SEMAPHORE);
-   if (!sem)
-      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   VkResult ret = sync_create(device, &sem->syncobj, false);
-   if (ret != VK_SUCCESS) {
-      vk_free2(&device->vk.alloc, pAllocator, sync);
-      return ret;
-   }
-
-   *pSemaphore = panvk_semaphore_to_handle(sem);
-   return VK_SUCCESS;
-}
-
-void
-panvk_DestroySemaphore(VkDevice _device, VkSemaphore _sem, const VkAllocationCallbacks *pAllocator)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-   VK_FROM_HANDLE(panvk_semaphore, sem, _sem);
-
-   sync_destroy(device, &sem->syncobj);
-   vk_object_free(&device->vk, pAllocator, sem);
-}
-
-VkResult
-panvk_ImportSemaphoreFdKHR(VkDevice _device, const VkImportSemaphoreFdInfoKHR *info)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-   VK_FROM_HANDLE(panvk_semaphore, sem, info->semaphore);
-   bool temp = info->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT;
-   bool sync_fd = info->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
-
-   return sync_import(device, &sem->syncobj, temp, sync_fd, info->fd);
-}
-
-VkResult
-panvk_GetSemaphoreFdKHR(VkDevice _device, const VkSemaphoreGetFdInfoKHR *info, int *pFd)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-   VK_FROM_HANDLE(panvk_semaphore, sem, info->semaphore);
-   bool sync_fd = info->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
-
-   return sync_export(device, &sem->syncobj, sync_fd, pFd);
-}
-
-VkResult
-panvk_CreateFence(VkDevice _device,
-                  const VkFenceCreateInfo *info,
-                  const VkAllocationCallbacks *pAllocator,
-                  VkFence *pFence)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-   struct panvk_fence *fence =
-         vk_object_zalloc(&device->vk, pAllocator, sizeof(*fence),
-                          VK_OBJECT_TYPE_FENCE);
-   if (!fence)
-      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   VkResult ret = sync_create(device, &fence->syncobj,
-                              info->flags & VK_FENCE_CREATE_SIGNALED_BIT);
-   if (ret != VK_SUCCESS) {
-      vk_free2(&device->vk.alloc, pAllocator, fence);
-      return ret;
-   }
-
-   *pFence = panvk_fence_to_handle(fence);
-   return VK_SUCCESS;
-}
-
-void
-panvk_DestroyFence(VkDevice _device, VkFence _fence,
-                   const VkAllocationCallbacks *pAllocator)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-   VK_FROM_HANDLE(panvk_fence, fence, _fence);
-
-   if (!fence)
-      return;
-
-   sync_destroy(device, &fence->syncobj);
-   vk_object_free(&device->vk, pAllocator, fence);
-}
-
-VkResult
-panvk_ImportFenceFdKHR(VkDevice _device, const VkImportFenceFdInfoKHR *info)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-   VK_FROM_HANDLE(panvk_fence, fence, info->fence);
-   bool sync_fd = info->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
-   bool temp = info->flags & VK_FENCE_IMPORT_TEMPORARY_BIT;
-
-   return sync_import(device, &fence->syncobj, temp, sync_fd, info->fd);
-}
-
-VkResult
-panvk_GetFenceFdKHR(VkDevice _device, const VkFenceGetFdInfoKHR *info, int *pFd)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-   VK_FROM_HANDLE(panvk_fence, fence, info->fence);
-   bool sync_fd = info->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
-
-   return sync_export(device, &fence->syncobj, sync_fd, pFd);
-}
-
-static VkResult
-drm_syncobj_wait(struct panvk_device *device,
-                 const uint32_t *handles, uint32_t count_handles,
-                 int64_t timeout_nsec, bool wait_all)
-{
-   const struct panfrost_device *pdev = &device->physical_device->pdev;
-   struct drm_syncobj_wait wait = {
-      .handles = (uint64_t) (uintptr_t) handles,
-      .count_handles = count_handles,
-      .timeout_nsec = timeout_nsec,
-      .flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT |
-               (wait_all ? DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL : 0)
-   };
-
-   int ret = drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_WAIT, &wait);
-   if (ret) {
-      if (errno == ETIME)
-         return VK_TIMEOUT;
-
-      assert(0);
-      return VK_ERROR_DEVICE_LOST; /* TODO */
-   }
-   return VK_SUCCESS;
-}
-
-static uint64_t
-gettime_ns(void)
-{
-   struct timespec current;
-   clock_gettime(CLOCK_MONOTONIC, &current);
-   return (uint64_t)current.tv_sec * 1000000000 + current.tv_nsec;
-}
-
-/* and the kernel converts it right back to relative timeout - very smart UAPI */
-static uint64_t
-absolute_timeout(uint64_t timeout)
-{
-   if (timeout == 0)
-      return 0;
-   uint64_t current_time = gettime_ns();
-   uint64_t max_timeout = (uint64_t) INT64_MAX - current_time;
-
-   timeout = MIN2(max_timeout, timeout);
-
-   return (current_time + timeout);
-}
-
-VkResult
-panvk_WaitForFences(VkDevice _device,
-                    uint32_t fenceCount,
-                    const VkFence *pFences,
-                    VkBool32 waitAll,
-                    uint64_t timeout)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-
-   if (panvk_device_is_lost(device))
-      return VK_ERROR_DEVICE_LOST;
-
-   uint32_t handles[fenceCount];
-   for (unsigned i = 0; i < fenceCount; ++i) {
-      VK_FROM_HANDLE(panvk_fence, fence, pFences[i]);
-
-      if (fence->syncobj.temporary) {
-         handles[i] = fence->syncobj.temporary;
-      } else {
-         handles[i] = fence->syncobj.permanent;
-      }
-   }
-
-   return drm_syncobj_wait(device, handles, fenceCount, absolute_timeout(timeout), waitAll);
-}
-
-VkResult
-panvk_ResetFences(VkDevice _device, uint32_t fenceCount, const VkFence *pFences)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-   const struct panfrost_device *pdev = &device->physical_device->pdev;
-   int ret;
-
-   uint32_t handles[fenceCount];
-   for (unsigned i = 0; i < fenceCount; ++i) {
-      VK_FROM_HANDLE(panvk_fence, fence, pFences[i]);
-
-      sync_set_temporary(device, &fence->syncobj, 0);
-      handles[i] = fence->syncobj.permanent;
-   }
-
-   struct drm_syncobj_array objs = {
-      .handles = (uint64_t) (uintptr_t) handles,
-      .count_handles = fenceCount,
-   };
-
-   ret = drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_RESET, &objs);
-   if (ret) {
-      panvk_device_set_lost(device, "DRM_IOCTL_SYNCOBJ_RESET failure: %s",
-                         strerror(errno));
-   }
-
-   return VK_SUCCESS;
-}
-
-VkResult
-panvk_GetFenceStatus(VkDevice _device, VkFence _fence)
-{
-   VK_FROM_HANDLE(panvk_device, device, _device);
-   VK_FROM_HANDLE(panvk_fence, fence, _fence);
-   uint32_t handle = fence->syncobj.temporary ? : fence->syncobj.permanent;
-   VkResult result;
-
-   result = drm_syncobj_wait(device, &handle, 1, 0, false);
-   if (result == VK_TIMEOUT)
-      result = VK_NOT_READY;
-   return result;
-}
-
-int
-panvk_signal_syncobjs(struct panvk_device *device,
-                      struct panvk_syncobj *syncobj1,
-                      struct panvk_syncobj *syncobj2)
-{
-   const struct panfrost_device *pdev = &device->physical_device->pdev;
-   uint32_t handles[2], count = 0;
-
-   if (syncobj1)
-      handles[count++] = syncobj1->temporary ?: syncobj1->permanent;
-
-   if (syncobj2)
-      handles[count++] = syncobj2->temporary ?: syncobj2->permanent;
-
-   if (!count)
-      return 0;
-
-   struct drm_syncobj_array objs = {
-      .handles = (uintptr_t) handles,
-      .count_handles = count
-   };
-
-   return drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_SIGNAL, &objs);
-}
-
-int
-panvk_syncobj_to_fd(struct panvk_device *device, struct panvk_syncobj *sync)
-{
-   const struct panfrost_device *pdev = &device->physical_device->pdev;
-   struct drm_syncobj_handle handle = { .handle = sync->permanent };
-   int ret;
-
-   ret = drmIoctl(pdev->fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &handle);
-
-   return ret ? -1 : handle.fd;
-}
diff --git a/src/panfrost/vulkan/panvk_vX_device.c b/src/panfrost/vulkan/panvk_vX_device.c
index 78d968c0e4d..6944afea557 100644
--- a/src/panfrost/vulkan/panvk_vX_device.c
+++ b/src/panfrost/vulkan/panvk_vX_device.c
@@ -33,6 +33,8 @@
 #include "panvk_private.h"
 #include "panvk_cs.h"
 
+#include "vk_drm_syncobj.h"
+
 static void
 panvk_queue_submit_batch(struct panvk_queue *queue,
                          struct panvk_batch *batch,
@@ -198,106 +200,102 @@ panvk_signal_event_syncobjs(struct panvk_queue *queue, struct panvk_batch *batch
 }
 
 VkResult
-panvk_per_arch(QueueSubmit)(VkQueue _queue,
-                            uint32_t submitCount,
-                            const VkSubmitInfo *pSubmits,
-                            VkFence _fence)
+panvk_per_arch(queue_submit)(struct vk_queue *vk_queue,
+                             struct vk_queue_submit *submit)
 {
-   VK_FROM_HANDLE(panvk_queue, queue, _queue);
-   VK_FROM_HANDLE(panvk_fence, fence, _fence);
+   struct panvk_queue *queue =
+      container_of(vk_queue, struct panvk_queue, vk);
    const struct panfrost_device *pdev = &queue->device->physical_device->pdev;
 
-   for (uint32_t i = 0; i < submitCount; ++i) {
-      const VkSubmitInfo *submit = pSubmits + i;
-      unsigned nr_semaphores = submit->waitSemaphoreCount + 1;
-      uint32_t semaphores[nr_semaphores];
-      
-      semaphores[0] = queue->sync;
-      for (unsigned i = 0; i < submit->waitSemaphoreCount; i++) {
-         VK_FROM_HANDLE(panvk_semaphore, sem, submit->pWaitSemaphores[i]);
+   unsigned nr_semaphores = submit->wait_count + 1;
+   uint32_t semaphores[nr_semaphores];
 
-         semaphores[i + 1] = sem->syncobj.temporary ? : sem->syncobj.permanent;
-      }
+   semaphores[0] = queue->sync;
+   for (unsigned i = 0; i < submit->wait_count; i++) {
+      assert(vk_sync_type_is_drm_syncobj(submit->waits[i].sync->type));
+      struct vk_drm_syncobj *syncobj =
+         vk_sync_as_drm_syncobj(submit->waits[i].sync);
 
-      for (uint32_t j = 0; j < submit->commandBufferCount; ++j) {
-         VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, (submit->pCommandBuffers[j]));
-
-         list_for_each_entry(struct panvk_batch, batch, &cmdbuf->batches, node) {
-            /* FIXME: should be done at the batch level */
-            unsigned nr_bos =
-               panvk_pool_num_bos(&cmdbuf->desc_pool) +
-               panvk_pool_num_bos(&cmdbuf->varying_pool) +
-               panvk_pool_num_bos(&cmdbuf->tls_pool) +
-               (batch->fb.info ? batch->fb.info->attachment_count : 0) +
-               (batch->blit.src ? 1 : 0) +
-               (batch->blit.dst ? 1 : 0) +
-               (batch->scoreboard.first_tiler ? 1 : 0) + 1;
-            unsigned bo_idx = 0;
-            uint32_t bos[nr_bos];
-
-            panvk_pool_get_bo_handles(&cmdbuf->desc_pool, &bos[bo_idx]);
-            bo_idx += panvk_pool_num_bos(&cmdbuf->desc_pool);
-
-            panvk_pool_get_bo_handles(&cmdbuf->varying_pool, &bos[bo_idx]);
-            bo_idx += panvk_pool_num_bos(&cmdbuf->varying_pool);
-
-            panvk_pool_get_bo_handles(&cmdbuf->tls_pool, &bos[bo_idx]);
-            bo_idx += panvk_pool_num_bos(&cmdbuf->tls_pool);
-
-            if (batch->fb.info) {
-               for (unsigned i = 0; i < batch->fb.info->attachment_count; i++) {
-                  bos[bo_idx++] = batch->fb.info->attachments[i].iview->pview.image->data.bo->gem_handle;
-               }
+      semaphores[i + 1] = syncobj->syncobj;
+   }
+
+   for (uint32_t j = 0; j < submit->command_buffer_count; ++j) {
+      struct panvk_cmd_buffer *cmdbuf =
+         container_of(submit->command_buffers[j], struct panvk_cmd_buffer, vk);
+
+      list_for_each_entry(struct panvk_batch, batch, &cmdbuf->batches, node) {
+         /* FIXME: should be done at the batch level */
+         unsigned nr_bos =
+            panvk_pool_num_bos(&cmdbuf->desc_pool) +
+            panvk_pool_num_bos(&cmdbuf->varying_pool) +
+            panvk_pool_num_bos(&cmdbuf->tls_pool) +
+            (batch->fb.info ? batch->fb.info->attachment_count : 0) +
+            (batch->blit.src ? 1 : 0) +
+            (batch->blit.dst ? 1 : 0) +
+            (batch->scoreboard.first_tiler ? 1 : 0) + 1;
+         unsigned bo_idx = 0;
+         uint32_t bos[nr_bos];
+
+         panvk_pool_get_bo_handles(&cmdbuf->desc_pool, &bos[bo_idx]);
+         bo_idx += panvk_pool_num_bos(&cmdbuf->desc_pool);
+
+         panvk_pool_get_bo_handles(&cmdbuf->varying_pool, &bos[bo_idx]);
+         bo_idx += panvk_pool_num_bos(&cmdbuf->varying_pool);
+
+         panvk_pool_get_bo_handles(&cmdbuf->tls_pool, &bos[bo_idx]);
+         bo_idx += panvk_pool_num_bos(&cmdbuf->tls_pool);
+
+         if (batch->fb.info) {
+            for (unsigned i = 0; i < batch->fb.info->attachment_count; i++) {
+               bos[bo_idx++] = batch->fb.info->attachments[i].iview->pview.image->data.bo->gem_handle;
             }
+         }
 
-            if (batch->blit.src)
-               bos[bo_idx++] = batch->blit.src->gem_handle;
+         if (batch->blit.src)
+            bos[bo_idx++] = batch->blit.src->gem_handle;
 
-            if (batch->blit.dst)
-               bos[bo_idx++] = batch->blit.dst->gem_handle;
+         if (batch->blit.dst)
+            bos[bo_idx++] = batch->blit.dst->gem_handle;
 
-            if (batch->scoreboard.first_tiler)
-               bos[bo_idx++] = pdev->tiler_heap->gem_handle;
+         if (batch->scoreboard.first_tiler)
+            bos[bo_idx++] = pdev->tiler_heap->gem_handle;
 
-            bos[bo_idx++] = pdev->sample_positions->gem_handle;
-            assert(bo_idx == nr_bos);
+         bos[bo_idx++] = pdev->sample_positions->gem_handle;
+         assert(bo_idx == nr_bos);
 
-            /* Merge identical BO entries. */
-            for (unsigned x = 0; x < nr_bos; x++) {
-               for (unsigned y = x + 1; y < nr_bos; ) {
-                  if (bos[x] == bos[y])
-                     bos[y] = bos[--nr_bos];
-                  else
-                     y++;
-               }
+         /* Merge identical BO entries. */
+         for (unsigned x = 0; x < nr_bos; x++) {
+            for (unsigned y = x + 1; y < nr_bos; ) {
+               if (bos[x] == bos[y])
+                  bos[y] = bos[--nr_bos];
+               else
+                  y++;
             }
+         }
 
-            unsigned nr_in_fences = 0;
-            unsigned max_wait_event_syncobjs =
-               util_dynarray_num_elements(&batch->event_ops,
-                                          struct panvk_event_op);
-            uint32_t in_fences[nr_semaphores + max_wait_event_syncobjs];
-            memcpy(in_fences, semaphores, nr_semaphores * sizeof(*in_fences));
-            nr_in_fences += nr_semaphores;
+         unsigned nr_in_fences = 0;
+         unsigned max_wait_event_syncobjs =
+            util_dynarray_num_elements(&batch->event_ops,
+                                       struct panvk_event_op);
+         uint32_t in_fences[nr_semaphores + max_wait_event_syncobjs];
+         memcpy(in_fences, semaphores, nr_semaphores * sizeof(*in_fences));
+         nr_in_fences += nr_semaphores;
 
-            panvk_add_wait_event_syncobjs(batch, in_fences, &nr_in_fences);
+         panvk_add_wait_event_syncobjs(batch, in_fences, &nr_in_fences);
 
-            panvk_queue_submit_batch(queue, batch, bos, nr_bos, in_fences, nr_in_fences);
+         panvk_queue_submit_batch(queue, batch, bos, nr_bos, in_fences, nr_in_fences);
 
-            panvk_signal_event_syncobjs(queue, batch);
-         }
-      }
-
-      /* Transfer the out fence to signal semaphores */
-      for (unsigned i = 0; i < submit->signalSemaphoreCount; i++) {
-         VK_FROM_HANDLE(panvk_semaphore, sem, submit->pSignalSemaphores[i]);
-         panvk_queue_transfer_sync(queue, sem->syncobj.temporary ? : sem->syncobj.permanent);
+         panvk_signal_event_syncobjs(queue, batch);
       }
    }
 
-   if (fence) {
-      /* Transfer the last out fence to the fence object */
-      panvk_queue_transfer_sync(queue, fence->syncobj.temporary ? : fence->syncobj.permanent);
+   /* Transfer the out fence to signal semaphores */
+   for (unsigned i = 0; i < submit->signal_count; i++) {
+      assert(vk_sync_type_is_drm_syncobj(submit->signals[i].sync->type));
+      struct vk_drm_syncobj *syncobj =
+         vk_sync_as_drm_syncobj(submit->signals[i].sync);
+
+      panvk_queue_transfer_sync(queue, syncobj->syncobj);
    }
 
    return VK_SUCCESS;
diff --git a/src/panfrost/vulkan/panvk_vX_device.h b/src/panfrost/vulkan/panvk_vX_device.h
new file mode 100644
index 00000000000..5a780944b94
--- /dev/null
+++ b/src/panfrost/vulkan/panvk_vX_device.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 Collabora 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 PANVK_PRIVATE_H
+#error "Must be included from panvk_private.h"
+#endif
+
+#ifndef PAN_ARCH
+#error "no arch"
+#endif
+
+VkResult
+panvk_per_arch(queue_submit)(struct vk_queue *queue,
+                             struct vk_queue_submit *submit);
diff --git a/src/panfrost/vulkan/panvk_wsi.c b/src/panfrost/vulkan/panvk_wsi.c
index b3accd7a7e6..2af6f85ccc1 100644
--- a/src/panfrost/vulkan/panvk_wsi.c
+++ b/src/panfrost/vulkan/panvk_wsi.c
@@ -27,6 +27,9 @@
 
 #include "panvk_private.h"
 
+#include "vk_fence.h"
+#include "vk_semaphore.h"
+#include "vk_sync_dummy.h"
 #include "vk_util.h"
 #include "wsi_common.h"
 
@@ -72,8 +75,8 @@ panvk_AcquireNextImage2KHR(VkDevice _device,
                            uint32_t *pImageIndex)
 {
    VK_FROM_HANDLE(panvk_device, device, _device);
-   VK_FROM_HANDLE(panvk_fence, fence, pAcquireInfo->fence);
-   VK_FROM_HANDLE(panvk_semaphore, sem, pAcquireInfo->semaphore);
+   VK_FROM_HANDLE(vk_fence, fence, pAcquireInfo->fence);
+   VK_FROM_HANDLE(vk_semaphore, sem, pAcquireInfo->semaphore);
    struct panvk_physical_device *pdevice = device->physical_device;
 
    VkResult result =
@@ -82,8 +85,24 @@ panvk_AcquireNextImage2KHR(VkDevice _device,
 
    /* signal fence/semaphore - image is available immediately */
    if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR) {
-      panvk_signal_syncobjs(device, fence ? &fence->syncobj : NULL,
-                            sem ? &sem->syncobj : NULL);
+      VkResult sync_res;
+      if (fence) {
+         vk_fence_reset_temporary(&device->vk, fence);
+         sync_res = vk_sync_create(&device->vk, &vk_sync_dummy_type,
+                                   0 /* flags */, 0 /* initial_value */,
+                                   &fence->temporary);
+         if (sync_res != VK_SUCCESS)
+            return sync_res;
+      }
+
+      if (sem) {
+         vk_semaphore_reset_temporary(&device->vk, sem);
+         sync_res = vk_sync_create(&device->vk, &vk_sync_dummy_type,
+                                   0 /* flags */, 0 /* initial_value */,
+                                   &sem->temporary);
+         if (sync_res != VK_SUCCESS)
+            return sync_res;
+      }
    }
 
    return result;



More information about the mesa-commit mailing list