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

Author: Yiwei Zhang <[email protected]>
Date:   Thu Aug 11 22:08:43 2022 +0000

venus: use a separate sync fence for Android wsi

Also refactors the codes a bit.

Signed-off-by: Yiwei Zhang <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17975>

---

 src/virtio/vulkan/vn_android.c | 49 ++++++++++++++++++++++++++++++++----------
 src/virtio/vulkan/vn_device.c  |  8 +++++--
 src/virtio/vulkan/vn_queue.h   |  4 ++++
 3 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/src/virtio/vulkan/vn_android.c b/src/virtio/vulkan/vn_android.c
index 9895f3bc805..f1ba3ce68f1 100644
--- a/src/virtio/vulkan/vn_android.c
+++ b/src/virtio/vulkan/vn_android.c
@@ -796,17 +796,38 @@ vn_AcquireImageANDROID(VkDevice device,
    return vn_result(dev->instance, result);
 }
 
+static VkResult
+vn_android_sync_fence_create(struct vn_queue *queue)
+{
+   struct vn_device *dev = queue->device;
+
+   const VkExportFenceCreateInfo export_info = {
+      .sType = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
+      .pNext = NULL,
+      .handleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
+   };
+   const VkFenceCreateInfo create_info = {
+      .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+      .pNext =
+         dev->instance->experimental.globalFencing ? &export_info : NULL,
+      .flags = 0,
+   };
+   return vn_CreateFence(vn_device_to_handle(dev), &create_info, NULL,
+                         &queue->sync_fence);
+}
+
 VkResult
-vn_QueueSignalReleaseImageANDROID(VkQueue queue,
+vn_QueueSignalReleaseImageANDROID(VkQueue _queue,
                                   uint32_t waitSemaphoreCount,
                                   const VkSemaphore *pWaitSemaphores,
                                   VkImage image,
                                   int *pNativeFenceFd)
 {
    VN_TRACE_FUNC();
-   struct vn_queue *que = vn_queue_from_handle(queue);
-   struct vn_device *dev = que->device;
+   struct vn_queue *queue = vn_queue_from_handle(_queue);
+   struct vn_device *dev = queue->device;
    const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
+   const bool has_global_fencing = dev->instance->experimental.globalFencing;
    VkDevice device = vn_device_to_handle(dev);
    VkPipelineStageFlags local_stage_masks[8];
    VkPipelineStageFlags *stage_masks = local_stage_masks;
@@ -818,6 +839,13 @@ vn_QueueSignalReleaseImageANDROID(VkQueue queue,
       return VK_SUCCESS;
    }
 
+   /* lazily create sync fence for Android wsi */
+   if (queue->sync_fence == VK_NULL_HANDLE) {
+      result = vn_android_sync_fence_create(queue);
+      if (result != VK_SUCCESS)
+         return result;
+   }
+
    if (waitSemaphoreCount > ARRAY_SIZE(local_stage_masks)) {
       stage_masks =
          vk_alloc(alloc, sizeof(*stage_masks) * waitSemaphoreCount,
@@ -844,10 +872,9 @@ vn_QueueSignalReleaseImageANDROID(VkQueue queue,
     * reset the fence during vn_GetFenceFdKHR currently. Thus to ensure proper
     * host driver behavior, we pass VK_NULL_HANDLE here.
     */
-   result = vn_QueueSubmit(
-      queue, 1, &submit_info,
-      dev->instance->experimental.globalFencing == VK_TRUE ? VK_NULL_HANDLE
-                                                           : que->wait_fence);
+   result =
+      vn_QueueSubmit(_queue, 1, &submit_info,
+                     has_global_fencing ? VK_NULL_HANDLE : queue->sync_fence);
 
    if (stage_masks != local_stage_masks)
       vk_free(alloc, stage_masks);
@@ -855,7 +882,7 @@ vn_QueueSignalReleaseImageANDROID(VkQueue queue,
    if (result != VK_SUCCESS)
       return vn_error(dev->instance, result);
 
-   if (dev->instance->experimental.globalFencing == VK_TRUE) {
+   if (has_global_fencing) {
       /* With globalFencing, the external queue fence was not passed in the
        * above vn_QueueSubmit to hint it to be synchronous. So we need to wait
        * for the ring here before vn_GetFenceFdKHR which is pure kernel ops.
@@ -867,17 +894,17 @@ vn_QueueSignalReleaseImageANDROID(VkQueue queue,
       const VkFenceGetFdInfoKHR fd_info = {
          .sType = VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
          .pNext = NULL,
-         .fence = que->wait_fence,
+         .fence = queue->sync_fence,
          .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
       };
       result = vn_GetFenceFdKHR(device, &fd_info, &fd);
    } else {
       result =
-         vn_WaitForFences(device, 1, &que->wait_fence, VK_TRUE, UINT64_MAX);
+         vn_WaitForFences(device, 1, &queue->sync_fence, VK_TRUE, UINT64_MAX);
       if (result != VK_SUCCESS)
          return vn_error(dev->instance, result);
 
-      result = vn_ResetFences(device, 1, &que->wait_fence);
+      result = vn_ResetFences(device, 1, &queue->sync_fence);
    }
 
    if (result != VK_SUCCESS)
diff --git a/src/virtio/vulkan/vn_device.c b/src/virtio/vulkan/vn_device.c
index e83e0f2ced7..57a72da643e 100644
--- a/src/virtio/vulkan/vn_device.c
+++ b/src/virtio/vulkan/vn_device.c
@@ -22,9 +22,13 @@
 static void
 vn_queue_fini(struct vn_queue *queue)
 {
+   VkDevice dev_handle = vn_device_to_handle(queue->device);
+
    if (queue->wait_fence != VK_NULL_HANDLE) {
-      vn_DestroyFence(vn_device_to_handle(queue->device), queue->wait_fence,
-                      NULL);
+      vn_DestroyFence(dev_handle, queue->wait_fence, NULL);
+   }
+   if (queue->sync_fence != VK_NULL_HANDLE) {
+      vn_DestroyFence(dev_handle, queue->sync_fence, NULL);
    }
    vn_object_base_fini(&queue->base);
 }
diff --git a/src/virtio/vulkan/vn_queue.h b/src/virtio/vulkan/vn_queue.h
index 594ca226e53..c815b994564 100644
--- a/src/virtio/vulkan/vn_queue.h
+++ b/src/virtio/vulkan/vn_queue.h
@@ -23,7 +23,11 @@ struct vn_queue {
    uint32_t index;
    uint32_t flags;
 
+   /* wait fence used for vn_QueueWaitIdle */
    VkFence wait_fence;
+
+   /* sync fence used for Android wsi */
+   VkFence sync_fence;
 };
 VK_DEFINE_HANDLE_CASTS(vn_queue, base.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
 

Reply via email to