anv: Support modifiers in GetImageFormatProperties2
authorJason Ekstrand <jason@jlekstrand.net>
Thu, 16 Jan 2020 19:38:55 +0000 (13:38 -0600)
committerMarge Bot <eric+marge@anholt.net>
Fri, 17 Jan 2020 18:27:29 +0000 (18:27 +0000)
Images with modifiers come with restrictions:

 1. They have to be simple 2D images right now

 2. They need to have a sensible format (not compressed, multi-plane, or
    non-power-of-two)

 3. If a CCS modifier is being requested, they have to actually support
    CCS_E and be CCS-compatible with any other formats the client may
    wish to use for image views.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3434>

src/intel/vulkan/anv_formats.c
src/intel/vulkan/anv_image.c
src/intel/vulkan/anv_private.h

index 405c732697655daec15ebd538b7a3ffa418c1b9b..7bd08c8772290afbbe2a7a0c801b998ef3e20847 100644 (file)
@@ -475,6 +475,18 @@ anv_get_format_plane(const struct gen_device_info *devinfo, VkFormat vk_format,
        (isl_layout->bpb == 24 || isl_layout->bpb == 48))
       return unsupported;
 
+   if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
+      /* No non-power-of-two fourcc formats exist */
+      if (!util_is_power_of_two_or_zero(isl_layout->bpb))
+         return unsupported;
+
+      if (vk_format_is_depth_or_stencil(vk_format))
+         return unsupported;
+
+      if (isl_format_is_compressed(plane_format.isl_format))
+         return unsupported;
+   }
+
    if (tiling == VK_IMAGE_TILING_OPTIMAL &&
        !util_is_power_of_two_or_zero(isl_layout->bpb)) {
       /* Tiled formats *must* be power-of-two because we need up upload
@@ -908,6 +920,40 @@ anv_get_image_format_properties(
        */
    }
 
+   if (info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
+      const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *modifier_info =
+         vk_find_struct_const(info->pNext,
+                              PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT);
+
+      /* Modifiers are only supported on simple 2D images */
+      if (info->type != VK_IMAGE_TYPE_2D)
+         goto unsupported;
+      maxArraySize = 1;
+      maxMipLevels = 1;
+      assert(sampleCounts == VK_SAMPLE_COUNT_1_BIT);
+
+      /* Modifiers are not yet supported for YCbCr */
+      const struct anv_format *format = anv_get_format(info->format);
+      if (format->n_planes > 1)
+         goto unsupported;
+
+      const struct isl_drm_modifier_info *isl_mod_info =
+         isl_drm_modifier_get_info(modifier_info->drmFormatModifier);
+      if (isl_mod_info->aux_usage == ISL_AUX_USAGE_CCS_E) {
+         /* If we have a CCS modifier, ensure that the format supports CCS
+          * and, if VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT is set, all of the
+          * formats in the format list are CCS compatible.
+          */
+         const VkImageFormatListCreateInfoKHR *fmt_list =
+            vk_find_struct_const(info->pNext,
+                                 IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
+         if (!anv_formats_ccs_e_compatible(devinfo, info->flags,
+                                           info->format, info->tiling,
+                                           fmt_list))
+            goto unsupported;
+      }
+   }
+
    /* From the bspec section entitled "Surface Layout and Tiling",
     * pre-gen9 has a 2 GB limitation of the size in bytes,
     * gen9 and gen10 have a 256 GB limitation and gen11+
@@ -1035,6 +1081,9 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties2(
       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
          external_info = (const void *) s;
          break;
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT:
+         /* anv_get_image_format_properties will handle this */
+         break;
       case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT:
          /* Ignore but don't warn */
          break;
index d2395314c914d00fe93ebc7cdad17e75cf60bc2a..14dd88537c148069b3aedddeb1bfdf6e57eff5b4 100644 (file)
@@ -159,19 +159,21 @@ add_surface(struct anv_image *image, struct anv_surface *surf, uint32_t plane)
 }
 
 
-static bool
-all_formats_ccs_e_compatible(const struct gen_device_info *devinfo,
-                             const VkImageFormatListCreateInfoKHR *fmt_list,
-                             struct anv_image *image)
+bool
+anv_formats_ccs_e_compatible(const struct gen_device_info *devinfo,
+                             VkImageCreateFlags create_flags,
+                             VkFormat vk_format,
+                             VkImageTiling vk_tiling,
+                             const VkImageFormatListCreateInfoKHR *fmt_list)
 {
    enum isl_format format =
-      anv_get_isl_format(devinfo, image->vk_format,
-                         VK_IMAGE_ASPECT_COLOR_BIT, image->tiling);
+      anv_get_isl_format(devinfo, vk_format,
+                         VK_IMAGE_ASPECT_COLOR_BIT, vk_tiling);
 
    if (!isl_format_supports_ccs_e(devinfo, format))
       return false;
 
-   if (!(image->create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT))
+   if (!(create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT))
       return true;
 
    if (!fmt_list || fmt_list->viewFormatCount == 0)
@@ -180,7 +182,7 @@ all_formats_ccs_e_compatible(const struct gen_device_info *devinfo,
    for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) {
       enum isl_format view_format =
          anv_get_isl_format(devinfo, fmt_list->pViewFormats[i],
-                            VK_IMAGE_ASPECT_COLOR_BIT, image->tiling);
+                            VK_IMAGE_ASPECT_COLOR_BIT, vk_tiling);
 
       if (!isl_formats_are_ccs_e_compatible(devinfo, format, view_format))
          return false;
@@ -654,7 +656,8 @@ anv_image_create(VkDevice _device,
                            IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
 
    image->ccs_e_compatible =
-      all_formats_ccs_e_compatible(&device->info, fmt_list, image);
+      anv_formats_ccs_e_compatible(&device->info, image->create_flags,
+                                   image->vk_format, image->tiling, fmt_list);
 
    uint32_t b;
    for_each_bit(b, image->aspects) {
index dd47df9a09d4cc87f092040aebac0f76d455578f..b41e1a2ddbd1ba4a14ffe7a7aebe7110184e66cf 100644 (file)
@@ -3287,6 +3287,12 @@ anv_get_isl_format(const struct gen_device_info *devinfo, VkFormat vk_format,
    return anv_get_format_plane(devinfo, vk_format, aspect, tiling).isl_format;
 }
 
+bool anv_formats_ccs_e_compatible(const struct gen_device_info *devinfo,
+                                  VkImageCreateFlags create_flags,
+                                  VkFormat vk_format,
+                                  VkImageTiling vk_tiling,
+                                  const VkImageFormatListCreateInfoKHR *fmt_list);
+
 static inline struct isl_swizzle
 anv_swizzle_for_render(struct isl_swizzle swizzle)
 {