[Mesa-dev] [PATCH 7/7] anv: Implement VK_KHX_external_memory_fd (v2)
Jason Ekstrand
jason at jlekstrand.net
Tue Feb 28 22:34:17 UTC 2017
On Tue, Feb 28, 2017 at 10:58 AM, Chad Versace <chadversary at chromium.org>
wrote:
> From: Jason Ekstrand <jason.ekstrand at intel.com>
>
>
> v2 (chadv):
> - Rebase.
> - Fix vkGetPhysicalDeviceImageFormatProperties2KHR when
> handleType == 0.
> - Move handleType-independency comments out of handleType-switch, in
> vkGetPhysicalDeviceExternalBufferPropertiesKHX. Reduces diff in
> future dma_buf patches.
>
> Co-authored-with: Chad Versace <chadversary at chromium.org>
> ---
>
> On my branch wip/anv-external-memory.
> http://git.kiwitree.net/cgit/~chadv/mesa/log/?h=wip/anv-external-memory
>
> src/intel/vulkan/anv_device.c | 90
> +++++++++++++++++++++++++++++----
> src/intel/vulkan/anv_entrypoints_gen.py | 1 +
> src/intel/vulkan/anv_formats.c | 59 ++++++++++++++++++---
> 3 files changed, 133 insertions(+), 17 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index 024e19f91b9..ec88547368a 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -310,6 +310,10 @@ static const VkExtensionProperties
> device_extensions[] = {
> .extensionName = VK_KHX_EXTERNAL_MEMORY_EXTENSION_NAME,
> .specVersion = 1,
> },
> + {
> + .extensionName = VK_KHX_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
> + .specVersion = 1,
> + },
> };
>
> static void *
> @@ -1400,7 +1404,7 @@ VkResult anv_AllocateMemory(
> {
> ANV_FROM_HANDLE(anv_device, device, _device);
> struct anv_device_memory *mem;
> - VkResult result;
> + VkResult result = VK_SUCCESS;
>
> assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_
> ALLOCATE_INFO);
>
> @@ -1418,18 +1422,50 @@ VkResult anv_AllocateMemory(
> if (mem == NULL)
> return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
>
> - /* The kernel is going to give us whole pages anyway */
> - uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096);
> -
> - result = anv_bo_init_new(&mem->bo, device, alloc_size);
> - if (result != VK_SUCCESS)
> - goto fail;
> -
> mem->type_index = pAllocateInfo->memoryTypeIndex;
> -
> mem->map = NULL;
> mem->map_size = 0;
>
> + const VkImportMemoryFdInfoKHX *fd_info =
> + vk_find_struct_const(pAllocateInfo->pNext,
> IMPORT_MEMORY_FD_INFO_KHX);
> +
> + /* The Vulkan spec permits handleType to be 0, in which case the
> struct is
> + * ignored.
> + */
> + if (fd_info && fd_info->handleType) {
> + /* At the moment, we only support the OPAQUE_FD memory type which is
> + * just a GEM buffer.
> + */
> + assert(fd_info->handleType ==
> + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX);
> +
> + uint32_t gem_handle = anv_gem_fd_to_handle(device, fd_info->fd);
> + if (!gem_handle) {
> + result = vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
> + goto fail;
> + }
> +
> + /* From the Vulkan spec:
> + *
> + * "Importing memory from a file descriptor transfers ownership
> of
> + * the file descriptor from the application to the Vulkan
> + * implementation. The application must not perform any
> operations on
> + * the file descriptor after a successful import."
> + *
> + * If the import fails, we leave the file descriptor open.
> + */
> + close(fd_info->fd);
> +
> + anv_bo_init(&mem->bo, gem_handle, pAllocateInfo->allocationSize);
> + } else {
> + /* The kernel is going to give us whole pages anyway */
> + uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize,
> 4096);
> +
> + result = anv_bo_init_new(&mem->bo, device, alloc_size);
> + if (result != VK_SUCCESS)
> + goto fail;
> + }
> +
> *pMem = anv_device_memory_to_handle(mem);
>
> return VK_SUCCESS;
> @@ -1440,6 +1476,42 @@ VkResult anv_AllocateMemory(
> return result;
> }
>
> +VkResult anv_GetMemoryFdKHX(
> + VkDevice device_h,
> + VkDeviceMemory memory_h,
> + VkExternalMemoryHandleTypeFlagBitsKHX handleType,
> + int* pFd)
> +{
> + ANV_FROM_HANDLE(anv_device, dev, device_h);
> + ANV_FROM_HANDLE(anv_device_memory, mem, memory_h);
> +
> + /* We support only one handle type. */
> + assert(handleType == VK_EXTERNAL_MEMORY_HANDLE_
> TYPE_OPAQUE_FD_BIT_KHX);
> +
> + int fd = anv_gem_handle_to_fd(dev, mem->bo.gem_handle);
> + if (fd == -1)
> + return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
> +
> + *pFd = fd;
> +
> + return VK_SUCCESS;
> +}
> +
> +VkResult anv_GetMemoryFdPropertiesKHX(
> + VkDevice device_h,
> + VkExternalMemoryHandleTypeFlagBitsKHX handleType,
> + int fd,
> + VkMemoryFdPropertiesKHX* pMemoryFdProperties)
> +{
> + /* The valid usage section for this function says:
> + *
> + * "handleType must not be one of the handle types defined as
> opaque."
> + *
> + * Since we only handle opaque handles for now, there are no FD
> properties.
> + */
> + return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX;
> +}
> +
> void anv_FreeMemory(
> VkDevice _device,
> VkDeviceMemory _mem,
> diff --git a/src/intel/vulkan/anv_entrypoints_gen.py
> b/src/intel/vulkan/anv_entrypoints_gen.py
> index d8816a581a2..530163c9eff 100644
> --- a/src/intel/vulkan/anv_entrypoints_gen.py
> +++ b/src/intel/vulkan/anv_entrypoints_gen.py
> @@ -39,6 +39,7 @@ supported_extensions = [
> 'VK_KHR_xlib_surface',
> 'VK_KHX_external_memory',
> 'VK_KHX_external_memory_capabilities',
> + 'VK_KHX_external_memory_fd',
> ]
>
> # We generate a static hash table for entry point lookup
> diff --git a/src/intel/vulkan/anv_formats.c b/src/intel/vulkan/anv_
> formats.c
> index f91ba437f1e..196a7516dfa 100644
> --- a/src/intel/vulkan/anv_formats.c
> +++ b/src/intel/vulkan/anv_formats.c
> @@ -656,6 +656,17 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties(
> pImageFormatProperties);
> }
>
> +static const VkExternalMemoryPropertiesKHX prime_fd_props = {
> + /* If we can handle external, then we can both import and export it. */
> + .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHX
> |
> + VK_EXTERNAL_MEMORY_FEATURE_
> IMPORTABLE_BIT_KHX,
> + /* For the moment, let's not support mixing and matching */
> + .exportFromImportedHandleTypes =
> + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX,
> + .compatibleHandleTypes =
> + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX,
> +};
> +
> VkResult anv_GetPhysicalDeviceImageFormatProperties2KHR(
> VkPhysicalDevice physicalDevice,
> const VkPhysicalDeviceImageFormatInfo2KHR* base_info,
> @@ -702,13 +713,23 @@ VkResult anv_GetPhysicalDeviceImageFormatPr
> operties2KHR(
> * present and VkExternalImageFormatPropertiesKHX will be ignored.
> */
> if (external_info->handleType != 0) {
> - /* FINISHME: Support at least one external memory type for images.
> */
> - (void) external_props;
> -
> - result = vk_errorf(VK_ERROR_FORMAT_NOT_SUPPORTED,
> - "unsupported VkExternalMemoryTypeFlagBitsKHX
> 0x%x",
> - external_info->handleType);
> - goto fail;
> + switch (external_info->handleType) {
> + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX:
> + external_props->externalMemoryProperties = prime_fd_props;
> + break;
> + default:
> + /* From the Vulkan 1.0.42 spec:
> + *
> + * If handleType is not compatible with the [parameters]
> specified
> + * in VkPhysicalDeviceImageFormatInfo2KHR, then
> + * vkGetPhysicalDeviceImageFormatProperties2KHR returns
> + * VK_ERROR_FORMAT_NOT_SUPPORTED.
> + */
> + result = vk_errorf(VK_ERROR_FORMAT_NOT_SUPPORTED,
> + "unsupported VkExternalMemoryTypeFlagBitsKHX
> 0x%x",
> + external_info->handleType);
> + goto fail;
> + }
> }
>
> return VK_SUCCESS;
> @@ -757,8 +778,30 @@ void anv_GetPhysicalDeviceExternalBuffe
> rPropertiesKHX(
> const VkPhysicalDeviceExternalBufferInfoKHX* pExternalBufferInfo,
> VkExternalBufferPropertiesKHX*
> pExternalBufferProperties)
> {
> - anv_finishme("Handle external buffers");
> + /* The Vulkan 1.0.42 spec says "handleType must be a valid
> + * VkExternalMemoryHandleTypeFlagBitsKHX value" in
> + * VkPhysicalDeviceExternalBufferInfoKHX. This differs from
> + * VkPhysicalDeviceExternalImageFormatInfoKHX, which surprisingly
> permits
> + * handleType == 0.
>
It's not that surprising. It lets the user just always chain in the struct
but makes it behave as if it weren't there if handleType == 0. For this
entrypoint, they won't be calling it unless they actually want to query
something.
Changes look good to me. I'll pull this patch into my tree.
> + */
> + assert(pExternalBufferInfo->handleType != 0);
> +
> + /* All of the current flags are for sparse which we don't support yet.
> + * Even when we do support it, doing sparse on external memory sounds
> + * sketchy. Also, just disallowing flags is the safe option.
> + */
> + if (pExternalBufferInfo->flags)
> + goto unsupported;
> +
> + switch (pExternalBufferInfo->handleType) {
> + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX:
> + pExternalBufferProperties->externalMemoryProperties =
> prime_fd_props;
> + return;
> + default:
> + goto unsupported;
> + }
>
> + unsupported:
> pExternalBufferProperties->externalMemoryProperties =
> (VkExternalMemoryPropertiesKHX) {0};
> }
> --
> 2.11.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170228/5b780b54/attachment-0001.html>
More information about the mesa-dev
mailing list