Mesa (master): anv: Implement VK_KHX_external_memory_fd

Jason Ekstrand jekstrand at kemper.freedesktop.org
Fri Apr 28 03:53:03 UTC 2017


Module: Mesa
Branch: master
Commit: 9bd1f0348734e5dbbdc84e96ac1f11836427ed7c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9bd1f0348734e5dbbdc84e96ac1f11836427ed7c

Author: Jason Ekstrand <jason.ekstrand at intel.com>
Date:   Tue Feb 28 10:58:40 2017 -0800

anv: Implement VK_KHX_external_memory_fd

This commit just exposes the memory handle type.  There's interesting we
need to do here for images.  So long as the user doesn't set any crazy
environment variables such as INTEL_DEBUG=nohiz, all of the compression
formats etc. should "just work" at least for opaque handle types.

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>
Reviewed-by: Chad Versace <chadversary at chromium.org>

---

 src/intel/vulkan/anv_device.c           | 71 ++++++++++++++++++++++++++++-----
 src/intel/vulkan/anv_entrypoints_gen.py |  1 +
 src/intel/vulkan/anv_formats.c          | 59 +++++++++++++++++++++++----
 3 files changed, 113 insertions(+), 18 deletions(-)

diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index c8621eec41..62974f19d8 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -366,6 +366,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 *
@@ -1600,7 +1604,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);
 
@@ -1638,19 +1642,36 @@ 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_cache_alloc(device, &device->bo_cache,
-                               alloc_size, &mem->bo);
-   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);
+
+      result = anv_bo_cache_import(device, &device->bo_cache,
+                                   fd_info->fd, pAllocateInfo->allocationSize,
+                                   &mem->bo);
+      if (result != VK_SUCCESS)
+         goto fail;
+   } else {
+      result = anv_bo_cache_alloc(device, &device->bo_cache,
+                                  pAllocateInfo->allocationSize,
+                                  &mem->bo);
+      if (result != VK_SUCCESS)
+         goto fail;
+   }
+
    *pMem = anv_device_memory_to_handle(mem);
 
    return VK_SUCCESS;
@@ -1661,6 +1682,36 @@ 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);
+
+   return anv_bo_cache_export(dev, &dev->bo_cache, mem->bo, pFd);
+}
+
+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 400b56766c..b4395c03b4 100644
--- a/src/intel/vulkan/anv_entrypoints_gen.py
+++ b/src/intel/vulkan/anv_entrypoints_gen.py
@@ -47,6 +47,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 b250931d4b..4c930eda1d 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_GetPhysicalDeviceImageFormatProperties2KHR(
     *    present and VkExternalImageFormatPropertiesKHX will be ignored.
     */
    if (external_info && 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_GetPhysicalDeviceExternalBufferPropertiesKHX(
     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.
+    */
+   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};
 }




More information about the mesa-commit mailing list