<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 28, 2017 at 2:38 PM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">On Tue, Feb 28, 2017 at 10:58 AM, Chad Versace <span dir="ltr"><<a href="mailto:chadversary@chromium.org" target="_blank">chadversary@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This is a complete but trivial implementation. It's trivial becasue We<br>
support no external memory capabilities yet.  Most of the real work in<br>
this commit is in reworking the UUIDs advertised by the driver.<br>
<br>
v2 (chadv):<br>
  - Fix chain traversal in vkGetPhysicalDeviceImageFormat<wbr>Properties2KHR.<br>
    Extract VkPhysicalDeviceExternalImageF<wbr>ormatInfoKHX from the chain of<br>
    input structs, not the chain of output structs.<br>
  - In vkGetPhysicalDeviceImageFormat<wbr>Properties2KHR, iterate over the<br>
    input chain and the output chain separately. Reduces diff in future<br>
    dma_buf patches.<br>
<br>
Co-authored-with: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com" target="_blank">jason.ekstrand@intel.com</a>><br>
---<br>
<br>
On my branch wip/anv-external-memory.<br>
  <a href="http://git.kiwitree.net/cgit/~chadv/mesa/log/?h=wip/anv-external-memory" rel="noreferrer" target="_blank">http://git.kiwitree.net/cgit/~<wbr>chadv/mesa/log/?h=wip/anv-exte<wbr>rnal-memory</a><br>
<br>
 src/intel/vulkan/anv_device.<wbr>c           | 53 ++++++++++++++++++++---<br>
 src/intel/vulkan/anv_entrypoi<wbr>nts_gen.py |  1 +<br>
 src/intel/vulkan/anv_formats.<wbr>c          | 75 +++++++++++++++++++++++++++++-<wbr>---<br>
 src/intel/vulkan/anv_private.<wbr>h          |  2 +<br>
 4 files changed, 117 insertions(+), 14 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_device.<wbr>c b/src/intel/vulkan/anv_device.<wbr>c<br>
index 3609670b348..9ee2e02ed51 100644<br>
--- a/src/intel/vulkan/anv_device.<wbr>c<br>
+++ b/src/intel/vulkan/anv_device.<wbr>c<br>
@@ -74,11 +74,37 @@ anv_physical_device_init_uuids<wbr>(struct anv_physical_device *device)<br>
    if (sha1_ctx == NULL)<br>
       return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
<br>
+   /* The pipeline cache UUID is used for determining when a pipeline cache is<br>
+    * invalid.  It needs both a driver build and the PCI ID of the device.<br>
+    */<br>
    _mesa_sha1_update(sha1_ctx, build_id_data(note), build_id_len);<br>
    _mesa_sha1_update(sha1_ctx, &device->chipset_id, sizeof(device->chipset_id));<br>
    _mesa_sha1_final(sha1_ctx, sha1);<br>
    memcpy(device->pipeline_cache_<wbr>uuid, sha1, VK_UUID_SIZE);<br>
<br>
+   /* The driver UUID is used for determining sharability of images and memory<br>
+    * between two Vulkan instances in separate processes.  People who want to<br>
+    * share memory need to also check the device UUID (below) so all this<br>
+    * needs to be is the build-id.<br>
+    */<br>
+   memcpy(device->driver_uuid, build_id_data(note), VK_UUID_SIZE);<br>
+<br>
+   sha1_ctx = _mesa_sha1_init();<br>
+   if (sha1_ctx == NULL)<br>
+      return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
+<br>
+   /* The device UUID uniquely identifies the given device within the machine.<br>
+    * Since we never have more than one device, this doesn't need to be a real<br>
+    * UUID.  However, on the off-chance that someone tries to use this to<br>
+    * cache pre-tiled images or something of the like, we use the PCI ID and<br>
+    * some bits if ISL info to ensure that this is safe.<br>
+    */<br>
+   _mesa_sha1_update(sha1_ctx, &device->chipset_id, sizeof(device->chipset_id));<br>
+   _mesa_sha1_update(sha1_ctx, &device->isl_dev.has_bit6_swiz<wbr>zling,<br>
+                     sizeof(device->isl_dev.has_bi<wbr>t6_swizzling));<br>
+   _mesa_sha1_final(sha1_ctx, sha1);<br>
+   memcpy(device->device_uuid, sha1, VK_UUID_SIZE);<br>
+<br>
    return VK_SUCCESS;<br>
 }<br>
<br>
@@ -163,10 +189,6 @@ anv_physical_device_init(struc<wbr>t anv_physical_device *device,<br>
       goto fail;<br>
    }<br>
<br>
-   result = anv_physical_device_init_uuids<wbr>(device);<br>
-   if (result != VK_SUCCESS)<br>
-      goto fail;<br>
-<br>
    bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X);<br>
<br>
    /* GENs prior to 8 do not support EU/Subslice info */<br>
@@ -206,14 +228,18 @@ anv_physical_device_init(struc<wbr>t anv_physical_device *device,<br>
    device->compiler->shader_debug<wbr>_log = compiler_debug_log;<br>
    device->compiler->shader_perf_<wbr>log = compiler_perf_log;<br>
<br>
+   isl_device_init(&device->isl_<wbr>dev, &device->info, swizzled);<br>
+<br>
+   result = anv_physical_device_init_uuids<wbr>(device);<br>
+   if (result != VK_SUCCESS)<br>
+      goto fail;<br>
+<br>
    result = anv_init_wsi(device);<br>
    if (result != VK_SUCCESS) {<br>
       ralloc_free(device->compiler)<wbr>;<br>
       goto fail;<br>
    }<br>
<br>
-   isl_device_init(&device->isl_<wbr>dev, &device->info, swizzled);<br>
-<br>
    device->local_fd = fd;<br>
    return VK_SUCCESS;<br>
<br>
@@ -257,6 +283,10 @@ static const VkExtensionProperties global_extensions[] = {<br>
       .extensionName = VK_KHR_GET_PHYSICAL_DEVICE_PRO<wbr>PERTIES_2_EXTENSION_NAME,<br>
       .specVersion = 1,<br>
    },<br>
+   {<br>
+      .extensionName = VK_KHX_EXTERNAL_MEMORY_CAPABIL<wbr>ITIES_EXTENSION_NAME,<br>
+      .specVersion = 1,<br>
+   },<br>
 };<br>
<br>
 static const VkExtensionProperties device_extensions[] = {<br>
@@ -668,10 +698,21 @@ void anv_GetPhysicalDevicePropertie<wbr>s2KHR(<br>
     VkPhysicalDevice                            physicalDevice,<br>
     <wbr>VkPhysicalDeviceProperties2KHR<wbr>*             pProperties)<br>
 {<br>
+   ANV_FROM_HANDLE(anv_physical_<wbr>device, pdevice, physicalDevice);<br>
+<br>
    anv_GetPhysicalDevicePropertie<wbr>s(physicalDevice, &pProperties->properties);<br>
<br>
    vk_foreach_struct(ext, pProperties->pNext) {<br>
       switch (ext->sType) {<br>
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEV<wbr>ICE_ID_PROPERTIES_KHX: {<br>
+         <wbr>VkPhysicalDeviceIDPropertiesKH<wbr>X *id_props =<br>
+            (VkPhysicalDeviceIDPropertiesK<wbr>HX *)ext;<br>
+         memcpy(id_props->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);<br>
+         memcpy(id_props->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);<br>
+         /* The LUID is for Windows. */<br>
+         id_props->deviceLUIDValid = false;<br>
+         break;<br>
+      }<br>
       default:<br>
          anv_debug_ignored_stype(ext->s<wbr>Type);<br>
          break;<br>
diff --git a/src/intel/vulkan/anv_entrypo<wbr>ints_gen.py b/src/intel/vulkan/anv_entrypo<wbr>ints_gen.py<br>
index 93511ec95e4..6cf9f5f4ddf 100644<br>
--- a/src/intel/vulkan/anv_entrypo<wbr>ints_gen.py<br>
+++ b/src/intel/vulkan/anv_entrypo<wbr>ints_gen.py<br>
@@ -37,6 +37,7 @@ supported_extensions = [<br>
    'VK_KHR_wayland_surface',<br>
    'VK_KHR_xcb_surface',<br>
    'VK_KHR_xlib_surface',<br>
+   'VK_KHX_external_memory_capab<wbr>ilities',<br>
 ]<br>
<br>
 # We generate a static hash table for entry point lookup<br>
diff --git a/src/intel/vulkan/anv_formats<wbr>.c b/src/intel/vulkan/anv_formats<wbr>.c<br>
index 6005791be5d..f91ba437f1e 100644<br>
--- a/src/intel/vulkan/anv_formats<wbr>.c<br>
+++ b/src/intel/vulkan/anv_formats<wbr>.c<br>
@@ -658,26 +658,74 @@ VkResult anv_GetPhysicalDeviceImageForm<wbr>atProperties(<br>
<br>
 VkResult anv_GetPhysicalDeviceImageForm<wbr>atProperties2KHR(<br>
     VkPhysicalDevice                            physicalDevice,<br>
-    const VkPhysicalDeviceImageFormatInf<wbr>o2KHR*  pImageFormatInfo,<br>
-    VkImageFormatProperties2KHR*                pImageFormatProperties)<br>
+    const VkPhysicalDeviceImageFormatInf<wbr>o2KHR*  base_info,<br>
+    VkImageFormatProperties2KHR*                base_props)<br>
 {<br>
    ANV_FROM_HANDLE(anv_physical_d<wbr>evice, physical_device, physicalDevice);<br>
+   const VkPhysicalDeviceExternalImageF<wbr>ormatInfoKHX *external_info = NULL;<br>
+   <wbr>VkExternalImageFormatPropertie<wbr>sKHX *external_props = NULL;<br>
    VkResult result;<br>
<br>
-   result = anv_get_image_format_propertie<wbr>s(physical_device, pImageFormatInfo,<br>
-               &pImageFormatProperties->imag<wbr>eFormatProperties);<br>
+   result = anv_get_image_format_propertie<wbr>s(physical_device, base_info,<br>
+               &base_props->imageFormatPrope<wbr>rties);<br>
    if (result != VK_SUCCESS)<br>
-      return result;<br>
+      goto fail;<br>
<br>
-   vk_foreach_struct(ext, pImageFormatProperties->pNext) {<br>
-      switch (ext->sType) {<br>
+   /* Extract input structs */<br>
+   vk_foreach_struct_const(s, base_info->pNext) {<br>
+      switch (s->sType) {<br>
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEV<wbr>ICE_EXTERNAL_IMAGE_FORMAT_INFO<wbr>_KHX:<br>
+         external_info = (const void *) s;<br>
+         break;<br>
       default:<br>
-         anv_debug_ignored_stype(ext-><wbr>sType);<br>
+         anv_debug_ignored_stype(s->sT<wbr>ype);<br>
+         break;<br>
+      }<br>
+   }<br>
+<br>
+   /* Extract output structs */<br>
+   vk_foreach_struct(s, base_props->pNext) {<br>
+      switch (s->sType) {<br>
+      case VK_STRUCTURE_TYPE_EXTERNAL_IMA<wbr>GE_FORMAT_PROPERTIES_KHX:<br>
+         external_props = (void *) s;<br>
+         break;<br>
+      default:<br>
+         anv_debug_ignored_stype(s->sT<wbr>ype);<br></blockquote><div><br></div></div></div><div>We have a find_struct helper precisely for doing this.  I guess this is marginally more efficient if we have a bunch of them but it's kind-of ugly. :-(  I'll see your dma-buf patches before I cast final judgment though.<br></div></div></div></div></blockquote><div><br></div><div>I rescind my comment.  Yours is way cleaner than mine.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div></div><div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
          break;<br>
       }<br>
    }<br>
<br>
+   /* From the Vulkan 1.0.42 spec:<br>
+    *<br>
+    *    If handleType is 0, vkGetPhysicalDeviceImageFormat<wbr>Properties2KHR will<br>
+    *    behave as if VkPhysicalDeviceExternalImageF<wbr>ormatInfoKHX was not<br>
+    *    present and VkExternalImageFormatPropertie<wbr>sKHX will be ignored.<br>
+    */<br>
+   if (external_info->handleType != 0) {<br>
+      /* FINISHME: Support at least one external memory type for images. */<br>
+      (void) external_props;<br>
+<br>
+      result = vk_errorf(VK_ERROR_FORMAT_NOT_<wbr>SUPPORTED,<br>
+                         "unsupported VkExternalMemoryTypeFlagBitsKH<wbr>X 0x%x",<br>
+                         external_info->handleType);<br>
+      goto fail;<br>
+   }<br>
+<br>
    return VK_SUCCESS;<br>
+<br>
+ fail:<br>
+   if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {<br>
+      /* From the Vulkan 1.0.42 spec:<br>
+       *<br>
+       *    If the combination of parameters to<br>
+       *    vkGetPhysicalDeviceImageFormat<wbr>Properties2KHR is not supported by<br>
+       *    the implementation for use in vkCreateImage, then all members of<br>
+       *    imageFormatProperties will be filled with zero.<br>
+       */<br>
+      base_props->imageFormatPropert<wbr>ies = (VkImageFormatProperties) {0};<br>
+   }<br>
+<br>
+   return result;<br>
 }<br>
<br>
 void anv_GetPhysicalDeviceSparseIma<wbr>geFormatProperties(<br>
@@ -703,3 +751,14 @@ void anv_GetPhysicalDeviceSparseIma<wbr>geFormatProperties2KHR(<br>
    /* Sparse images are not yet supported. */<br>
    *pPropertyCount = 0;<br>
 }<br>
+<br>
+void anv_GetPhysicalDeviceExternalB<wbr>ufferPropertiesKHX(<br>
+    VkPhysicalDevice                             physicalDevice,<br>
+    const VkPhysicalDeviceExternalBuffer<wbr>InfoKHX* pExternalBufferInfo,<br>
+    VkExternalBufferPropertiesKHX*<wbr>               pExternalBufferProperties)<br>
+{<br>
+   anv_finishme("Handle external buffers");<br>
+<br>
+   pExternalBufferProperties->ex<wbr>ternalMemoryProperties =<br>
+      (VkExternalMemoryPropertiesKHX<wbr>) {0};<br>
+}<br>
diff --git a/src/intel/vulkan/anv_private<wbr>.h b/src/intel/vulkan/anv_private<wbr>.h<br>
index a4fd707fe9e..816ee8a509b 100644<br>
--- a/src/intel/vulkan/anv_private<wbr>.h<br>
+++ b/src/intel/vulkan/anv_private<wbr>.h<br>
@@ -531,6 +531,8 @@ struct anv_physical_device {<br>
     uint32_t                                    subslice_total;<br>
<br>
     uint8_t                                     pipeline_cache_uuid[VK_UUID_S<wbr>IZE];<br>
+    uint8_t                                     driver_uuid[VK_UUID_SIZE];<br>
+    uint8_t                                     device_uuid[VK_UUID_SIZE];<br>
<br>
     struct wsi_device                       wsi_device;<br>
     int                                         local_fd;<br>
<span class="m_8971622146258699429HOEnZb"><font color="#888888">--<br>
2.11.1<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>