<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, Aug 21, 2018 at 3:28 AM Tapani Pälli <<a href="mailto:tapani.palli@intel.com">tapani.palli@intel.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Since we don't know the exact format at creation time, some initialization<br>
is done only when bound with memory in vkBindImageMemory.<br>
<br>
v2: demand dedicated allocation in vkGetImageMemoryRequirements2 if<br>
    image has external format<br>
<br>
Signed-off-by: Tapani Pälli <<a href="mailto:tapani.palli@intel.com" target="_blank">tapani.palli@intel.com</a>><br>
---<br>
 src/intel/vulkan/anv_android.c |  40 ++++++++++++++<br>
 src/intel/vulkan/anv_device.c  |   2 +-<br>
 src/intel/vulkan/anv_image.c   | 115 +++++++++++++++++++++++++++++++++++++++++<br>
 src/intel/vulkan/anv_private.h |  10 ++++<br>
 4 files changed, 166 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c<br>
index 6f90649847d..299b728a6f2 100644<br>
--- a/src/intel/vulkan/anv_android.c<br>
+++ b/src/intel/vulkan/anv_android.c<br>
@@ -344,6 +344,46 @@ anv_create_ahw_memory(VkDevice device_h,<br>
    return VK_SUCCESS;<br>
 }<br>
<br>
+VkResult<br>
+anv_image_from_external(<br>
+   VkDevice device_h,<br>
+   const VkImageCreateInfo *base_info,<br>
+   const struct VkExternalMemoryImageCreateInfo *create_info,<br>
+   const VkAllocationCallbacks *alloc,<br>
+   VkImage *out_image_h)<br>
+{<br>
+   ANV_FROM_HANDLE(anv_device, device, device_h);<br>
+   VkImage image_h = VK_NULL_HANDLE;<br>
+   struct anv_image *image = NULL;<br>
+   VkResult result = VK_SUCCESS;<br>
+<br>
+   /* Note, we can't set format, stride and such yet. */<br>
+   struct anv_image_create_info anv_info = {<br>
+      .vk_info = base_info,<br>
+      .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT,<br>
+      .external_format = true,<br>
+   };<br>
+<br>
+   const struct VkExternalFormatANDROID *ext_info =<br>
+      vk_find_struct_const(base_info->pNext, EXTERNAL_FORMAT_ANDROID);<br>
+<br>
+   if (ext_info && ext_info->externalFormat != 0) {<br>
+      assert(base_info->format == VK_FORMAT_UNDEFINED);<br>
+      assert(base_info->imageType == VK_IMAGE_TYPE_2D);<br>
+      assert(base_info->usage == VK_IMAGE_USAGE_SAMPLED_BIT);<br>
+      assert(base_info->tiling == VK_IMAGE_TILING_OPTIMAL);<br>
+   }<br>
+<br>
+   result = anv_image_create(device_h, &anv_info, alloc, &image_h);<br>
+   image = anv_image_from_handle(image_h);<br>
+   if (result != VK_SUCCESS)<br>
+      return result;<br>
+<br>
+   *out_image_h = image_h;<br>
+<br>
+   return result;<br>
+}<br>
+<br>
 VkResult<br>
 anv_image_from_gralloc(VkDevice device_h,<br>
                        const VkImageCreateInfo *base_info,<br>
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c<br>
index 54919112d08..fbe057a8eec 100644<br>
--- a/src/intel/vulkan/anv_device.c<br>
+++ b/src/intel/vulkan/anv_device.c<br>
@@ -2634,7 +2634,7 @@ void anv_GetImageMemoryRequirements2(<br>
       switch (ext->sType) {<br>
       case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {<br>
          VkMemoryDedicatedRequirements *requirements = (void *)ext;<br>
-         if (image->needs_set_tiling) {<br>
+         if (image->needs_set_tiling || image->external_format) {<br>
             /* If we need to set the tiling for external consumers, we need a<br>
              * dedicated allocation.<br>
              *<br>
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c<br>
index e4ab74a15d6..de03d64c6a7 100644<br>
--- a/src/intel/vulkan/anv_image.c<br>
+++ b/src/intel/vulkan/anv_image.c<br>
@@ -596,6 +596,15 @@ anv_image_create(VkDevice _device,<br>
    image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier :<br>
                                           DRM_FORMAT_MOD_INVALID;<br>
<br>
+   /* In case of external format, We don't know format yet,<br>
+    * so skip the rest for now.<br>
+    */<br>
+   if (create_info->external_format) {<br>
+      image->external_format = true;<br>
+      *pImage = anv_image_to_handle(image);<br>
+      return VK_SUCCESS;<br>
+   }<br>
+<br>
    const struct anv_format *format = anv_get_format(image->vk_format);<br>
    assert(format != NULL);<br>
<br>
@@ -631,6 +640,14 @@ anv_CreateImage(VkDevice device,<br>
                 VkImage *pImage)<br>
 {<br>
 #ifdef ANDROID<br>
+   const struct VkExternalMemoryImageCreateInfo *create_info =<br>
+      vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);<br>
+<br>
+   if (create_info && create_info->handleTypes &<br>
+       VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)<br>
+      return anv_image_from_external(device, pCreateInfo, create_info,<br>
+                                     pAllocator, pImage);<br>
+<br>
    const VkNativeBufferANDROID *gralloc_info =<br>
       vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);<br>
<br>
@@ -687,6 +704,99 @@ static void anv_image_bind_memory_plane(struct anv_device *device,<br>
    };<br>
 }<br>
<br>
+#ifdef ANDROID<br>
+/* We are binding AHardwareBuffer. Get a description and<br>
+ * prepare anv_image properly.<br>
+ */<br>
+static void<br>
+prepare_ahw_image(struct anv_device *device,<br>
+                  struct anv_image *image,<br>
+                  struct anv_device_memory *mem)<br>
+{<br>
+   assert(mem->ahw);<br>
+<br>
+   AHardwareBuffer_Desc desc;<br>
+   AHardwareBuffer_describe(mem->ahw, &desc);<br>
+<br>
+   /* Check tiling. */<br>
+   int i915_tiling = anv_gem_get_tiling(device, mem->bo->gem_handle);<br>
+   VkImageTiling vk_tiling = 2;<br>
+<br>
+   isl_tiling_flags_t isl_tiling_flags = 0;<br>
+<br>
+   switch (i915_tiling) {<br>
+   case I915_TILING_NONE:<br>
+      vk_tiling = VK_IMAGE_TILING_LINEAR;<br>
+      isl_tiling_flags = ISL_TILING_LINEAR_BIT;<br>
+      break;<br>
+   case I915_TILING_X:<br>
+      vk_tiling = VK_IMAGE_TILING_OPTIMAL;<br>
+      isl_tiling_flags = ISL_TILING_X_BIT;<br>
+      break;<br>
+   case I915_TILING_Y:<br>
+      vk_tiling = VK_IMAGE_TILING_OPTIMAL;<br>
+      isl_tiling_flags = ISL_TILING_Y0_BIT;<br>
+      break;<br>
+   case -1:<br>
+   default:<br>
+      unreachable("Invalid tiling flags.");<br>
+   }<br>
+<br>
+   assert(vk_tiling == VK_IMAGE_TILING_LINEAR ||<br>
+          vk_tiling == VK_IMAGE_TILING_OPTIMAL);<br>
+<br>
+   /* Check format. */<br>
+   VkFormat vk_format = vk_format_from_android(desc.format);<br>
+   enum isl_format isl_fmt = anv_get_isl_format(&device->info,<br>
+                                                vk_format,<br>
+                                                VK_IMAGE_ASPECT_COLOR_BIT,<br>
+                                                vk_tiling);<br>
+   assert(format != ISL_FORMAT_UNSUPPORTED);<br>
+<br>
+   /* Now we should be able to fill anv_image fields properly and<br>
+    * create isl_surface for it.<br>
+    */<br>
+   image->vk_format = vk_format;<br>
+   image->format = anv_get_format(vk_format);<br>
+   image->aspects = vk_format_aspects(image->vk_format);<br>
+<br>
+   const struct anv_format *format = anv_get_format(image->vk_format);<br>
+   assert(format != NULL);<br>
+<br>
+   image->n_planes = format->n_planes;<br>
+<br>
+   /* Fill anv_image_create_info here so that we can call make_surface. */<br>
+   VkImageCreateInfo base_info = {<br>
+      .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,<br>
+      .pNext = NULL,<br>
+      .format = vk_format,<br>
+      .imageType = VK_IMAGE_TYPE_2D,<br>
+      .usage = VK_IMAGE_USAGE_SAMPLED_BIT,<br>
+      .tiling = VK_IMAGE_TILING_OPTIMAL,<br>
+      .samples = image->samples,<br>
+      .arrayLayers = image->array_size,<br>
+      .mipLevels = image->levels,<br>
+      .extent = image->extent,<br>
+   };<br></blockquote><div><br></div><div>This is gross.  Most of the stuff that make_surface pulls from the VkImageCreateInfo is already stashed in the image.  We should make make_surface pull the data it needs from the image and stop referencing the VkImageCreateInfo directly.  Then this function would get a lot smaller and we would have less redundant information to get out of sync.<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_image_create_info anv_info = {<br>
+      .vk_info = &base_info,<br>
+      .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT,<br>
+      .external_format = true,<br>
+   };<br>
+<br>
+   anv_info.stride = desc.stride *<br>
+                     (isl_format_get_layout(isl_fmt)->bpb / 8);<br>
+<br>
+   uint32_t b;<br>
+   for_each_bit(b, image->aspects) {<br>
+      VkResult r = make_surface(device, image, &anv_info, isl_tiling_flags,<br>
+                       (1 << b));<br>
+      assert(r == VK_SUCCESS);<br>
+   }<br>
+}<br>
+#endif<br>
+<br>
 VkResult anv_BindImageMemory(<br>
     VkDevice                                    _device,<br>
     VkImage                                     _image,<br>
@@ -697,6 +807,11 @@ VkResult anv_BindImageMemory(<br>
    ANV_FROM_HANDLE(anv_device_memory, mem, _memory);<br>
    ANV_FROM_HANDLE(anv_image, image, _image);<br>
<br>
+#ifdef ANDROID<br>
+   if (mem->ahw && image->format == VK_FORMAT_UNDEFINED)<br>
+      prepare_ahw_image(device, image, mem);<br>
+#endif<br>
+<br>
    uint32_t aspect_bit;<br>
    anv_foreach_image_aspect_bit(aspect_bit, image, image->aspects) {<br>
       uint32_t plane =<br>
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h<br>
index 56dee607dbe..7c01cf82a52 100644<br>
--- a/src/intel/vulkan/anv_private.h<br>
+++ b/src/intel/vulkan/anv_private.h<br>
@@ -2665,6 +2665,9 @@ struct anv_image {<br>
     */<br>
    bool disjoint;<br>
<br>
+   /* Image was created with external format. */<br>
+   bool external_format;<br>
+<br>
    /**<br>
     * Image subsurfaces<br>
     *<br>
@@ -3040,6 +3043,7 @@ struct anv_image_create_info {<br>
    isl_surf_usage_flags_t isl_extra_usage_flags;<br>
<br>
    uint32_t stride;<br>
+   bool external_format;<br>
 };<br>
<br>
 VkResult anv_image_create(VkDevice _device,<br>
@@ -3054,6 +3058,12 @@ VkResult anv_image_from_gralloc(VkDevice device_h,<br>
                                 const VkAllocationCallbacks *alloc,<br>
                                 VkImage *pImage);<br>
<br>
+VkResult anv_image_from_external(VkDevice device_h,<br>
+                                 const VkImageCreateInfo *base_info,<br>
+                                 const struct VkExternalMemoryImageCreateInfo *create_info,<br>
+                                 const VkAllocationCallbacks *alloc,<br>
+                                 VkImage *out_image_h);<br>
+<br>
 VkResult anv_import_ahw_memory(VkDevice device_h,<br>
                                struct anv_device_memory *mem,<br>
                                const VkImportAndroidHardwareBufferInfoANDROID *info);<br>
-- <br>
2.14.4<br>
<br>
_______________________________________________<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/mailman/listinfo/mesa-dev</a><br>
</blockquote></div></div>