Mesa (main): venus: refactor vn_AcquireImageANDROID with globalFencing

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 15 20:00:09 UTC 2021


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

Author: Yiwei Zhang <zzyiwei at chromium.org>
Date:   Sat Jun 12 23:17:44 2021 +0000

venus: refactor vn_AcquireImageANDROID with globalFencing

This patch refactors to use vn_Import*FdKHR for Android WSI native sync
fence import when globalFencing is supported. Currently there's no perf
win from this, but will move the composer release fence waiting to the
GPU device side automatically when the entire Venus fencing support is
improved.

Signed-off-by: Yiwei Zhang <zzyiwei at chromium.org>
Reviewed-by: Chia-I Wu <olvaffe at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11342>

---

 src/virtio/vulkan/vn_android.c | 88 +++++++++++++++++++++++++++++++++++-------
 src/virtio/vulkan/vn_queue.c   |  6 +--
 2 files changed, 75 insertions(+), 19 deletions(-)

diff --git a/src/virtio/vulkan/vn_android.c b/src/virtio/vulkan/vn_android.c
index 7afc56ee594..aa59b5dcd5b 100644
--- a/src/virtio/vulkan/vn_android.c
+++ b/src/virtio/vulkan/vn_android.c
@@ -540,28 +540,86 @@ vn_AcquireImageANDROID(VkDevice device,
                        VkSemaphore semaphore,
                        VkFence fence)
 {
-   /* At this moment, out semaphore and fence are filled with already signaled
-    * payloads, and the native fence fd is waited inside until signaled.
-    */
    struct vn_device *dev = vn_device_from_handle(device);
-   struct vn_semaphore *sem = vn_semaphore_from_handle(semaphore);
-   struct vn_fence *fen = vn_fence_from_handle(fence);
+   VkResult result = VK_SUCCESS;
+
+   if (dev->instance->experimental.globalFencing == VK_FALSE) {
+      /* Fallback when VkVenusExperimentalFeatures100000MESA::globalFencing is
+       * VK_FALSE, out semaphore and fence are filled with already signaled
+       * payloads, and the native fence fd is waited inside until signaled.
+       */
+      if (nativeFenceFd >= 0) {
+         int ret = sync_wait(nativeFenceFd, -1);
+         /* Android loader expects the ICD to always close the fd */
+         close(nativeFenceFd);
+         if (ret)
+            return vn_error(dev->instance, VK_ERROR_SURFACE_LOST_KHR);
+      }
+
+      if (semaphore != VK_NULL_HANDLE)
+         vn_semaphore_signal_wsi(dev, vn_semaphore_from_handle(semaphore));
 
+      if (fence != VK_NULL_HANDLE)
+         vn_fence_signal_wsi(dev, vn_fence_from_handle(fence));
+
+      return VK_SUCCESS;
+   }
+
+   int semaphore_fd = -1;
+   int fence_fd = -1;
    if (nativeFenceFd >= 0) {
-      int ret = sync_wait(nativeFenceFd, INT32_MAX);
-      /* Android loader expects the ICD to always close the fd */
-      close(nativeFenceFd);
-      if (ret)
-         return vn_error(dev->instance, VK_ERROR_SURFACE_LOST_KHR);
+      if (semaphore != VK_NULL_HANDLE && fence != VK_NULL_HANDLE) {
+         semaphore_fd = nativeFenceFd;
+         fence_fd = os_dupfd_cloexec(nativeFenceFd);
+         if (fence_fd < 0) {
+            result = (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS
+                                       : VK_ERROR_OUT_OF_HOST_MEMORY;
+            close(nativeFenceFd);
+            return vn_error(dev->instance, result);
+         }
+      } else if (semaphore != VK_NULL_HANDLE) {
+         semaphore_fd = nativeFenceFd;
+      } else if (fence != VK_NULL_HANDLE) {
+         fence_fd = nativeFenceFd;
+      } else {
+         close(nativeFenceFd);
+      }
    }
 
-   if (sem)
-      vn_semaphore_signal_wsi(dev, sem);
+   if (semaphore != VK_NULL_HANDLE) {
+      const VkImportSemaphoreFdInfoKHR info = {
+         .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
+         .pNext = NULL,
+         .semaphore = semaphore,
+         .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
+         .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
+         .fd = semaphore_fd,
+      };
+      result = vn_ImportSemaphoreFdKHR(device, &info);
+      if (result == VK_SUCCESS)
+         semaphore_fd = -1;
+   }
 
-   if (fen)
-      vn_fence_signal_wsi(dev, fen);
+   if (result == VK_SUCCESS && fence != VK_NULL_HANDLE) {
+      const VkImportFenceFdInfoKHR info = {
+         .sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
+         .pNext = NULL,
+         .fence = fence,
+         .flags = VK_FENCE_IMPORT_TEMPORARY_BIT,
+         .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
+         .fd = fence_fd,
+      };
+      result = vn_ImportFenceFdKHR(device, &info);
+      if (result == VK_SUCCESS)
+         fence_fd = -1;
+   }
 
-   return VK_SUCCESS;
+   if (semaphore_fd >= 0)
+      close(semaphore_fd);
+   if (fence_fd >= 0)
+      close(fence_fd);
+
+   return vn_result(dev->instance, result);
 }
 
 VkResult
diff --git a/src/virtio/vulkan/vn_queue.c b/src/virtio/vulkan/vn_queue.c
index 0ddc731e447..21aea4d0df4 100644
--- a/src/virtio/vulkan/vn_queue.c
+++ b/src/virtio/vulkan/vn_queue.c
@@ -708,8 +708,7 @@ vn_ImportFenceFdKHR(VkDevice device,
    assert(dev->instance->experimental.globalFencing);
    assert(sync_file);
    if (fd >= 0) {
-      const int ret = sync_wait(fd, -1);
-      if (ret)
+      if (sync_wait(fd, -1))
          return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
 
       close(fd);
@@ -982,8 +981,7 @@ vn_ImportSemaphoreFdKHR(
    assert(dev->instance->experimental.globalFencing);
    assert(sync_file);
    if (fd >= 0) {
-      const int ret = sync_wait(fd, -1);
-      if (ret)
+      if (sync_wait(fd, -1))
          return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
 
       close(fd);



More information about the mesa-commit mailing list