[Mesa-dev] [PATCH 7/8] anv/android: support creating images from external format

Jason Ekstrand jason at jlekstrand.net
Wed Aug 22 14:51:40 UTC 2018


On Tue, Aug 21, 2018 at 3:28 AM Tapani Pälli <tapani.palli at intel.com> wrote:

> Since we don't know the exact format at creation time, some initialization
> is done only when bound with memory in vkBindImageMemory.
>
> v2: demand dedicated allocation in vkGetImageMemoryRequirements2 if
>     image has external format
>
> Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
> ---
>  src/intel/vulkan/anv_android.c |  40 ++++++++++++++
>  src/intel/vulkan/anv_device.c  |   2 +-
>  src/intel/vulkan/anv_image.c   | 115
> +++++++++++++++++++++++++++++++++++++++++
>  src/intel/vulkan/anv_private.h |  10 ++++
>  4 files changed, 166 insertions(+), 1 deletion(-)
>
> diff --git a/src/intel/vulkan/anv_android.c
> b/src/intel/vulkan/anv_android.c
> index 6f90649847d..299b728a6f2 100644
> --- a/src/intel/vulkan/anv_android.c
> +++ b/src/intel/vulkan/anv_android.c
> @@ -344,6 +344,46 @@ anv_create_ahw_memory(VkDevice device_h,
>     return VK_SUCCESS;
>  }
>
> +VkResult
> +anv_image_from_external(
> +   VkDevice device_h,
> +   const VkImageCreateInfo *base_info,
> +   const struct VkExternalMemoryImageCreateInfo *create_info,
> +   const VkAllocationCallbacks *alloc,
> +   VkImage *out_image_h)
> +{
> +   ANV_FROM_HANDLE(anv_device, device, device_h);
> +   VkImage image_h = VK_NULL_HANDLE;
> +   struct anv_image *image = NULL;
> +   VkResult result = VK_SUCCESS;
> +
> +   /* Note, we can't set format, stride and such yet. */
> +   struct anv_image_create_info anv_info = {
> +      .vk_info = base_info,
> +      .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT,
> +      .external_format = true,
> +   };
> +
> +   const struct 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);
> +   }
> +
> +   result = anv_image_create(device_h, &anv_info, alloc, &image_h);
> +   image = anv_image_from_handle(image_h);
> +   if (result != VK_SUCCESS)
> +      return result;
> +
> +   *out_image_h = image_h;
> +
> +   return result;
> +}
> +
>  VkResult
>  anv_image_from_gralloc(VkDevice device_h,
>                         const VkImageCreateInfo *base_info,
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index 54919112d08..fbe057a8eec 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -2634,7 +2634,7 @@ void anv_GetImageMemoryRequirements2(
>        switch (ext->sType) {
>        case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
>           VkMemoryDedicatedRequirements *requirements = (void *)ext;
> -         if (image->needs_set_tiling) {
> +         if (image->needs_set_tiling || image->external_format) {
>              /* If we need to set the tiling for external consumers, we
> need a
>               * dedicated allocation.
>               *
> diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
> index e4ab74a15d6..de03d64c6a7 100644
> --- a/src/intel/vulkan/anv_image.c
> +++ b/src/intel/vulkan/anv_image.c
> @@ -596,6 +596,15 @@ anv_image_create(VkDevice _device,
>     image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier :
>                                            DRM_FORMAT_MOD_INVALID;
>
> +   /* 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;
> +      *pImage = anv_image_to_handle(image);
> +      return VK_SUCCESS;
> +   }
> +
>     const struct anv_format *format = anv_get_format(image->vk_format);
>     assert(format != NULL);
>
> @@ -631,6 +640,14 @@ anv_CreateImage(VkDevice device,
>                  VkImage *pImage)
>  {
>  #ifdef ANDROID
> +   const struct 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);
> +
>     const VkNativeBufferANDROID *gralloc_info =
>        vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
>
> @@ -687,6 +704,99 @@ static void anv_image_bind_memory_plane(struct
> anv_device *device,
>     };
>  }
>
> +#ifdef ANDROID
> +/* We are binding AHardwareBuffer. Get a description and
> + * prepare anv_image properly.
> + */
> +static void
> +prepare_ahw_image(struct anv_device *device,
> +                  struct anv_image *image,
> +                  struct anv_device_memory *mem)
> +{
> +   assert(mem->ahw);
> +
> +   AHardwareBuffer_Desc desc;
> +   AHardwareBuffer_describe(mem->ahw, &desc);
> +
> +   /* Check tiling. */
> +   int i915_tiling = anv_gem_get_tiling(device, mem->bo->gem_handle);
> +   VkImageTiling vk_tiling = 2;
> +
> +   isl_tiling_flags_t isl_tiling_flags = 0;
> +
> +   switch (i915_tiling) {
> +   case I915_TILING_NONE:
> +      vk_tiling = VK_IMAGE_TILING_LINEAR;
> +      isl_tiling_flags = ISL_TILING_LINEAR_BIT;
> +      break;
> +   case I915_TILING_X:
> +      vk_tiling = VK_IMAGE_TILING_OPTIMAL;
> +      isl_tiling_flags = ISL_TILING_X_BIT;
> +      break;
> +   case I915_TILING_Y:
> +      vk_tiling = VK_IMAGE_TILING_OPTIMAL;
> +      isl_tiling_flags = ISL_TILING_Y0_BIT;
> +      break;
> +   case -1:
> +   default:
> +      unreachable("Invalid tiling flags.");
> +   }
> +
> +   assert(vk_tiling == VK_IMAGE_TILING_LINEAR ||
> +          vk_tiling == VK_IMAGE_TILING_OPTIMAL);
> +
> +   /* Check format. */
> +   VkFormat vk_format = vk_format_from_android(desc.format);
> +   enum isl_format isl_fmt = anv_get_isl_format(&device->info,
> +                                                vk_format,
> +                                                VK_IMAGE_ASPECT_COLOR_BIT,
> +                                                vk_tiling);
> +   assert(format != ISL_FORMAT_UNSUPPORTED);
> +
> +   /* Now we should be able to fill anv_image fields properly and
> +    * create isl_surface for it.
> +    */
> +   image->vk_format = vk_format;
> +   image->format = anv_get_format(vk_format);
> +   image->aspects = vk_format_aspects(image->vk_format);
> +
> +   const struct anv_format *format = anv_get_format(image->vk_format);
> +   assert(format != NULL);
> +
> +   image->n_planes = format->n_planes;
> +
> +   /* Fill anv_image_create_info here so that we can call make_surface. */
> +   VkImageCreateInfo base_info = {
> +      .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
> +      .pNext = NULL,
> +      .format = vk_format,
> +      .imageType = VK_IMAGE_TYPE_2D,
> +      .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
> +      .tiling = VK_IMAGE_TILING_OPTIMAL,
> +      .samples = image->samples,
> +      .arrayLayers = image->array_size,
> +      .mipLevels = image->levels,
> +      .extent = image->extent,
> +   };
>

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.


> +
> +   struct anv_image_create_info anv_info = {
> +      .vk_info = &base_info,
> +      .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT,
> +      .external_format = true,
> +   };
> +
> +   anv_info.stride = desc.stride *
> +                     (isl_format_get_layout(isl_fmt)->bpb / 8);
> +
> +   uint32_t b;
> +   for_each_bit(b, image->aspects) {
> +      VkResult r = make_surface(device, image, &anv_info,
> isl_tiling_flags,
> +                       (1 << b));
> +      assert(r == VK_SUCCESS);
> +   }
> +}
> +#endif
> +
>  VkResult anv_BindImageMemory(
>      VkDevice                                    _device,
>      VkImage                                     _image,
> @@ -697,6 +807,11 @@ VkResult anv_BindImageMemory(
>     ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
>     ANV_FROM_HANDLE(anv_image, image, _image);
>
> +#ifdef ANDROID
> +   if (mem->ahw && image->format == VK_FORMAT_UNDEFINED)
> +      prepare_ahw_image(device, image, mem);
> +#endif
> +
>     uint32_t aspect_bit;
>     anv_foreach_image_aspect_bit(aspect_bit, image, image->aspects) {
>        uint32_t plane =
> diff --git a/src/intel/vulkan/anv_private.h
> b/src/intel/vulkan/anv_private.h
> index 56dee607dbe..7c01cf82a52 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -2665,6 +2665,9 @@ struct anv_image {
>      */
>     bool disjoint;
>
> +   /* Image was created with external format. */
> +   bool external_format;
> +
>     /**
>      * Image subsurfaces
>      *
> @@ -3040,6 +3043,7 @@ struct anv_image_create_info {
>     isl_surf_usage_flags_t isl_extra_usage_flags;
>
>     uint32_t stride;
> +   bool external_format;
>  };
>
>  VkResult anv_image_create(VkDevice _device,
> @@ -3054,6 +3058,12 @@ VkResult anv_image_from_gralloc(VkDevice device_h,
>                                  const VkAllocationCallbacks *alloc,
>                                  VkImage *pImage);
>
> +VkResult anv_image_from_external(VkDevice device_h,
> +                                 const VkImageCreateInfo *base_info,
> +                                 const struct
> VkExternalMemoryImageCreateInfo *create_info,
> +                                 const VkAllocationCallbacks *alloc,
> +                                 VkImage *out_image_h);
> +
>  VkResult anv_import_ahw_memory(VkDevice device_h,
>                                 struct anv_device_memory *mem,
>                                 const
> VkImportAndroidHardwareBufferInfoANDROID *info);
> --
> 2.14.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180822/f5fab590/attachment-0001.html>


More information about the mesa-dev mailing list