diff options
Diffstat (limited to 'src/intel/vulkan/anv_queue.c')
-rw-r--r-- | src/intel/vulkan/anv_queue.c | 154 |
1 files changed, 149 insertions, 5 deletions
diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c index 2c10e9d2f69..9a0789ca322 100644 --- a/src/intel/vulkan/anv_queue.c +++ b/src/intel/vulkan/anv_queue.c @@ -528,11 +528,38 @@ VkResult anv_CreateSemaphore( if (semaphore == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - /* The DRM execbuffer ioctl always execute in-oder so long as you stay - * on the same ring. Since we don't expose the blit engine as a DMA - * queue, a dummy no-op semaphore is a perfectly valid implementation. - */ - semaphore->permanent.type = ANV_SEMAPHORE_TYPE_DUMMY; + const VkExportSemaphoreCreateInfoKHR *export = + vk_find_struct_const(pCreateInfo->pNext, EXPORT_SEMAPHORE_CREATE_INFO_KHR); + VkExternalSemaphoreHandleTypeFlagsKHR handleTypes = + export ? export->handleTypes : 0; + + if (handleTypes == 0) { + /* The DRM execbuffer ioctl always execute in-oder so long as you stay + * on the same ring. Since we don't expose the blit engine as a DMA + * queue, a dummy no-op semaphore is a perfectly valid implementation. + */ + semaphore->permanent.type = ANV_SEMAPHORE_TYPE_DUMMY; + } else if (handleTypes & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR) { + assert(handleTypes == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR); + + semaphore->permanent.type = ANV_SEMAPHORE_TYPE_BO; + VkResult result = anv_bo_cache_alloc(device, &device->bo_cache, + 4096, &semaphore->permanent.bo); + if (result != VK_SUCCESS) { + vk_free2(&device->alloc, pAllocator, semaphore); + return result; + } + + /* If we're going to use this as a fence, we need to *not* have the + * EXEC_OBJECT_ASYNC bit set. + */ + assert(!(semaphore->permanent.bo->flags & EXEC_OBJECT_ASYNC)); + } else { + assert(!"Unknown handle type"); + vk_free2(&device->alloc, pAllocator, semaphore); + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); + } + semaphore->temporary.type = ANV_SEMAPHORE_TYPE_NONE; *pSemaphore = anv_semaphore_to_handle(semaphore); @@ -558,6 +585,17 @@ anv_semaphore_impl_cleanup(struct anv_device *device, unreachable("Invalid semaphore type"); } +void +anv_semaphore_reset_temporary(struct anv_device *device, + struct anv_semaphore *semaphore) +{ + if (semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE) + return; + + anv_semaphore_impl_cleanup(device, &semaphore->temporary); + semaphore->temporary.type = ANV_SEMAPHORE_TYPE_NONE; +} + void anv_DestroySemaphore( VkDevice _device, VkSemaphore _semaphore, @@ -574,3 +612,109 @@ void anv_DestroySemaphore( vk_free2(&device->alloc, pAllocator, semaphore); } + +void anv_GetPhysicalDeviceExternalSemaphorePropertiesKHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalSemaphoreInfoKHR* pExternalSemaphoreInfo, + VkExternalSemaphorePropertiesKHR* pExternalSemaphoreProperties) +{ + switch (pExternalSemaphoreInfo->handleType) { + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: + pExternalSemaphoreProperties->exportFromImportedHandleTypes = + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; + pExternalSemaphoreProperties->compatibleHandleTypes = + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; + pExternalSemaphoreProperties->externalSemaphoreFeatures = + VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR | + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR; + break; + + default: + pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0; + pExternalSemaphoreProperties->compatibleHandleTypes = 0; + pExternalSemaphoreProperties->externalSemaphoreFeatures = 0; + } +} + +VkResult anv_ImportSemaphoreFdKHR( + VkDevice _device, + const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_semaphore, semaphore, pImportSemaphoreFdInfo->semaphore); + int fd = pImportSemaphoreFdInfo->fd; + + struct anv_semaphore_impl new_impl = { + .type = ANV_SEMAPHORE_TYPE_NONE, + }; + + switch (pImportSemaphoreFdInfo->handleType) { + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: { + new_impl.type = ANV_SEMAPHORE_TYPE_BO; + + VkResult result = anv_bo_cache_import(device, &device->bo_cache, + fd, 4096, &new_impl.bo); + if (result != VK_SUCCESS) + return result; + + /* If we're going to use this as a fence, we need to *not* have the + * EXEC_OBJECT_ASYNC bit set. + */ + assert(!(new_impl.bo->flags & EXEC_OBJECT_ASYNC)); + + break; + } + + default: + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); + } + + if (pImportSemaphoreFdInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR) { + anv_semaphore_impl_cleanup(device, &semaphore->temporary); + semaphore->temporary = new_impl; + } else { + anv_semaphore_impl_cleanup(device, &semaphore->permanent); + semaphore->permanent = new_impl; + } + + return VK_SUCCESS; +} + +VkResult anv_GetSemaphoreFdKHR( + VkDevice _device, + const VkSemaphoreGetFdInfoKHR* pGetFdInfo, + int* pFd) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_semaphore, semaphore, pGetFdInfo->semaphore); + VkResult result; + + assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR); + + struct anv_semaphore_impl *impl = + semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE ? + &semaphore->temporary : &semaphore->permanent; + + switch (impl->type) { + case ANV_SEMAPHORE_TYPE_BO: + result = anv_bo_cache_export(device, &device->bo_cache, impl->bo, pFd); + if (result != VK_SUCCESS) + return result; + break; + + default: + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR); + } + + /* From the Vulkan 1.0.53 spec: + * + * "Export operations have the same transference as the specified handle + * type’s import operations. [...] If the semaphore was using a + * temporarily imported payload, the semaphore’s prior permanent payload + * will be restored. + */ + if (impl == &semaphore->temporary) + anv_semaphore_impl_cleanup(device, impl); + + return VK_SUCCESS; +} |