radv: Implement sync file import/export for fences & semaphores.

Reviewed-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Bas Nieuwenhuizen 2017-12-18 21:02:05 +01:00
parent b98bbdf490
commit 52b3f50df8

View file

@ -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;