<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Mar 6, 2017 at 12:40 PM, 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">For now, we support dma_buf images for only a single format,<br>
VK_FORMAT_R8G8B8A8_UNORM.  And the image must be a "simple" image: 2D,<br>
single-sample, non-mipmappped, non-array, non-cube.<br>
---<br>
 src/intel/vulkan/anv_device.c           |   4 +<br>
 src/intel/vulkan/anv_<wbr>entrypoints_gen.py |   1 +<br>
 src/intel/vulkan/anv_formats.c          | 147 ++++++++++++++++++++++++++-<br>
 src/intel/vulkan/anv_image.c            | 173 ++++++++++++++++++++++++++++++<wbr>--<br>
 src/intel/vulkan/anv_private.h          |   6 ++<br>
 5 files changed, 320 insertions(+), 11 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_device.<wbr>c b/src/intel/vulkan/anv_device.<wbr>c<br>
index cc5f57b0f86..b2dce7695fc 100644<br>
--- a/src/intel/vulkan/anv_device.<wbr>c<br>
+++ b/src/intel/vulkan/anv_device.<wbr>c<br>
@@ -326,6 +326,10 @@ static const VkExtensionProperties device_extensions[] = {<br>
       .extensionName = VK_MESAX_EXTERNAL_MEMORY_DMA_<wbr>BUF_EXTENSION_NAME,<br>
       .specVersion = 0,<br>
    },<br>
+   {<br>
+      .extensionName = VK_MESAX_EXTERNAL_IMAGE_DMA_<wbr>BUF_EXTENSION_NAME,<br>
+      .specVersion = 0,<br>
+   },<br>
 };<br>
<br>
 static void *<br>
diff --git a/src/intel/vulkan/anv_<wbr>entrypoints_gen.py b/src/intel/vulkan/anv_<wbr>entrypoints_gen.py<br>
index 7ba070be5e4..b49a9c54e27 100644<br>
--- a/src/intel/vulkan/anv_<wbr>entrypoints_gen.py<br>
+++ b/src/intel/vulkan/anv_<wbr>entrypoints_gen.py<br>
@@ -43,6 +43,7 @@ supported_extensions = [<br>
    'VK_KHX_external_memory',<br>
    'VK_KHX_external_memory_<wbr>capabilities',<br>
    'VK_KHX_external_memory_fd',<br>
+   'VK_MESAX_external_image_dma_<wbr>buf',<br>
    'VK_MESAX_external_memory_dma_<wbr>buf',<br>
 ]<br>
<br>
diff --git a/src/intel/vulkan/anv_<wbr>formats.c b/src/intel/vulkan/anv_<wbr>formats.c<br>
index cbbbd0bc0d8..98a321a0a82 100644<br>
--- a/src/intel/vulkan/anv_<wbr>formats.c<br>
+++ b/src/intel/vulkan/anv_<wbr>formats.c<br>
@@ -471,16 +471,64 @@ void anv_<wbr>GetPhysicalDeviceFormatPropert<wbr>ies(<br>
                pFormatProperties);<br>
 }<br>
<br>
+static void<br>
+get_dma_buf_format_props(<wbr>struct anv_physical_device *phys_dev,<br>
+                         VkFormat vk_format,<br>
+                         VkDmaBufFormatPropertiesMESAX *props)<br>
+{<br>
+   struct anv_format anv_format = anv_formats[vk_format];<br>
+   ANV_OUTARRAY_MAKE(mod_props, props->pModifierProperties,<br>
+                     &props->modifierCount);<br>
+<br>
+   VkFormatFeatureFlags image_features = 0;<br>
+   if (vk_format == VK_FORMAT_R8G8B8A8_UNORM) {<br>
+      /* FINISHME: Support more formats for dma_buf images. */<br>
+<br>
+      /* For dma_buf images, we must use the exact format provided by the<br>
+       * user.  We must not adjust the format, as we do for non-external<br>
+       * images, with swizzles and other tricks. In other words, the image's<br>
+       * "base" format and "adjusted" format must be the same.<br>
+       */<br></blockquote><div><br></div><div>Why?  This assertion makes me think you have something backwards.  The reason why we do swizzles and things is precicely to ensure that, regardless of wether or not the hardware actually supports the VkFormat natively, the underlying bits correctly correspond to the Vulkan format.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      image_features = get_image_format_properties(&<wbr>phys_dev->info,<br>
+                        /*base format*/ anv_format.isl_format,<br>
+                        /*adjusted format*/ anv_format);<br>
+   }<br>
+<br>
+   if (image_features == 0)<br>
+      return;<br>
+<br>
+   /* Return DRM format modifiers in order of decreasing preference. */<br>
+   anv_outarray_append(&mod_<wbr>props, p) {<br>
+      p->drmFormatModifier = I915_FORMAT_MOD_Y_TILED;<br>
+      p->imageFeatures = image_features;<br>
+   }<br>
+<br>
+   anv_outarray_append(&mod_<wbr>props, p) {<br>
+      p->drmFormatModifier = I915_FORMAT_MOD_X_TILED;<br>
+      p->imageFeatures = image_features;<br>
+   }<br>
+<br>
+   anv_outarray_append(&mod_<wbr>props, p) {<br>
+      p->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;<br>
+      p->imageFeatures = image_features;<br>
+   }<br></blockquote><div><br></div><div>We should get CCS hooked up soonish as well.  But X, Y, and linear first...<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+}<br>
+<br>
 void anv_<wbr>GetPhysicalDeviceFormatPropert<wbr>ies2KHR(<br>
     VkPhysicalDevice                            physicalDevice,<br>
     VkFormat                                    format,<br>
     VkFormatProperties2KHR*                     pFormatProperties)<br>
 {<br>
+   ANV_FROM_HANDLE(anv_physical_<wbr>device, phys_dev, physicalDevice);<br>
+<br>
    anv_<wbr>GetPhysicalDeviceFormatPropert<wbr>ies(physicalDevice, format,<br>
                                          &pFormatProperties-><wbr>formatProperties);<br>
<br>
    vk_foreach_struct(ext, pFormatProperties->pNext) {<br>
       switch (ext->sType) {<br>
+      case VK_STRUCTURE_TYPE_DMA_BUF_<wbr>FORMAT_PROPERTIES_MESAX:<br>
+         get_dma_buf_format_props(phys_<wbr>dev, format, (VkDmaBufFormatPropertiesMESAX *) ext);<br>
+         break;<br>
       default:<br>
          anv_debug_ignored_stype(ext-><wbr>sType);<br>
          break;<br>
@@ -685,6 +733,94 @@ static const VkExternalMemoryPropertiesKHX dma_buf_mem_props = {<br>
       VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_DMA_BUF_BIT_MESAX,<br>
 };<br>
<br>
+static VkResult<br>
+get_dma_buf_image_format_<wbr>props(struct anv_physical_device *phys_dev,<br>
+                               const VkPhysicalDeviceImageFormatInf<wbr>o2KHR *base_info,<br>
+                               VkImageFormatProperties2KHR *base_props,<br>
+                               VkExternalImageFormatPropertie<wbr>sKHX *external_props,<br>
+                               VkDmaBufImageFormatPropertiesM<wbr>ESAX *dma_buf_props)<br>
+{<br>
+   /* We reject vkGetPhysicalDeviceImageFormat<wbr>Properties2KHR() on the<br>
+    * DMA_BUF_BIT unless the user adds VkDmaBufImageFormatPropertiesM<wbr>ESAX to<br>
+    * the output chain. The spec permits this behavior but does not require<br>
+    * it.<br>
+    */<br>
+   if (dma_buf_props == NULL) {<br>
+      return vk_errorf(VK_ERROR_FORMAT_NOT_<wbr>SUPPORTED,<br>
+                       "dma_buf images require VkDmaBufImageFormatPropertiesM<wbr>ESAX");<br>
+   }<br>
+<br>
+   ANV_OUTARRAY_MAKE(mod_props, dma_buf_props-><wbr>pModifierProperties,<br>
+                     &dma_buf_props->modifierCount)<wbr>;<br>
+<br>
+   if (base_info->type != VK_IMAGE_TYPE_2D) {<br>
+      return vk_errorf(VK_ERROR_FORMAT_NOT_<wbr>SUPPORTED,<br>
+                       "dma_buf images require VK_IMAGE_TYPE_2D");<br>
+   }<br>
+<br>
+   if (base_info->flags != 0) {<br>
+      return vk_errorf(VK_ERROR_FORMAT_NOT_<wbr>SUPPORTED,<br>
+                       "dma_buf images support no VkImageCreateFlags");<br>
+   }<br>
+<br>
+   if (base_info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_<wbr>ATTACHMENT_BIT) {<br>
+      return vk_errorf(VK_ERROR_FORMAT_NOT_<wbr>SUPPORTED,<br>
+                       "dma_buf images do not support "<br>
+                       "VK_IMAGE_USAGE_DEPTH_STENCIL_<wbr>ATTACHMENT_BIT");<br>
+   }<br>
+<br>
+   if (base_info->format != VK_FORMAT_R8G8B8A8_UNORM) {<br>
+      /* FINISHME: Support more formats for dma_buf images. */<br>
+      return vk_errorf(VK_ERROR_FORMAT_NOT_<wbr>SUPPORTED,<br>
+                       "dma_buf images do not support VkFormat 0x%x",<br>
+                       base_info->format);<br></blockquote><div><br></div><div>We should get rid of the string in the table and use dylan's new _mesa_VkFormat_to_str helper instead.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+   }<br>
+<br>
+   /* We restrict some properties on dma_buf images. */<br>
+   base_props-><wbr>imageFormatProperties.<wbr>maxMipLevels = 1;<br>
+   base_props-><wbr>imageFormatProperties.<wbr>maxArrayLayers = 1;<br>
+   base_props-><wbr>imageFormatProperties.<wbr>sampleCounts = VK_SAMPLE_COUNT_1_BIT;<br>
+<br>
+   /* Return DRM format modifiers in order of decreasing preference. */<br>
+   if (base_info->tiling == VK_IMAGE_TILING_OPTIMAL) {<br>
+      anv_outarray_append(&mod_<wbr>props, p) {<br>
+         p->drmFormatModifier = I915_FORMAT_MOD_Y_TILED;<br>
+         p->maxRowPitch = 0;<br>
+         p->rowPitchAlignment = 0;<br>
+         p->imageFormatProperties = base_props-><wbr>imageFormatProperties;<br>
+      }<br>
+<br>
+      anv_outarray_append(&mod_<wbr>props, p) {<br>
+         p->drmFormatModifier = I915_FORMAT_MOD_X_TILED;<br>
+         p->maxRowPitch = 0;<br>
+         p->rowPitchAlignment = 0;<br>
+         p->imageFormatProperties = base_props-><wbr>imageFormatProperties;<br>
+      }<br>
+   }<br>
+<br>
+   anv_outarray_append(&mod_<wbr>props, p) {<br>
+      p->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;<br>
+      p->maxRowPitch = 1 << 18; /* See RENDER_SURFACE_STATE::<wbr>SurfacePitch */<br>
+      p->rowPitchAlignment = 1;<br></blockquote><div><br></div><div>Uh... no.  rowPitchAlignment needs to be at least texel size or we can't render to it.  And 2xTexelSize for YUV.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      p->imageFormatProperties = base_props-><wbr>imageFormatProperties;<br>
+   }<br>
+<br>
+   /* Clobber the base properties.<br>
+    *<br>
+    * TODO(chadv): Explain why the interaction between<br>
+    * VK_MESAX_external_image_dma_<wbr>buf and VK_KHX_external_memory_<wbr>capabilities<br>
+    * requires us to zero the base properties.<br>
+    */<br>
+   base_props-><wbr>imageFormatProperties = (VkImageFormatProperties) {0};<br></blockquote><div><br></div><div>Why can't the base props just be the properties as if there were no modifiers?  That seems like reasonable behavior to me.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   external_props-><wbr>externalMemoryProperties = dma_buf_mem_props;<br>
+<br>
+   if (anv_outarray_is_incomple(&<wbr>mod_props))<br>
+      return VK_INCOMPLETE;<br>
+<br>
+   return VK_SUCCESS;<br>
+}<br>
+<br>
 VkResult anv_<wbr>GetPhysicalDeviceImageFormatPr<wbr>operties2KHR(<br>
     VkPhysicalDevice                            physicalDevice,<br>
     const VkPhysicalDeviceImageFormatInf<wbr>o2KHR*  base_info,<br>
@@ -693,6 +829,7 @@ VkResult anv_<wbr>GetPhysicalDeviceImageFormatPr<wbr>operties2KHR(<br>
    ANV_FROM_HANDLE(anv_physical_<wbr>device, physical_device, physicalDevice);<br>
    const VkPhysicalDeviceExternalImageF<wbr>ormatInfoKHX *external_info = NULL;<br>
    VkExternalImageFormatPropertie<wbr>sKHX *external_props = NULL;<br>
+   VkDmaBufImageFormatPropertiesM<wbr>ESAX *dma_buf_props = NULL;<br>
    VkResult result;<br>
<br>
    result = anv_get_image_format_<wbr>properties(physical_device, base_info,<br>
@@ -718,6 +855,9 @@ VkResult anv_<wbr>GetPhysicalDeviceImageFormatPr<wbr>operties2KHR(<br>
       case VK_STRUCTURE_TYPE_EXTERNAL_<wbr>IMAGE_FORMAT_PROPERTIES_KHX:<br>
          external_props = (void *) s;<br>
          break;<br>
+      case VK_STRUCTURE_TYPE_DMA_BUF_<wbr>IMAGE_FORMAT_PROPERTIES_MESAX:<br>
+         dma_buf_props = (void *) s;<br>
+         break;<br>
       default:<br>
          anv_debug_ignored_stype(s-><wbr>sType);<br>
          break;<br>
@@ -736,7 +876,12 @@ VkResult anv_<wbr>GetPhysicalDeviceImageFormatPr<wbr>operties2KHR(<br>
          external_props-><wbr>externalMemoryProperties = opaque_fd_props;<br>
          break;<br>
       case VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_DMA_BUF_BIT_MESAX:<br>
-         /* Fallthrough. We support dma_buf for VkBuffer but not yet VkImage. */<br>
+         result = get_dma_buf_image_format_<wbr>props(physical_device, base_info,<br>
+                                                 base_props, external_props,<br>
+                                                 dma_buf_props);<br>
+         if (result != VK_SUCCESS)<br>
+            goto fail;<br>
+         break;<br>
       default:<br>
          /* From the Vulkan 1.0.42 spec:<br>
           *<br>
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c<br>
index bca56a417aa..60b33fba2ae 100644<br>
--- a/src/intel/vulkan/anv_image.c<br>
+++ b/src/intel/vulkan/anv_image.c<br>
@@ -106,11 +106,23 @@ get_surface(struct anv_image *image, VkImageAspectFlags aspect)<br>
 }<br>
<br>
 static isl_tiling_flags_t<br>
-choose_isl_tiling_flags(const struct anv_image_create_info *anv_info)<br>
+choose_isl_tiling_flags(const struct anv_image_create_info *anv_info,<br>
+                        const VkImportImageDmaBufInfoMESAX *import_dma_buf_info,<br>
+                        const VkExportImageDmaBufInfoMESAX *export_dma_buf_info)<br>
 {<br>
    isl_tiling_flags_t flags;<br>
<br>
-   if (anv_info->vk_info->tiling == VK_IMAGE_TILING_LINEAR) {<br>
+   if (import_dma_buf_info) {<br>
+      uint64_t mod = import_dma_buf_info-><wbr>drmFormatModifier;<br>
+      flags = 1 << isl_tiling_from_drm_format_<wbr>mod(mod);<br>
+   } else if (export_dma_buf_info) {<br>
+      flags = 0;<br>
+<br>
+      for (uint32_t i = 0; i < export_dma_buf_info-><wbr>drmFormatModifierCount; ++i) {<br>
+         uint64_t mod = export_dma_buf_info-><wbr>pDrmFormatModifiers[i];<br>
+         flags |= 1 << isl_tiling_from_drm_format_<wbr>mod(mod);<br>
+      }<br>
+   } else if (anv_info->vk_info->tiling == VK_IMAGE_TILING_LINEAR) {<br>
       flags = ISL_TILING_LINEAR_BIT;<br>
    } else {<br>
       flags = ISL_TILING_ANY_MASK;<br>
@@ -119,9 +131,49 @@ choose_isl_tiling_flags(const struct anv_image_create_info *anv_info)<br>
    if (anv_info->isl_tiling_flags)<br>
       flags &= anv_info->isl_tiling_flags;<br>
<br>
+   assert(flags != 0);<br>
+<br>
    return flags;<br>
 }<br>
<br>
+static enum isl_format<br>
+choose_isl_format(const struct anv_device *dev,<br>
+                  const VkImageCreateInfo *base_info,<br>
+                  VkImageAspectFlagBits aspect,<br>
+                  VkExternalMemoryHandleTypeFlag<wbr>sKHX handle_types)<br>
+{<br>
+   /* We don't yet support images compatible with multiple handle types<br>
+    * because our choice of format depends on the handle type.  For<br>
+    * non-external images and opaque fd images, we choose an "adjusted"<br>
+    * format. For dma_buf images, we must use the exact format provided by the<br>
+    * user.<br>
+    */<br></blockquote><div><br></div><div>As I said above, I'm fairly sure this is false.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+   assert(__builtin_popcount(<wbr>handle_types) <= 1);<br>
+<br>
+   if (handle_types & VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_DMA_BUF_BIT_MESAX) {<br>
+      return anv_get_raw_isl_format(&dev-><wbr>info, base_info->format);<br>
+   } else {<br>
+      return anv_get_isl_format(&dev->info, base_info->format, aspect,<br>
+                                base_info->tiling);<br>
+   }<br>
+}<br>
+<br>
+static uint32_t<br>
+choose_row_pitch(const struct anv_image_create_info *anv_info,<br>
+                 const VkImportImageDmaBufPlaneInfoME<wbr>SAX *plane_info)<br>
+{<br>
+   if (anv_info->stride != 0)<br>
+      return anv_info->stride;<br>
+<br>
+   if (plane_info) {<br>
+      assert(plane_info->rowPitch > 0);<br>
+      return plane_info->rowPitch;<br>
+   }<br>
+<br>
+   /* Let isl choose the pitch. */<br>
+   return 0;<br>
+}<br>
+<br>
 static void<br>
 set_min_surface_offset(const struct anv_image *image, struct anv_surface *surf)<br>
 {<br>
@@ -231,8 +283,24 @@ static void<br>
 make_aux_surface_maybe(const struct anv_device *dev,<br>
                        const VkImageCreateInfo *base_info,<br>
                        VkImageAspectFlags aspect,<br>
+                       VkExternalMemoryHandleTypeFlag<wbr>sKHX handle_types,<br>
                        struct anv_image *image)<br>
 {<br>
+   /* We don't yet support images compatible with multiple handle types<br>
+    * because our choice of aux surface depends on the handle type. For<br>
+    * non-external images and opaque fd images, we choose the optimal aux<br>
+    * surface. For dma_buf images, we must use the aux surface specified by<br>
+    * the user.<br>
+    */<br>
+   assert(__builtin_popcount(<wbr>handle_types) <= 1);<br></blockquote><div><br></div><div>I'm not sure how I feel about tying modifiers with handle types.  In my brain, the DMA_BUF handle type is just a more specific handle type than OPAQUE_FD where it's letting the client know, "No, really, this is a dma-buf".  I don't see why you couldn't use the regular Vulkan image sharing stuff (check UUIDs and start creating images) on top of dma-buf memory.  Maybe modifiers should *require* dma-buf memory, but I don't see why it dma-buf memory needs to require modifiers.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+   if (handle_types & VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_DMA_BUF_BIT_MESAX) {<br>
+      /* As of 2017-02-25, drm_fourcc.h still does not define a format modifier<br>
+       * for any aux surface.<br>
+       */<br>
+      return;<br>
+   }<br>
+<br>
    if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {<br>
       make_hiz_surface_maybe(dev, base_info, image);<br>
    } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && base_info->samples == 1) {<br>
@@ -251,7 +319,10 @@ make_aux_surface_maybe(const struct anv_device *dev,<br>
 static void<br>
 make_main_surface(const struct anv_device *dev,<br>
                   const struct anv_image_create_info *anv_info,<br>
+                  const VkImportImageDmaBufInfoMESAX *import_dma_buf_info,<br>
+                  const VkExportImageDmaBufInfoMESAX *export_dma_buf_info,<br>
                   VkImageAspectFlags aspect,<br>
+                  VkExternalMemoryHandleTypeFlag<wbr>sKHX handle_types,<br>
                   struct anv_image *image)<br>
 {<br>
    const VkImageCreateInfo *base_info = anv_info->vk_info;<br>
@@ -263,14 +334,21 @@ make_main_surface(const struct anv_device *dev,<br>
       [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D,<br>
    };<br>
<br>
-   const isl_tiling_flags_t tiling_flags = choose_isl_tiling_flags(anv_<wbr>info);<br>
+   const VkImportImageDmaBufPlaneInfoME<wbr>SAX *plane_info = NULL;<br>
+   if (import_dma_buf_info)<br>
+      plane_info = &import_dma_buf_info->pPlanes[<wbr>0];<br>
+<br>
+   const isl_tiling_flags_t tiling_flags =<br>
+      choose_isl_tiling_flags(anv_<wbr>info, import_dma_buf_info, export_dma_buf_info);<br>
+   const uint32_t row_pitch = choose_row_pitch(anv_info, plane_info);<br></blockquote><div><br></div><div>I'm not sure how I feel about the way you're tying this all into ISL.  Another option would be to add isl_surface_init_for_modifier that takes a subset of the parameters (everything's 2d for instance) and keep this stuff internal to ISL.  I haven't spent a long time thinking through it though so take this very much as a first impression.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
    struct anv_surface *anv_surf = get_surface(image, aspect);<br>
<br>
    image->extent = anv_sanitize_image_extent(<wbr>base_info->imageType,<br>
                                              base_info->extent);<br>
<br>
-   enum isl_format format = anv_get_isl_format(&dev->info, base_info->format,<br>
-                                               aspect, base_info->tiling);<br>
+   const enum isl_format format =<br>
+      choose_isl_format(dev, base_info, aspect, handle_types);<br>
    assert(format != ISL_FORMAT_UNSUPPORTED);<br>
<br>
    ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,<br>
@@ -283,7 +361,7 @@ make_main_surface(const struct anv_device *dev,<br>
       .array_len = base_info->arrayLayers,<br>
       .samples = base_info->samples,<br>
       .min_alignment = 0,<br>
-      .row_pitch = anv_info->stride,<br>
+      .row_pitch = row_pitch,<br>
       .usage = choose_isl_surf_usage(image-><wbr>usage, aspect),<br>
       .tiling_flags = tiling_flags);<br>
<br>
@@ -292,7 +370,12 @@ make_main_surface(const struct anv_device *dev,<br>
     */<br>
    assert(ok);<br>
<br>
-   set_min_surface_offset(image, anv_surf);<br>
+   if (plane_info) {<br>
+      anv_surf->offset = plane_info->offset;<br>
+   } else {<br>
+      set_min_surface_offset(image, anv_surf);<br>
+   }<br>
+<br>
    add_surface(image, anv_surf);<br>
 }<br>
<br>
@@ -304,10 +387,36 @@ anv_image_create(VkDevice _device,<br>
 {<br>
    ANV_FROM_HANDLE(anv_device, device, _device);<br>
    const VkImageCreateInfo *base_info = anv_info->vk_info;<br>
+   const VkImportImageDmaBufInfoMESAX *import_dma_buf_info = NULL;<br>
+   const VkExportImageDmaBufInfoMESAX *export_dma_buf_info = NULL;<br>
+   VkExternalMemoryHandleTypeFlag<wbr>sKHX handle_types = 0;<br>
    struct anv_image *image = NULL;<br>
<br>
    assert(base_info->sType == VK_STRUCTURE_TYPE_IMAGE_<wbr>CREATE_INFO);<br>
<br>
+   vk_foreach_struct_const(s, base_info->pNext) {<br>
+      switch (s->sType) {<br>
+      case VK_STRUCTURE_TYPE_EXTERNAL_<wbr>MEMORY_IMAGE_CREATE_INFO_KHX:<br></blockquote><div><br></div><div>Maybe assert handle_types == 0 to ensure it doesn't get set twice?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+         handle_types =<br>
+            ((const VkExternalMemoryImageCreateInf<wbr>oKHX *) s)->handleTypes;<br>
+         assert((handle_types & ~ANV_SUPPORTED_MEMORY_HANDLE_<wbr>TYPES) == 0);<br>
+         break;<br>
+      case VK_STRUCTURE_TYPE_IMPORT_<wbr>IMAGE_DMA_BUF_INFO_MESAX:<br>
+         import_dma_buf_info = (const void *) s;<br>
+         break;<br>
+      case VK_STRUCTURE_TYPE_EXPORT_<wbr>IMAGE_DMA_BUF_INFO_MESAX:<br>
+         export_dma_buf_info = (const void *) s;<br>
+         break;<br>
+      default:<br>
+         anv_debug_ignored_stype(s-><wbr>sType);<br>
+         break;<br>
+      }<br>
+   }<br>
+<br>
+   /* For dma_buf images, we require the user to provide DRM format modifiers. */<br>
+   assert((bool)(handle_types & VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_DMA_BUF_BIT_MESAX) ==<br>
+          (import_dma_buf_info || export_dma_buf_info));<br>
+<br>
    anv_assert(base_info-><wbr>mipLevels > 0);<br>
    anv_assert(base_info-><wbr>arrayLayers > 0);<br>
    anv_assert(base_info->samples > 0);<br>
@@ -335,8 +444,9 @@ anv_image_create(VkDevice _device,<br>
    uint32_t b;<br>
    for_each_bit(b, image->aspects) {<br>
       VkImageAspectFlagBits aspect = 1 << b;<br>
-      make_main_surface(device, anv_info, aspect, image);<br>
-      make_aux_surface_maybe(device, base_info, aspect, image);<br>
+      make_main_surface(device, anv_info, import_dma_buf_info,<br>
+                        export_dma_buf_info, aspect, handle_types, image);<br>
+      make_aux_surface_maybe(device, base_info, aspect, handle_types, image);<br>
    }<br>
<br>
    *pImage = anv_image_to_handle(image);<br>
@@ -469,13 +579,56 @@ void anv_GetImageSubresourceLayout(<br>
    }<br>
 }<br>
<br>
+static VkResult<br>
+get_image_dma_buf_props(const struct anv_image *image,<br>
+                        VkImageDmaBufPropertiesMESAX* dma_buf_props)<br>
+{<br>
+   ANV_OUTARRAY_MAKE(planes, dma_buf_props->pPlanes,<br>
+                     &dma_buf_props->planeCount);<br>
+   bool ok UNUSED;<br>
+<br>
+   /* For now, we support exactly one format for dma_buf images. */<br>
+   assert(image->vk_format == VK_FORMAT_R8G8B8A8_UNORM);<br>
+<br>
+   /* For now, We don't support dma_buf images with auxiliary surfaces. */<br>
+   assert(image->aux_surface.isl.<wbr>size == 0);<br>
+<br>
+   ok = isl_surf_get_drm_format_mod(&<wbr>image->color_surface.isl,<br>
+                                    image->aux_usage,<br>
+                                    &dma_buf_props-><wbr>drmFormatModifier);<br>
+   assert(ok);<br>
+<br>
+   anv_outarray_append(&planes, p) {<br>
+      p->offset = image->color_surface.offset;<br>
+      p->rowPitch = image->color_surface.isl.row_<wbr>pitch;<br>
+   }<br>
+<br>
+   if (anv_outarray_is_incomple(&<wbr>planes))<br>
+      return VK_INCOMPLETE;<br>
+<br>
+   return VK_SUCCESS;<br>
+}<br>
+<br>
 VkResult anv_GetImagePropertiesEXT(<br>
     VkDevice                                    device_h,<br>
     VkImage                                     image_h,<br>
     VkImagePropertiesEXT*                       base_props)<br>
 {<br>
+   ANV_FROM_HANDLE(anv_image, image, image_h);<br>
+   VkResult result;<br>
+<br>
    vk_foreach_struct(s, base_props->pNext) {<br>
-      anv_debug_ignored_stype(s-><wbr>sType);<br>
+      switch (s->sType) {<br>
+      case VK_STRUCTURE_TYPE_IMAGE_DMA_<wbr>BUF_PROPERTIES_MESAX:<br>
+         result = get_image_dma_buf_props(image,<br>
+                                          (VkImageDmaBufPropertiesMESAX *) s);<br>
+         if (result != VK_SUCCESS)<br>
+            return result;<br>
+         break;<br>
+      default:<br>
+         anv_debug_ignored_stype(s-><wbr>sType);<br>
+         break;<br>
+      }<br>
    }<br>
<br>
    return VK_SUCCESS;<br>
diff --git a/src/intel/vulkan/anv_<wbr>private.h b/src/intel/vulkan/anv_<wbr>private.h<br>
index ac922e7cfc6..103a9d68a9e 100644<br>
--- a/src/intel/vulkan/anv_<wbr>private.h<br>
+++ b/src/intel/vulkan/anv_<wbr>private.h<br>
@@ -30,7 +30,13 @@<br>
 #include <pthread.h><br>
 #include <assert.h><br>
 #include <stdint.h><br>
+<br>
 #include <i915_drm.h><br>
+#include <drm_fourcc.h><br>
+<br>
+#ifndef DRM_FORMAT_MOD_LINEAR /* new in Linux 4.10 */<br>
+#define DRM_FORMAT_MOD_LINEAR 0<br>
+#endif<br>
<br>
 #ifdef HAVE_VALGRIND<br>
 #include <valgrind.h><br>
<span class="HOEnZb"><font color="#888888">--<br>
2.12.0<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">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><br></div></div>