[Mesa-dev] [PATCH 16/21] anv: Implement VK_KHX_external_semaphore_fd
Chad Versace
chadversary at chromium.org
Wed May 3 00:15:20 UTC 2017
On Fri 14 Apr 2017, Jason Ekstrand wrote:
> This implementation allocates a 4k BO for each semaphore that can be
> exported using OPAQUE_FD and uses the kernel's already-existing
> synchronization mechanism on BOs.
> ---
> src/intel/vulkan/anv_batch_chain.c | 53 ++++++++++--
> src/intel/vulkan/anv_device.c | 4 +
> src/intel/vulkan/anv_entrypoints_gen.py | 1 +
> src/intel/vulkan/anv_private.h | 16 +++-
> src/intel/vulkan/anv_queue.c | 141 ++++++++++++++++++++++++++++++--
> 5 files changed, 199 insertions(+), 16 deletions(-)
[snip]
> @@ -513,14 +533,33 @@ VkResult anv_CreateSemaphore(
> VkExternalSemaphoreHandleTypeFlagsKHX handleTypes =
> export ? export->handleTypes : 0;
>
> - /* External semaphores are not yet supported */
> - assert(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_KHX) {
> + assert(handleTypes == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX);
> +
> + 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.
> + */
> + 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_KHX);
The Vulkan 1.0.49 spec does not list
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX as a possible error code for
vkCreateSemaphore. The reason is that
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX indicates that an external handle
does not match the expected handle type. Since vkCreateSemaphore has no
parameter that's an external handle, it can't return the error.
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX only makes sense for functions that
import a handle or query the properties of a handle.
This 'else' branch is capturing invalid application usage the API. Since
invalid usages leads to undefined behavior, we could claim that Mesa's
undefined behavior is to return a helpful error code. But...
I much prefer disastrous undefined behavior here instead of helpful
undefined behavior. If we return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX,
then appsy may accidentally rely on our out-of-spec behavior. It would
be better to just abort() or, like anvil does in most cases, silently
ignore the invalid case and continue blindly ahead.
[snip]
> +static void
> +anv_semaphore_impl_cleanup(struct anv_device *device,
> + struct anv_semaphore_impl *impl)
> +{
> + switch (impl->type) {
> + case ANV_SEMAPHORE_TYPE_NONE:
> + case ANV_SEMAPHORE_TYPE_DUMMY:
> + /* Dummy. Nothing to do */
> + break;
> +
> + case ANV_SEMAPHORE_TYPE_BO:
> + anv_bo_cache_release(device, &device->bo_cache, impl->bo);
> + break;
> +
> + default:
> + unreachable("Invalid semaphore type");
> + }
This switch statement is a good candidate for exhaustive switch warnings
(-Wswitch). But we don't get the warnings unless the default is dropped
and the unreachable is moved to after the switch statement.
> +}
[snip]
>
> @@ -548,9 +609,73 @@ void anv_GetPhysicalDeviceExternalSemaphorePropertiesKHX(
> VkExternalSemaphorePropertiesKHX* pExternalSemaphoreProperties)
> {
> switch (pExternalSemaphoreInfo->handleType) {
> + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX:
> + pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
I expected exportFromImportedHandleTypes to be
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX. Why is it 0?
I admit I don't fully understand the VK_KHX_external_semaphore spec. (To
be fair, I doubt anyone fully understands it).
> + pExternalSemaphoreProperties->compatibleHandleTypes =
> + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX;
> + pExternalSemaphoreProperties->externalSemaphoreFeatures =
> + VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHX |
> + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHX;
> + break;
> +
> default:
> pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
> pExternalSemaphoreProperties->compatibleHandleTypes = 0;
> pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
> }
> }
> +
> +VkResult anv_ImportSemaphoreFdKHX(
> + VkDevice _device,
> + const VkImportSemaphoreFdInfoKHX* pImportSemaphoreFdInfo)
> +{
> + ANV_FROM_HANDLE(anv_device, device, _device);
> + ANV_FROM_HANDLE(anv_semaphore, semaphore, pImportSemaphoreFdInfo->semaphore);
> +
> + switch (pImportSemaphoreFdInfo->handleType) {
> + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHX: {
> + struct anv_bo *bo;
> + VkResult result = anv_bo_cache_import(device, &device->bo_cache,
> + pImportSemaphoreFdInfo->fd, 4096,
> + &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.
> + */
> + bo->flags &= ~EXEC_OBJECT_ASYNC;
> +
> + anv_semaphore_impl_cleanup(device, &semaphore->permanent);
> +
> + semaphore->permanent.type = ANV_SEMAPHORE_TYPE_BO;
> + semaphore->permanent.bo = bo;
> +
> + return VK_SUCCESS;
> + }
> +
> + default:
> + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
Yep. VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX is required here.
> + }
> +}
> +
> +VkResult anv_GetSemaphoreFdKHX(
> + VkDevice _device,
> + VkSemaphore _semaphore,
> + VkExternalSemaphoreHandleTypeFlagBitsKHX handleType,
> + int* pFd)
> +{
> + ANV_FROM_HANDLE(anv_device, device, _device);
> + ANV_FROM_HANDLE(anv_semaphore, semaphore, _semaphore);
> +
> + switch (semaphore->permanent.type) {
> + case ANV_SEMAPHORE_TYPE_BO:
> + return anv_bo_cache_export(device, &device->bo_cache,
> + semaphore->permanent.bo, pFd);
> +
> + default:
> + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
Like vkCreateSemaphore, for the same reasons,
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX is not a valid error code for
vkGetSemaphoreFdKHX. And like vkCreateSemaphore, I think disastrous
undefined behavior here is better than helpful undefined behavior.
> + }
> +
> + return VK_SUCCESS;
> +}
More information about the mesa-dev
mailing list