From 4a61be24fee8cd3a18ee9c4b44cff17035acbcee Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Sun, 21 Apr 2019 01:01:55 +0100 Subject: [PATCH] anv: only resort to sync fds internally with no syncobj support We can rely on only one kind of synchronization object (drm-syncobj) when it is available. This reduces the number of file descriptors we use in our implementation. This will be required later for timeline semaphores implementation, at this point we won't ever want to use anything else but syncobjs. v2: Only use has_syncobj for semaphores (Jason) v3: Only has_syncobj in assert on semaphores in QueueSubmit (Jason) Signed-off-by: Lionel Landwerlin Reviewed-by: Jason Ekstrand --- src/intel/vulkan/anv_batch_chain.c | 8 +++++++ src/intel/vulkan/anv_queue.c | 45 +++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c index 098b1a3..114eda03 100644 --- a/src/intel/vulkan/anv_batch_chain.c +++ b/src/intel/vulkan/anv_batch_chain.c @@ -1594,6 +1594,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device, VkFence _fence) { ANV_FROM_HANDLE(anv_fence, fence, _fence); + UNUSED struct anv_physical_device *pdevice = &device->instance->physicalDevice; struct anv_execbuf execbuf; anv_execbuf_init(&execbuf); @@ -1608,6 +1609,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device, switch (impl->type) { case ANV_SEMAPHORE_TYPE_BO: + assert(!pdevice->has_syncobj); result = anv_execbuf_add_bo(&execbuf, impl->bo, NULL, 0, &device->alloc); if (result != VK_SUCCESS) @@ -1615,6 +1617,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device, break; case ANV_SEMAPHORE_TYPE_SYNC_FILE: + assert(!pdevice->has_syncobj); if (in_fence == -1) { in_fence = impl->fd; } else { @@ -1664,6 +1667,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device, switch (impl->type) { case ANV_SEMAPHORE_TYPE_BO: + assert(!pdevice->has_syncobj); result = anv_execbuf_add_bo(&execbuf, impl->bo, NULL, EXEC_OBJECT_WRITE, &device->alloc); if (result != VK_SUCCESS) @@ -1671,6 +1675,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device, break; case ANV_SEMAPHORE_TYPE_SYNC_FILE: + assert(!pdevice->has_syncobj); need_out_fence = true; break; @@ -1705,6 +1710,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device, switch (impl->type) { case ANV_FENCE_TYPE_BO: + assert(!pdevice->has_syncobj_wait); result = anv_execbuf_add_bo(&execbuf, &impl->bo.bo, NULL, EXEC_OBJECT_WRITE, &device->alloc); if (result != VK_SUCCESS) @@ -1778,6 +1784,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device, } if (fence && fence->permanent.type == ANV_FENCE_TYPE_BO) { + assert(!pdevice->has_syncobj_wait); /* BO fences can't be shared, so they can't be temporary. */ assert(fence->temporary.type == ANV_FENCE_TYPE_NONE); @@ -1795,6 +1802,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device, } if (result == VK_SUCCESS && need_out_fence) { + assert(!pdevice->has_syncobj_wait); int out_fence = execbuf.execbuf.rsvd2 >> 32; for (uint32_t i = 0; i < num_out_semaphores; i++) { ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]); diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c index dcefed9..4e87193 100644 --- a/src/intel/vulkan/anv_queue.c +++ b/src/intel/vulkan/anv_queue.c @@ -967,9 +967,13 @@ VkResult anv_CreateSemaphore( } } else if (handleTypes & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) { assert(handleTypes == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT); - - semaphore->permanent.type = ANV_SEMAPHORE_TYPE_SYNC_FILE; - semaphore->permanent.fd = -1; + if (device->instance->physicalDevice.has_syncobj) { + semaphore->permanent.type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ; + semaphore->permanent.syncobj = anv_gem_syncobj_create(device, 0); + } else { + semaphore->permanent.type = ANV_SEMAPHORE_TYPE_SYNC_FILE; + semaphore->permanent.fd = -1; + } } else { assert(!"Unknown handle type"); vk_free2(&device->alloc, pAllocator, semaphore); @@ -1132,10 +1136,30 @@ VkResult anv_ImportSemaphoreFdKHR( break; case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT: - new_impl = (struct anv_semaphore_impl) { - .type = ANV_SEMAPHORE_TYPE_SYNC_FILE, - .fd = fd, - }; + if (device->instance->physicalDevice.has_syncobj) { + new_impl = (struct anv_semaphore_impl) { + .type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ, + .syncobj = anv_gem_syncobj_create(device, 0), + }; + if (!new_impl.syncobj) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + if (anv_gem_syncobj_import_sync_file(device, new_impl.syncobj, fd)) { + anv_gem_syncobj_destroy(device, new_impl.syncobj); + return vk_errorf(device->instance, NULL, + VK_ERROR_INVALID_EXTERNAL_HANDLE, + "syncobj sync file import failed: %m"); + } + /* Ownership of the FD is transfered to Anv. Since we don't need it + * anymore because the associated fence has been put into a syncobj, + * we must close the FD. + */ + close(fd); + } else { + new_impl = (struct anv_semaphore_impl) { + .type = ANV_SEMAPHORE_TYPE_SYNC_FILE, + .fd = fd, + }; + } break; default: @@ -1205,7 +1229,12 @@ VkResult anv_GetSemaphoreFdKHR( return VK_SUCCESS; case ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ: - fd = anv_gem_syncobj_handle_to_fd(device, impl->syncobj); + if (pGetFdInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) + fd = anv_gem_syncobj_export_sync_file(device, impl->syncobj); + else { + assert(pGetFdInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT); + fd = anv_gem_syncobj_handle_to_fd(device, impl->syncobj); + } if (fd < 0) return vk_error(VK_ERROR_TOO_MANY_OBJECTS); *pFd = fd; -- 2.7.4