Mesa (master): anv: Implement VK_KHX_external_memory_capabilities

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


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

Author: Chad Versace <chadversary at chromium.org>
Date:   Tue Feb 28 10:58:31 2017 -0800

anv: Implement VK_KHX_external_memory_capabilities

This is a complete but trivial implementation. It's trivial becasue We
support no external memory capabilities yet.  Most of the real work in
this commit is in reworking the UUIDs advertised by the driver.

v2 (chadv):
  - Fix chain traversal in vkGetPhysicalDeviceImageFormatProperties2KHR.
    Extract VkPhysicalDeviceExternalImageFormatInfoKHX from the chain of
    input structs, not the chain of output structs.
  - In vkGetPhysicalDeviceImageFormatProperties2KHR, iterate over the
    input chain and the output chain separately. Reduces diff in future
    dma_buf patches.

Co-authored-with: Jason Ekstrand <jason at jlekstrand.net>
Reviewed-by: Chad Versace <chadversary at chromium.org>
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>

---

 src/intel/vulkan/anv_device.c           | 52 ++++++++++++++++++++---
 src/intel/vulkan/anv_entrypoints_gen.py |  1 +
 src/intel/vulkan/anv_formats.c          | 75 +++++++++++++++++++++++++++++----
 src/intel/vulkan/anv_private.h          |  2 +
 4 files changed, 116 insertions(+), 14 deletions(-)

diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 4d0d613d61..df6f7ad763 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -116,6 +116,9 @@ anv_physical_device_init_uuids(struct anv_physical_device *device)
    uint8_t sha1[20];
    STATIC_ASSERT(VK_UUID_SIZE <= sizeof(sha1));
 
+   /* The pipeline cache UUID is used for determining when a pipeline cache is
+    * invalid.  It needs both a driver build and the PCI ID of the device.
+    */
    _mesa_sha1_init(&sha1_ctx);
    _mesa_sha1_update(&sha1_ctx, build_id_data(note), build_id_len);
    _mesa_sha1_update(&sha1_ctx, &device->chipset_id,
@@ -123,6 +126,27 @@ anv_physical_device_init_uuids(struct anv_physical_device *device)
    _mesa_sha1_final(&sha1_ctx, sha1);
    memcpy(device->pipeline_cache_uuid, sha1, VK_UUID_SIZE);
 
+   /* The driver UUID is used for determining sharability of images and memory
+    * between two Vulkan instances in separate processes.  People who want to
+    * share memory need to also check the device UUID (below) so all this
+    * needs to be is the build-id.
+    */
+   memcpy(device->driver_uuid, build_id_data(note), VK_UUID_SIZE);
+
+   /* The device UUID uniquely identifies the given device within the machine.
+    * Since we never have more than one device, this doesn't need to be a real
+    * UUID.  However, on the off-chance that someone tries to use this to
+    * cache pre-tiled images or something of the like, we use the PCI ID and
+    * some bits of ISL info to ensure that this is safe.
+    */
+   _mesa_sha1_init(&sha1_ctx);
+   _mesa_sha1_update(&sha1_ctx, &device->chipset_id,
+                     sizeof(device->chipset_id));
+   _mesa_sha1_update(&sha1_ctx, &device->isl_dev.has_bit6_swizzling,
+                     sizeof(device->isl_dev.has_bit6_swizzling));
+   _mesa_sha1_final(&sha1_ctx, sha1);
+   memcpy(device->device_uuid, sha1, VK_UUID_SIZE);
+
    return VK_SUCCESS;
 }
 
@@ -209,10 +233,6 @@ anv_physical_device_init(struct anv_physical_device *device,
 
    device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC);
 
-   result = anv_physical_device_init_uuids(device);
-   if (result != VK_SUCCESS)
-      goto fail;
-
    bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X);
 
    /* GENs prior to 8 do not support EU/Subslice info */
@@ -252,14 +272,18 @@ anv_physical_device_init(struct anv_physical_device *device,
    device->compiler->shader_debug_log = compiler_debug_log;
    device->compiler->shader_perf_log = compiler_perf_log;
 
+   isl_device_init(&device->isl_dev, &device->info, swizzled);
+
+   result = anv_physical_device_init_uuids(device);
+   if (result != VK_SUCCESS)
+      goto fail;
+
    result = anv_init_wsi(device);
    if (result != VK_SUCCESS) {
       ralloc_free(device->compiler);
       goto fail;
    }
 
-   isl_device_init(&device->isl_dev, &device->info, swizzled);
-
    device->local_fd = fd;
    return VK_SUCCESS;
 
@@ -303,6 +327,10 @@ static const VkExtensionProperties global_extensions[] = {
       .extensionName = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
       .specVersion = 1,
    },
+   {
+      .extensionName = VK_KHX_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
+      .specVersion = 1,
+   },
 };
 
 static const VkExtensionProperties device_extensions[] = {
@@ -729,6 +757,8 @@ void anv_GetPhysicalDeviceProperties2KHR(
     VkPhysicalDevice                            physicalDevice,
     VkPhysicalDeviceProperties2KHR*             pProperties)
 {
+   ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
+
    anv_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
 
    vk_foreach_struct(ext, pProperties->pNext) {
@@ -741,6 +771,16 @@ void anv_GetPhysicalDeviceProperties2KHR(
          break;
       }
 
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHX: {
+         VkPhysicalDeviceIDPropertiesKHX *id_props =
+            (VkPhysicalDeviceIDPropertiesKHX *)ext;
+         memcpy(id_props->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
+         memcpy(id_props->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
+         /* The LUID is for Windows. */
+         id_props->deviceLUIDValid = false;
+         break;
+      }
+
       default:
          anv_debug_ignored_stype(ext->sType);
          break;
diff --git a/src/intel/vulkan/anv_entrypoints_gen.py b/src/intel/vulkan/anv_entrypoints_gen.py
index 1a7d75309c..245d6d024e 100644
--- a/src/intel/vulkan/anv_entrypoints_gen.py
+++ b/src/intel/vulkan/anv_entrypoints_gen.py
@@ -45,6 +45,7 @@ SUPPORTED_EXTENSIONS = [
     'VK_KHR_wayland_surface',
     'VK_KHR_xcb_surface',
     'VK_KHR_xlib_surface',
+    'VK_KHX_external_memory_capabilities',
 ]
 
 # 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 6005791be5..b250931d4b 100644
--- a/src/intel/vulkan/anv_formats.c
+++ b/src/intel/vulkan/anv_formats.c
@@ -658,26 +658,74 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties(
 
 VkResult anv_GetPhysicalDeviceImageFormatProperties2KHR(
     VkPhysicalDevice                            physicalDevice,
-    const VkPhysicalDeviceImageFormatInfo2KHR*  pImageFormatInfo,
-    VkImageFormatProperties2KHR*                pImageFormatProperties)
+    const VkPhysicalDeviceImageFormatInfo2KHR*  base_info,
+    VkImageFormatProperties2KHR*                base_props)
 {
    ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
+   const VkPhysicalDeviceExternalImageFormatInfoKHX *external_info = NULL;
+   VkExternalImageFormatPropertiesKHX *external_props = NULL;
    VkResult result;
 
-   result = anv_get_image_format_properties(physical_device, pImageFormatInfo,
-               &pImageFormatProperties->imageFormatProperties);
+   result = anv_get_image_format_properties(physical_device, base_info,
+               &base_props->imageFormatProperties);
    if (result != VK_SUCCESS)
-      return result;
+      goto fail;
 
-   vk_foreach_struct(ext, pImageFormatProperties->pNext) {
-      switch (ext->sType) {
+   /* Extract input structs */
+   vk_foreach_struct_const(s, base_info->pNext) {
+      switch (s->sType) {
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHX:
+         external_info = (const void *) s;
+         break;
       default:
-         anv_debug_ignored_stype(ext->sType);
+         anv_debug_ignored_stype(s->sType);
+         break;
+      }
+   }
+
+   /* Extract output structs */
+   vk_foreach_struct(s, base_props->pNext) {
+      switch (s->sType) {
+      case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHX:
+         external_props = (void *) s;
+         break;
+      default:
+         anv_debug_ignored_stype(s->sType);
          break;
       }
    }
 
+   /* From the Vulkan 1.0.42 spec:
+    *
+    *    If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2KHR will
+    *    behave as if VkPhysicalDeviceExternalImageFormatInfoKHX was not
+    *    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;
+   }
+
    return VK_SUCCESS;
+
+ fail:
+   if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
+      /* From the Vulkan 1.0.42 spec:
+       *
+       *    If the combination of parameters to
+       *    vkGetPhysicalDeviceImageFormatProperties2KHR is not supported by
+       *    the implementation for use in vkCreateImage, then all members of
+       *    imageFormatProperties will be filled with zero.
+       */
+      base_props->imageFormatProperties = (VkImageFormatProperties) {0};
+   }
+
+   return result;
 }
 
 void anv_GetPhysicalDeviceSparseImageFormatProperties(
@@ -703,3 +751,14 @@ void anv_GetPhysicalDeviceSparseImageFormatProperties2KHR(
    /* Sparse images are not yet supported. */
    *pPropertyCount = 0;
 }
+
+void anv_GetPhysicalDeviceExternalBufferPropertiesKHX(
+    VkPhysicalDevice                             physicalDevice,
+    const VkPhysicalDeviceExternalBufferInfoKHX* pExternalBufferInfo,
+    VkExternalBufferPropertiesKHX*               pExternalBufferProperties)
+{
+   anv_finishme("Handle external buffers");
+
+   pExternalBufferProperties->externalMemoryProperties =
+      (VkExternalMemoryPropertiesKHX) {0};
+}
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 506bab98c4..36a6760615 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -631,6 +631,8 @@ struct anv_physical_device {
     uint32_t                                    subslice_total;
 
     uint8_t                                     pipeline_cache_uuid[VK_UUID_SIZE];
+    uint8_t                                     driver_uuid[VK_UUID_SIZE];
+    uint8_t                                     device_uuid[VK_UUID_SIZE];
 
     struct wsi_device                       wsi_device;
     int                                         local_fd;




More information about the mesa-commit mailing list