From e2ac01aaac8bb5a9adbbe0ff84c75a0b395b2414 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 8 Jun 2021 10:54:49 -0700 Subject: [PATCH] venus: add support for external fence on Android This is a hack. Signed-off-by: Chia-I Wu Reviewed-by: Yiwei Zhang Part-of: --- src/virtio/vulkan/vn_device.c | 13 ++++++++ src/virtio/vulkan/vn_queue.c | 75 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/virtio/vulkan/vn_device.c b/src/virtio/vulkan/vn_device.c index 9446509..2ea3efb 100644 --- a/src/virtio/vulkan/vn_device.c +++ b/src/virtio/vulkan/vn_device.c @@ -1412,6 +1412,13 @@ vn_physical_device_init_external_fence_handles( * and idle waiting. */ physical_dev->external_fence_handles = 0; + +#ifdef ANDROID + if (physical_dev->instance->experimental.globalFencing) { + physical_dev->external_fence_handles = + VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT; + } +#endif } static void @@ -1468,6 +1475,12 @@ vn_physical_device_get_native_extensions( #endif } +#ifdef ANDROID + if (instance->experimental.globalFencing) { + exts->KHR_external_fence_fd = true; + } +#endif + #ifdef VN_USE_WSI_PLATFORM exts->KHR_incremental_present = true; exts->KHR_swapchain = true; diff --git a/src/virtio/vulkan/vn_queue.c b/src/virtio/vulkan/vn_queue.c index b1cfa79..c694d73 100644 --- a/src/virtio/vulkan/vn_queue.c +++ b/src/virtio/vulkan/vn_queue.c @@ -10,6 +10,7 @@ #include "vn_queue.h" +#include "util/libsync.h" #include "venus-protocol/vn_protocol_driver_event.h" #include "venus-protocol/vn_protocol_driver_fence.h" #include "venus-protocol/vn_protocol_driver_queue.h" @@ -664,12 +665,60 @@ vn_WaitForFences(VkDevice device, return vn_result(dev->instance, result); } +static VkResult +vn_create_sync_file(struct vn_device *dev, int *out_fd) +{ + struct vn_renderer_sync *sync; + VkResult result = vn_renderer_sync_create(dev->renderer, 0, + VN_RENDERER_SYNC_BINARY, &sync); + if (result != VK_SUCCESS) + return vn_error(dev->instance, result); + + const struct vn_renderer_submit submit = { + .batches = + &(const struct vn_renderer_submit_batch){ + .syncs = &sync, + .sync_values = &(const uint64_t){ 1 }, + .sync_count = 1, + }, + .batch_count = 1, + }; + result = vn_renderer_submit(dev->renderer, &submit); + if (result != VK_SUCCESS) { + vn_renderer_sync_destroy(dev->renderer, sync); + return vn_error(dev->instance, result); + } + + *out_fd = vn_renderer_sync_export_syncobj(dev->renderer, sync, true); + vn_renderer_sync_destroy(dev->renderer, sync); + + return *out_fd >= 0 ? VK_SUCCESS : VK_ERROR_TOO_MANY_OBJECTS; +} + VkResult vn_ImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR *pImportFenceFdInfo) { struct vn_device *dev = vn_device_from_handle(device); - return vn_error(dev->instance, VK_ERROR_UNKNOWN); + struct vn_fence *fence = vn_fence_from_handle(pImportFenceFdInfo->fence); + ASSERTED const bool sync_file = pImportFenceFdInfo->handleType == + VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT; + const int fd = pImportFenceFdInfo->fd; + + assert(dev->instance->experimental.globalFencing); + assert(sync_file); + if (fd >= 0) { + const int ret = sync_wait(fd, -1); + if (ret) + return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE); + + close(fd); + } + + /* abuse VN_SYNC_TYPE_WSI_SIGNALED */ + vn_fence_signal_wsi(dev, fence); + + return VK_SUCCESS; } VkResult @@ -678,7 +727,29 @@ vn_GetFenceFdKHR(VkDevice device, int *pFd) { struct vn_device *dev = vn_device_from_handle(device); - return vn_error(dev->instance, VK_ERROR_UNKNOWN); + struct vn_fence *fence = vn_fence_from_handle(pGetFdInfo->fence); + const bool sync_file = + pGetFdInfo->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT; + struct vn_sync_payload *payload = fence->payload; + + assert(dev->instance->experimental.globalFencing); + assert(sync_file); + int fd = -1; + if (payload->type == VN_SYNC_TYPE_DEVICE_ONLY) { + VkResult result = vn_create_sync_file(dev, &fd); + if (result != VK_SUCCESS) + return vn_error(dev->instance, result); + } + + if (sync_file) { + vn_sync_payload_release(dev, &fence->temporary); + fence->payload = &fence->permanent; + + /* XXX implies reset operation on the host fence */ + } + + *pFd = fd; + return VK_SUCCESS; } /* semaphore commands */ -- 2.7.4