Mesa (master): anv/image: Check that anv_image is compatible with its modifier

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Apr 8 14:38:25 UTC 2021


Module: Mesa
Branch: master
Commit: a7a59d8dd122898ba1444636d356f060a9217ff5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a7a59d8dd122898ba1444636d356f060a9217ff5

Author: Chad Versace <chad at kiwitree.net>
Date:   Sun Mar 21 17:14:12 2021 -0700

anv/image: Check that anv_image is compatible with its modifier

At end of image creation, check for incompatibilities that
vkGetPhysicalDeviceImageFormatProperties2() has difficulty predicting.

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/1466>

---

 src/intel/vulkan/anv_image.c | 86 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index d6d36738be7..95324aecb8e 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -787,6 +787,88 @@ check_memory_bindings(const struct anv_device *device,
 #endif
 }
 
+/**
+ * Check that the fully-initialized anv_image is compatible with its DRM format
+ * modifier.
+ *
+ * Checking compatibility at the end of image creation is prudent, not
+ * superfluous, because usage of modifiers triggers numerous special cases
+ * throughout queries and image creation, and because
+ * vkGetPhysicalDeviceImageFormatProperties2 has difficulty detecting all
+ * incompatibilities.
+ *
+ * Return VK_ERROR_UNKNOWN if the incompatibility is difficult to detect in
+ * vkGetPhysicalDeviceImageFormatProperties2.  Otherwise, assert fail.
+ *
+ * Ideally, if vkGetPhysicalDeviceImageFormatProperties2() succeeds with a given
+ * modifier, then vkCreateImage() produces an image that is compatible with the
+ * modifier. However, it is difficult to reconcile the two functions to agree
+ * due to their complexity. For example, isl_surf_get_ccs_surf() may
+ * unexpectedly fail in vkCreateImage(), eliminating the image's aux surface
+ * even when the modifier requires one. (Maybe we should reconcile the two
+ * functions despite the difficulty).
+ */
+static VkResult MUST_CHECK
+check_drm_format_mod(const struct anv_device *device,
+                     const struct anv_image *image)
+{
+   /* Image must have a modifier if and only if it has modifier tiling. */
+   assert((image->drm_format_mod != DRM_FORMAT_MOD_INVALID) ==
+          (image->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT));
+
+   if (image->drm_format_mod == DRM_FORMAT_MOD_INVALID)
+      return VK_SUCCESS;
+
+   const struct isl_drm_modifier_info *isl_mod_info =
+      isl_drm_modifier_get_info(image->drm_format_mod);
+
+   /* Driver must support the modifier. */
+   assert(isl_drm_modifier_get_score(&device->info, isl_mod_info->modifier));
+
+   /* Enforced by us, not the Vulkan spec. */
+   assert(image->type == VK_IMAGE_TYPE_2D);
+   assert(!(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT));
+   assert(!(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT));
+   assert(image->levels == 1);
+   assert(image->array_size == 1);
+   assert(image->samples == 1);
+
+   /* FINISHME: Support multi-planar formats with modifiers */
+   assert(image->n_planes == 1);
+   assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
+
+   for (int i = 0; i < image->n_planes; ++i) {
+      const struct anv_image_plane *plane = &image->planes[i];
+      ASSERTED const struct anv_format_plane *plane_format =
+         &image->format->planes[i];
+      ASSERTED const struct isl_format_layout *isl_layout =
+         isl_format_get_layout(plane_format->isl_format);
+
+      /* Enforced by us, not the Vulkan spec. */
+      assert(isl_layout->txc == ISL_TXC_NONE);
+      assert(isl_layout->colorspace == ISL_COLORSPACE_LINEAR ||
+             isl_layout->colorspace == ISL_COLORSPACE_SRGB);
+      assert(!anv_surface_is_valid(&plane->shadow_surface));
+
+      if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) {
+         /* Reject DISJOINT for consistency with the GL driver. */
+         assert(!image->disjoint);
+
+         /* The modifier's required aux usage mandates the image's aux usage.
+          * The inverse, however, does not hold; if the modifier has no aux
+          * usage, then we may enable a private aux surface.
+          */
+         if (plane->aux_usage != isl_mod_info->aux_usage) {
+            return vk_errorf(device, &image->base, VK_ERROR_UNKNOWN,
+                             "image with modifier unexpectedly has wrong aux "
+                             "usage");
+         }
+      }
+   }
+
+   return VK_SUCCESS;
+}
+
 static VkResult
 add_all_surfaces(struct anv_device *device,
                  struct anv_image *image,
@@ -991,6 +1073,10 @@ anv_image_create(VkDevice _device,
    if (r != VK_SUCCESS)
       goto fail;
 
+   r = check_drm_format_mod(device, image);
+   if (r != VK_SUCCESS)
+      goto fail;
+
    *pImage = anv_image_to_handle(image);
 
    return VK_SUCCESS;



More information about the mesa-commit mailing list