Mesa (main): anv/android: Rework our handling of AHardwareBuffer imports

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 27 17:27:39 UTC 2021


Module: Mesa
Branch: main
Commit: 49908c602ffd2d84063effa7ddd0ee842be41a89
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=49908c602ffd2d84063effa7ddd0ee842be41a89

Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Thu Jul 22 11:17:28 2021 -0500

anv/android: Rework our handling of AHardwareBuffer imports

The current code we have for this is a bit of a mess, likely due to
trying too hard to put it in anv_android.c.  The external_format bit in
anv_image, for instance, really means "quit creation early" which is
something we want to do for AHardwareBuffer imports regardless of
whether or not they use a native format.  It gets set both by declaring
an AHardwareBuffer external handle type and by VkExternalFormatANDROID.
However, VkExternalFormatANDROID is only allowed for AHardwareBuffer
imports.  If we ever did get an external format outside the context of
an AHardwareBuffer import, we would end up with a useless partially
created image.

When we detect an AHardwareBuffer import, we punt off to a function in
anv_android.c that does nothing interesting but call anv_create_image
with AUX disabled and external_format = true.  The aux disable here is
useless because the actual isl_surf layout is done by resolve_ahw_image
which also sets ISL_SURF_USAGE_DISABLE_AUX_BIT.  As far as external
formats go, anv_image_from_external() sets it regardless of whether or
not there is actually an external format.

This commit replaces anv_image::external_format with anv_image::from_ahb
which is the thing we actually want to track for this.  We delete
anv_image_from_external and a bunch of the external_format handling
because it's all useless.  The end result is massively simpler and,
while it appears to blur the boundary between Android code and the rest
of the driver, it makes the whole flow more obvious.

Reviewed-by: Tapani Pälli <tapani.palli at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12040>

---

 src/intel/vulkan/anv_android.c | 41 --------------------------------------
 src/intel/vulkan/anv_image.c   | 45 +++++++++++++++---------------------------
 src/intel/vulkan/anv_private.h | 14 +++++++++----
 3 files changed, 26 insertions(+), 74 deletions(-)

diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c
index 8e02aae92d7..fec5c58a4a7 100644
--- a/src/intel/vulkan/anv_android.c
+++ b/src/intel/vulkan/anv_android.c
@@ -452,47 +452,6 @@ anv_create_ahw_memory(VkDevice device_h,
 
 }
 
-VkResult
-anv_image_from_external(
-   VkDevice device_h,
-   const VkImageCreateInfo *base_info,
-   const VkExternalMemoryImageCreateInfo *create_info,
-   const VkAllocationCallbacks *alloc,
-   VkImage *out_image_h)
-{
-#if ANDROID_API_LEVEL >= 26
-   ANV_FROM_HANDLE(anv_device, device, device_h);
-
-   const VkExternalFormatANDROID *ext_info =
-      vk_find_struct_const(base_info->pNext, EXTERNAL_FORMAT_ANDROID);
-
-   if (ext_info && ext_info->externalFormat != 0) {
-      assert(base_info->format == VK_FORMAT_UNDEFINED);
-      assert(base_info->imageType == VK_IMAGE_TYPE_2D);
-      assert(base_info->usage == VK_IMAGE_USAGE_SAMPLED_BIT);
-      assert(base_info->tiling == VK_IMAGE_TILING_OPTIMAL);
-   }
-
-   struct anv_image_create_info anv_info = {
-      .vk_info = base_info,
-      .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT,
-      .external_format = true,
-   };
-
-   VkImage image_h;
-   VkResult result = anv_image_create(device_h, &anv_info, alloc, &image_h);
-   if (result != VK_SUCCESS)
-      return result;
-
-   *out_image_h = image_h;
-
-   return VK_SUCCESS;
-#else
-   return VK_ERROR_EXTENSION_NOT_PRESENT;
-#endif
-}
-
-
 VkResult
 anv_image_from_gralloc(VkDevice device_h,
                        const VkImageCreateInfo *base_info,
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index 386241fd8f5..9d58fa968c5 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -1266,6 +1266,9 @@ anv_image_create(VkDevice _device,
    const struct wsi_image_create_info *wsi_info =
       vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
 
+   const VkExternalFormatANDROID *ext_format =
+      vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);
+
    if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
       mod_explicit_info =
          vk_find_struct_const(pCreateInfo->pNext,
@@ -1312,6 +1315,9 @@ anv_image_create(VkDevice _device,
    image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier :
                                           DRM_FORMAT_MOD_INVALID;
 
+   if (ext_format && ext_format->externalFormat != 0)
+      image->has_android_external_format = true;
+
    if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
       image->stencil_usage = pCreateInfo->usage;
       const VkImageStencilUsageCreateInfoEXT *stencil_usage_info =
@@ -1330,11 +1336,12 @@ anv_image_create(VkDevice _device,
       };
    }
 
-   /* In case of external format, We don't know format yet,
-    * so skip the rest for now.
-    */
-   if (create_info->external_format) {
-      image->external_format = true;
+   /* In case of AHardwareBuffer import, we don't know the layout yet */
+   const VkExternalMemoryImageCreateInfo *ext_mem_info =
+      vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
+   if (ext_mem_info && (ext_mem_info->handleTypes &
+       VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) {
+      image->from_ahb = true;
       *pImage = anv_image_to_handle(image);
       return VK_SUCCESS;
    }
@@ -1453,7 +1460,6 @@ anv_image_from_swapchain(VkDevice device,
    return anv_image_create(device,
       &(struct anv_image_create_info) {
          .vk_info = &local_create_info,
-         .external_format = swapchain_image->external_format,
       },
       pAllocator,
       pImage);
@@ -1465,25 +1471,6 @@ anv_CreateImage(VkDevice device,
                 const VkAllocationCallbacks *pAllocator,
                 VkImage *pImage)
 {
-   const VkExternalMemoryImageCreateInfo *create_info =
-      vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
-
-   if (create_info && (create_info->handleTypes &
-       VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID))
-      return anv_image_from_external(device, pCreateInfo, create_info,
-                                     pAllocator, pImage);
-
-   bool use_external_format = false;
-   const VkExternalFormatANDROID *ext_format =
-      vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);
-
-   /* "If externalFormat is zero, the effect is as if the
-    * VkExternalFormatANDROID structure was not present. Otherwise, the image
-    * will have the specified external format."
-    */
-   if (ext_format && ext_format->externalFormat != 0)
-      use_external_format = true;
-
    const VkNativeBufferANDROID *gralloc_info =
       vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
    if (gralloc_info)
@@ -1499,7 +1486,6 @@ anv_CreateImage(VkDevice device,
    return anv_image_create(device,
       &(struct anv_image_create_info) {
          .vk_info = pCreateInfo,
-         .external_format = use_external_format,
       },
       pAllocator,
       pImage);
@@ -1653,7 +1639,7 @@ void anv_GetImageMemoryRequirements2(
       switch (ext->sType) {
       case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
          VkMemoryDedicatedRequirements *requirements = (void *)ext;
-         if (image->needs_set_tiling || image->external_format) {
+         if (image->needs_set_tiling || image->from_ahb) {
             /* If we need to set the tiling for external consumers, we need a
              * dedicated allocation.
              *
@@ -2705,7 +2691,7 @@ anv_CreateImageView(VkDevice _device,
     * VKSamplerYcbcrConversionInfo with a conversion object created with the same
     * external format as image."
     */
-   assert(!image->external_format || conv_info);
+   assert(!image->has_android_external_format || conv_info);
 
    if (conv_info) {
       ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, conv_info->conversion);
@@ -2791,7 +2777,8 @@ anv_CreateImageView(VkDevice _device,
    iview->vk_format = pCreateInfo->format;
 
    /* "If image has an external format, format must be VK_FORMAT_UNDEFINED." */
-   assert(!image->external_format || pCreateInfo->format == VK_FORMAT_UNDEFINED);
+   assert(!image->has_android_external_format ||
+          pCreateInfo->format == VK_FORMAT_UNDEFINED);
 
    /* Format is undefined, this can happen when using external formats. Set
     * view format from the passed conversion info.
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index fa3582b979f..b5180910dbe 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -3983,8 +3983,16 @@ struct anv_image {
     */
    bool disjoint;
 
-   /* Image was created with external format. */
-   bool external_format;
+   /**
+    * Image was imported from an struct AHardwareBuffer.  We have to delay
+    * final image creation until bind time.
+    */
+   bool from_ahb;
+
+   /**
+    * True if an external format was specified
+    */
+   bool has_android_external_format;
 
    /**
     * Image was imported from gralloc with VkNativeBufferANDROID. The gralloc bo
@@ -4434,8 +4442,6 @@ struct anv_image_create_info {
 
    /** These flags will be added to any derived from VkImageCreateInfo. */
    isl_surf_usage_flags_t isl_extra_usage_flags;
-
-   bool external_format;
 };
 
 VkResult anv_image_create(VkDevice _device,



More information about the mesa-commit mailing list