[Mesa-dev] [RFC PATCH v1 25/30] RFC: anv: Support VkImageDrmFormatModifierListCreateInfoEXT

Jason Ekstrand jason at jlekstrand.net
Tue Nov 7 20:52:35 UTC 2017


On Tue, Nov 7, 2017 at 6:48 AM, Chad Versace <chadversary at chromium.org>
wrote:

> Incremental implementation of VK_EXT_image_drm_format_modifier.
> ---
>  src/intel/vulkan/anv_image.c   | 72 ++++++++++++++++++++++++++++++
> ++++++++----
>  src/intel/vulkan/anv_private.h |  6 ++++
>  2 files changed, 72 insertions(+), 6 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
> index ba932ba47c3..8d434293124 100644
> --- a/src/intel/vulkan/anv_image.c
> +++ b/src/intel/vulkan/anv_image.c
> @@ -27,6 +27,7 @@
>  #include <unistd.h>
>  #include <fcntl.h>
>  #include <sys/mman.h>
> +#include <drm_fourcc.h>
>
>  #include "anv_private.h"
>  #include "util/debug.h"
> @@ -35,11 +36,12 @@
>  #include "vk_format_info.h"
>
>  static isl_surf_usage_flags_t
> -choose_isl_surf_usage(VkImageCreateFlags vk_create_flags,
> -                      VkImageUsageFlags vk_usage,
> +choose_isl_surf_usage(const VkImageCreateInfo *vk_info,
>                        isl_surf_usage_flags_t isl_extra_usage,
>                        VkImageAspectFlagBits aspect)
>  {
> +   VkImageCreateFlags vk_create_flags = vk_info->flags;
> +   VkImageUsageFlags vk_usage = vk_info->usage;
>     isl_surf_usage_flags_t isl_usage = isl_extra_usage;
>
>     if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
> @@ -87,11 +89,15 @@ choose_isl_surf_usage(VkImageCreateFlags
> vk_create_flags,
>        isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
>     }
>
> +   if (vk_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
> +      isl_usage |= ISL_SURF_USAGE_DISABLE_AUX_BIT;
> +
>     return isl_usage;
>  }
>
>  static isl_tiling_flags_t
> -choose_isl_tiling_flags(const struct anv_image_create_info *anv_info)
> +choose_isl_tiling_flags(const struct anv_image_create_info *anv_info,
> +                        const struct isl_drm_modifier_info *isl_mod_info)
>  {
>     const VkImageCreateInfo *base_info = anv_info->vk_info;
>     isl_tiling_flags_t flags = 0;
> @@ -100,11 +106,16 @@ choose_isl_tiling_flags(const struct
> anv_image_create_info *anv_info)
>     default:
>        unreachable("bad VkImageTiling");
>     case VK_IMAGE_TILING_OPTIMAL:
> +      assert(isl_mod_info == NULL);
>        flags = ISL_TILING_ANY_MASK;
>        break;
>     case VK_IMAGE_TILING_LINEAR:
> +      assert(isl_mod_info == NULL);
>        flags = ISL_TILING_LINEAR_BIT;
>        break;
> +   case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:
> +      flags = 1 << isl_mod_info->tiling;
> +      break;
>     }
>
>     if (anv_info->isl_tiling_flags)
> @@ -298,8 +309,7 @@ make_surface(const struct anv_device *dev,
>     struct anv_surface *anv_surf = &image->planes[plane].surface;
>
>     const isl_surf_usage_flags_t usage =
> -      choose_isl_surf_usage(vk_info->flags, image->usage,
> -                            anv_info->isl_extra_usage_flags, aspect);
> +      choose_isl_surf_usage(vk_info, anv_info->isl_extra_usage_flags,
> aspect);
>
>     /* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need
> to
>      * fall back to linear on Broadwell and earlier because we aren't
> @@ -492,6 +502,38 @@ make_surface(const struct anv_device *dev,
>     return VK_SUCCESS;
>  }
>
> +static uint32_t
> +score_drm_format_mod(uint64_t mod)
> +{
> +   switch (mod) {
> +   default: unreachable("bad DRM format modifier");
> +   case I915_FORMAT_MOD_Y_TILED: return 3;
> +   case I915_FORMAT_MOD_X_TILED: return 2;
> +   case DRM_FORMAT_MOD_LINEAR: return 1;
> +   }
> +}
> +
> +static const struct isl_drm_modifier_info *
> +choose_drm_format_mod(const VkImageDrmFormatModifierListCreateInfoEXT
> *mod_list)
> +{
> +   uint64_t best_mod = UINT64_MAX;
> +   uint32_t best_score = 0;
> +
> +   for (uint32_t i = 0; i < mod_list->drmFormatModifierCount; ++i) {
> +      uint64_t mod = mod_list->pDrmFormatModifiers[i];
> +      uint32_t score = score_drm_format_mod(mod);
> +
> +      if (score > best_score) {
> +         best_mod = mod;
> +         best_score = score;
> +      }
> +   }
> +
> +   assert(best_score != 0);
> +
> +   return isl_drm_modifier_get_info(best_mod);
> +}
>

We did things slightly differently in intel_screen.c but I like this better.


> +
>  VkResult
>  anv_image_create(VkDevice _device,
>                   const struct anv_image_create_info *create_info,
> @@ -500,11 +542,26 @@ anv_image_create(VkDevice _device,
>  {
>     ANV_FROM_HANDLE(anv_device, device, _device);
>     const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
> +   const VkImageDrmFormatModifierListCreateInfoEXT *vk_mod_list = NULL;
> +   const struct isl_drm_modifier_info *isl_mod_info = NULL;
>     struct anv_image *image = NULL;
>     VkResult r;
>
>     assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
>
> +   /* Extract input structs */
> +   vk_foreach_struct_const(s, pCreateInfo->pNext) {
> +      switch (s->sType) {
> +      case VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_
> INFO_EXT:
> +         vk_mod_list = (const VkImageDrmFormatModifierListCreateInfoEXT
> *) s;
> +         isl_mod_info = choose_drm_format_mod(vk_mod_list);
>

Does image creation need to somehow fail if they choose an invalid
modifier?  Or are we just trusting that they enumerate correctly?  I'm fine
with just trusting the client but I wanted to double-check.


> +         break;
> +      default:
> +         anv_debug_ignored_stype(s->sType);
> +         break;
> +      }
> +   }
> +
>     anv_assert(pCreateInfo->mipLevels > 0);
>     anv_assert(pCreateInfo->arrayLayers > 0);
>     anv_assert(pCreateInfo->samples > 0);
> @@ -529,11 +586,14 @@ anv_image_create(VkDevice _device,
>     image->tiling = pCreateInfo->tiling;
>     image->disjoint = pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT_
> KHR;
>
> +   if (isl_mod_info)
> +      image->drm_format_mod = isl_mod_info->modifier;
> +
>     const struct anv_format *format = anv_get_format(image->vk_format);
>     assert(format != NULL);
>
>     const isl_tiling_flags_t isl_tiling_flags =
> -      choose_isl_tiling_flags(create_info);
> +      choose_isl_tiling_flags(create_info, isl_mod_info);
>
>     image->n_planes = format->n_planes;
>
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_
> private.h
> index e17a52a4a70..2312845570b 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -2337,6 +2337,12 @@ struct anv_image {
>     VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */
>     VkImageTiling tiling; /** VkImageCreateInfo::tiling */
>
> +   /**
> +    * Must be DRM_FORMAT_MOD_INVALID unless tiling is
> +    * VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT.
> +    */
> +   uint64_t drm_format_mod;
> +
>     VkDeviceSize size;
>     uint32_t alignment;
>
> --
> 2.13.0
>
> _______________________________________________
> 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/20171107/641c43b6/attachment-0001.html>


More information about the mesa-dev mailing list