From 52b3f50df8a20064f38e45d2abe6030feac4f055 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Mon, 18 Dec 2017 21:02:05 +0100 Subject: [PATCH] radv: Implement sync file import/export for fences & semaphores. Reviewed-by: Dave Airlie --- src/amd/vulkan/radv_device.c | 115 ++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 28 deletions(-) diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index a4ec912ff2c..0c31bfb9b44 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -2825,7 +2825,6 @@ VkResult radv_CreateSemaphore( /* create a syncobject if we are going to export this semaphore */ if (handleTypes) { assert (device->physical_device->rad_info.has_syncobj); - assert (handleTypes == VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR); int ret = device->ws->create_syncobj(device->ws, &sem->syncobj); if (ret) { vk_free2(&device->alloc, pAllocator, sem); @@ -3683,18 +3682,59 @@ VkResult radv_GetMemoryFdPropertiesKHR(VkDevice _device, } } +static VkResult radv_import_opaque_fd(struct radv_device *device, + int fd, + uint32_t *syncobj) +{ + uint32_t syncobj_handle = 0; + int ret = device->ws->import_syncobj(device->ws, fd, &syncobj_handle); + if (ret != 0) + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); + + if (*syncobj) + device->ws->destroy_syncobj(device->ws, *syncobj); + + *syncobj = syncobj_handle; + close(fd); + + return VK_SUCCESS; +} + +static VkResult radv_import_sync_fd(struct radv_device *device, + int fd, + uint32_t *syncobj) +{ + /* If we create a syncobj we do it locally so that if we have an error, we don't + * leave a syncobj in an undetermined state in the fence. */ + uint32_t syncobj_handle = *syncobj; + if (!syncobj_handle) { + int ret = device->ws->create_syncobj(device->ws, &syncobj_handle); + if (ret) { + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); + } + } + + if (fd == -1) { + device->ws->signal_syncobj(device->ws, syncobj_handle); + } else { + int ret = device->ws->import_syncobj_from_sync_file(device->ws, syncobj_handle, fd); + if (ret != 0) + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); + } + + *syncobj = syncobj_handle; + if (fd != -1) + close(fd); + + return VK_SUCCESS; +} + VkResult radv_ImportSemaphoreFdKHR(VkDevice _device, const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo) { RADV_FROM_HANDLE(radv_device, device, _device); RADV_FROM_HANDLE(radv_semaphore, sem, pImportSemaphoreFdInfo->semaphore); - uint32_t syncobj_handle = 0; uint32_t *syncobj_dst = NULL; - assert(pImportSemaphoreFdInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR); - - int ret = device->ws->import_syncobj(device->ws, pImportSemaphoreFdInfo->fd, &syncobj_handle); - if (ret != 0) - return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); if (pImportSemaphoreFdInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR) { syncobj_dst = &sem->temp_syncobj; @@ -3702,12 +3742,14 @@ VkResult radv_ImportSemaphoreFdKHR(VkDevice _device, syncobj_dst = &sem->syncobj; } - if (*syncobj_dst) - device->ws->destroy_syncobj(device->ws, *syncobj_dst); - - *syncobj_dst = syncobj_handle; - close(pImportSemaphoreFdInfo->fd); - return VK_SUCCESS; + switch(pImportSemaphoreFdInfo->handleType) { + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: + return radv_import_opaque_fd(device, pImportSemaphoreFdInfo->fd, syncobj_dst); + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR: + return radv_import_sync_fd(device, pImportSemaphoreFdInfo->fd, syncobj_dst); + default: + unreachable("Unhandled semaphore handle type"); + } } VkResult radv_GetSemaphoreFdKHR(VkDevice _device, @@ -3719,12 +3761,22 @@ VkResult radv_GetSemaphoreFdKHR(VkDevice _device, int ret; uint32_t syncobj_handle; - assert(pGetFdInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR); if (sem->temp_syncobj) syncobj_handle = sem->temp_syncobj; else syncobj_handle = sem->syncobj; - ret = device->ws->export_syncobj(device->ws, syncobj_handle, pFd); + + switch(pGetFdInfo->handleType) { + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: + ret = device->ws->export_syncobj(device->ws, syncobj_handle, pFd); + break; + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR: + ret = device->ws->export_syncobj_to_sync_file(device->ws, syncobj_handle, pFd); + break; + default: + unreachable("Unhandled semaphore handle type"); + } + if (ret) return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); return VK_SUCCESS; @@ -3752,13 +3804,8 @@ VkResult radv_ImportFenceFdKHR(VkDevice _device, { RADV_FROM_HANDLE(radv_device, device, _device); RADV_FROM_HANDLE(radv_fence, fence, pImportFenceFdInfo->fence); - uint32_t syncobj_handle = 0; uint32_t *syncobj_dst = NULL; - assert(pImportFenceFdInfo->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR); - int ret = device->ws->import_syncobj(device->ws, pImportFenceFdInfo->fd, &syncobj_handle); - if (ret != 0) - return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); if (pImportFenceFdInfo->flags & VK_FENCE_IMPORT_TEMPORARY_BIT_KHR) { syncobj_dst = &fence->temp_syncobj; @@ -3766,12 +3813,14 @@ VkResult radv_ImportFenceFdKHR(VkDevice _device, syncobj_dst = &fence->syncobj; } - if (*syncobj_dst) - device->ws->destroy_syncobj(device->ws, *syncobj_dst); - - *syncobj_dst = syncobj_handle; - close(pImportFenceFdInfo->fd); - return VK_SUCCESS; + switch(pImportFenceFdInfo->handleType) { + case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: + return radv_import_opaque_fd(device, pImportFenceFdInfo->fd, syncobj_dst); + case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR: + return radv_import_sync_fd(device, pImportFenceFdInfo->fd, syncobj_dst); + default: + unreachable("Unhandled fence handle type"); + } } VkResult radv_GetFenceFdKHR(VkDevice _device, @@ -3783,12 +3832,22 @@ VkResult radv_GetFenceFdKHR(VkDevice _device, int ret; uint32_t syncobj_handle; - assert(pGetFdInfo->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR); if (fence->temp_syncobj) syncobj_handle = fence->temp_syncobj; else syncobj_handle = fence->syncobj; - ret = device->ws->export_syncobj(device->ws, syncobj_handle, pFd); + + switch(pGetFdInfo->handleType) { + case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: + ret = device->ws->export_syncobj(device->ws, syncobj_handle, pFd); + break; + case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR: + ret = device->ws->export_syncobj_to_sync_file(device->ws, syncobj_handle, pFd); + break; + default: + unreachable("Unhandled fence handle type"); + } + if (ret) return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); return VK_SUCCESS; -- 2.30.2