[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