Mesa (staging/22.1): anv: track if images can be fast clear with non-zero color

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 27 18:15:09 UTC 2022


Module: Mesa
Branch: staging/22.1
Commit: a84f27ea3ef02a1c159d8b584cab1aab5b19b0c8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a84f27ea3ef02a1c159d8b584cab1aab5b19b0c8

Author: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Date:   Fri Jul  1 10:44:48 2022 +0300

anv: track if images can be fast clear with non-zero color

Because clear colors are stored as 4 32bit component values, there is
an issue if you try to format instance :

   - clearing in R16G16_UNORM
   - draw in R32_UINT

Clear will use 2 components of the clear color in dword0 & dword1.

While draw will use only one component of dword0.

This change uses the mutable format information to track whether clear
colors can be non-zero for fast clears.

With :

   - non mutable formats, we can fast clear with any color on Gfx > 8
   - mutable formats with incompatible component sizes, we can only
     fast clear with 0 color

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Cc: mesa-stable
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5930
Reviewed-by: Nanley Chery <nanley.g.chery at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17329>
(cherry picked from commit 682383e5b3328d4a7418ce802d2226c87bbda966)

Conflicts:
	src/intel/vulkan/anv_image.c

---

 .pick_status.json              |  2 +-
 src/intel/vulkan/anv_image.c   | 74 ++++++++++++++++++++++++++++++++++++++++++
 src/intel/vulkan/anv_private.h | 16 +++++++++
 3 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/.pick_status.json b/.pick_status.json
index 946576f5353..2e92243d20d 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -6979,7 +6979,7 @@
         "description": "anv: track if images can be fast clear with non-zero color",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null
     },
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index 7422ccdaf9e..7728f382272 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -368,6 +368,64 @@ anv_image_plane_needs_shadow_surface(const struct intel_device_info *devinfo,
    return false;
 }
 
+static bool
+can_fast_clear_with_non_zero_color(const struct intel_device_info *devinfo,
+                                   const struct anv_image *image,
+                                   uint32_t plane,
+                                   const VkImageFormatListCreateInfoKHR *fmt_list)
+{
+   /* If we don't have an AUX surface where fast clears apply, we can return
+    * early.
+    */
+   if (!isl_aux_usage_has_fast_clears(image->planes[plane].aux_usage))
+      return false;
+
+   /* Non mutable image, we can fast clear with any color supported by HW.
+    */
+   if (!(image->vk.create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT))
+      return true;
+
+   /* Mutable image with no format list, we have to assume all formats */
+   if (!fmt_list || fmt_list->viewFormatCount == 0)
+      return false;
+
+   enum isl_format img_format = image->planes[plane].primary_surface.isl.format;
+
+   /* Check bit compatibility for clear color components */
+   for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) {
+      struct anv_format_plane view_format_plane =
+         anv_get_format_plane(devinfo, fmt_list->pViewFormats[i],
+                              plane, image->vk.tiling);
+
+      enum isl_format view_format = view_format_plane.isl_format;
+
+      if (!isl_formats_have_same_bits_per_channel(img_format, view_format))
+         return false;
+
+      /* Switching between any of those format types on Gfx7/8 will cause
+       * problems https://gitlab.freedesktop.org/mesa/mesa/-/issues/1711
+       */
+      if (devinfo->ver <= 8) {
+         if (isl_format_has_float_channel(img_format) &&
+             !isl_format_has_float_channel(view_format))
+            return false;
+
+         if (isl_format_has_int_channel(img_format) &&
+             !isl_format_has_int_channel(view_format))
+            return false;
+
+         if (isl_format_has_unorm_channel(img_format) &&
+             !isl_format_has_unorm_channel(view_format))
+            return false;
+
+         if (isl_format_has_snorm_channel(img_format) &&
+             !isl_format_has_snorm_channel(view_format))
+            return false;
+      }
+   }
+
+   return true;
+}
 static enum isl_format
 anv_get_isl_format_with_usage(const struct intel_device_info *devinfo,
                               VkFormat vk_format,
@@ -1381,6 +1439,14 @@ anv_image_init(struct anv_device *device, struct anv_image *image,
    if (r != VK_SUCCESS)
       goto fail;
 
+   /* Once we have all the bindings, determine whether we can do non 0 fast
+    * clears for each plane.
+    */
+   for (uint32_t p = 0; p < image->n_planes; p++) {
+      image->planes[p].can_non_zero_fast_clear =
+         can_fast_clear_with_non_zero_color(&device->info, image, p, fmt_list);
+   }
+
    return VK_SUCCESS;
 
 fail:
@@ -2267,6 +2333,10 @@ anv_layout_to_fast_clear_type(const struct intel_device_info * const devinfo,
           */
          return ANV_FAST_CLEAR_DEFAULT_VALUE;
       } else if (layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+         /* The image might not support non zero fast clears when mutable. */
+         if (!image->planes[plane].can_non_zero_fast_clear)
+            return ANV_FAST_CLEAR_DEFAULT_VALUE;
+
          /* When we're in a render pass we have the clear color data from the
           * VkRenderPassBeginInfo and we can use arbitrary clear colors.  They
           * must get partially resolved before we leave the render pass.
@@ -2275,6 +2345,10 @@ anv_layout_to_fast_clear_type(const struct intel_device_info * const devinfo,
       } else if (image->planes[plane].aux_usage == ISL_AUX_USAGE_MCS ||
                  image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) {
          if (devinfo->ver >= 11) {
+            /* The image might not support non zero fast clears when mutable. */
+            if (!image->planes[plane].can_non_zero_fast_clear)
+               return ANV_FAST_CLEAR_DEFAULT_VALUE;
+
             /* On ICL and later, the sampler hardware uses a copy of the clear
              * value that is encoded as a pixel value.  Therefore, we can use
              * any clear color we like for sampling.
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 8b9029906d9..2a9325f9abb 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -3889,6 +3889,22 @@ struct anv_image {
 
       /** Location of the fast clear state.  */
       struct anv_image_memory_range fast_clear_memory_range;
+
+      /**
+       * Whether this image can be fast cleared with non-zero clear colors.
+       * This can happen with mutable images when formats of different bit
+       * sizes per components are used.
+       *
+       * On Gfx9+, because the clear colors are stored as a 4 components 32bit
+       * values, we can clear in R16G16_UNORM (store 2 16bit values in the
+       * components 0 & 1 of the clear color) and then draw in R32_UINT which
+       * would interpret the clear color as a single component value, using
+       * only the first 16bit component of the previous written clear color.
+       *
+       * On Gfx7/7.5/8, only CC_ZERO/CC_ONE clear colors are supported, this
+       * boolean will prevent the usage of CC_ONE.
+       */
+      bool can_non_zero_fast_clear;
    } planes[3];
 };
 



More information about the mesa-commit mailing list