[Mesa-stable] [PATCH] anv: Restrict some fast-clear values gen7-8

Nanley Chery nanleychery at gmail.com
Tue Oct 2 00:48:23 UTC 2018


The Vulkan API was recently clarified to allow image views of different
formats to be used for rendering to the same image. Due to certain
incompatible clear-color encodings on gen7-8, we must be more careful
about which fast-clear values we allow.

Makes the following crucible test pass pre-SKL:
func.renderpass.clear.color-view-one

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105826
Cc: <mesa-stable at lists.freedesktop.org>
---

The crucible test currently only exists in a merge request:
https://gitlab.freedesktop.org/mesa/crucible/merge_requests/11

 src/intel/vulkan/anv_image.c       | 36 ++++++++++++++++++++++++++++++
 src/intel/vulkan/anv_private.h     |  6 +++++
 src/intel/vulkan/genX_cmd_buffer.c | 19 +++++++++++++---
 3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index b0d8c560adb..4eb06501f8d 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -156,6 +156,40 @@ add_surface(struct anv_image *image, struct anv_surface *surf, uint32_t plane)
                                          surf->isl.alignment_B);
 }
 
+static bool
+all_formats_flt_xor_int(const struct gen_device_info *devinfo,
+                       const struct VkImageCreateInfo *vk_info)
+{
+   if (!(vk_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT))
+      return true;
+
+   const VkImageFormatListCreateInfoKHR *fmt_list =
+      vk_find_struct_const(vk_info->pNext, IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
+
+   if (!fmt_list || fmt_list->viewFormatCount == 0)
+      return false;
+
+   enum isl_format format =
+      anv_get_isl_format(devinfo, vk_info->format,
+                         VK_IMAGE_ASPECT_COLOR_BIT, vk_info->tiling);
+
+   const bool is_int = isl_format_has_int_channel(format) ||
+                       isl_format_has_uint_channel(format);
+
+   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, vk_info->tiling);
+
+      const bool view_is_int = isl_format_has_int_channel(view_format) ||
+                               isl_format_has_uint_channel(view_format);
+
+      if (is_int != view_is_int)
+         return false;
+   }
+
+   return true;
+}
 
 static bool
 all_formats_ccs_e_compatible(const struct gen_device_info *devinfo,
@@ -593,6 +627,8 @@ anv_image_create(VkDevice _device,
    image->usage = pCreateInfo->usage;
    image->tiling = pCreateInfo->tiling;
    image->disjoint = pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT;
+   image->fmts_flt_xor_int =
+      all_formats_flt_xor_int(&device->info, pCreateInfo);
    image->needs_set_tiling = wsi_info && wsi_info->scanout;
    image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier :
                                           DRM_FORMAT_MOD_INVALID;
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 60f40c7e2ae..07dcc9f9b37 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -2641,6 +2641,12 @@ struct anv_image {
    VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */
    VkImageTiling tiling; /** VkImageCreateInfo::tiling */
 
+   /**
+    * True if this image may be used with integer or float formats, but not
+    * both.
+    */
+   bool fmts_flt_xor_int;
+
    /** True if this is needs to be bound to an appropriately tiled BO.
     *
     * When not using modifiers, consumers such as X11, Wayland, and KMS need
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index 099c30f3d66..da01795db10 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -322,9 +322,22 @@ color_attachment_compute_aux_usage(struct anv_device * device,
           render_area.extent.height != iview->extent.height)
          att_state->fast_clear = false;
 
-      /* On Broadwell and earlier, we can only handle 0/1 clear colors */
-      if (GEN_GEN <= 8 && !att_state->clear_color_is_zero_one)
-         att_state->fast_clear = false;
+      /* Broadwell and earlier have restrictions due to integer and float
+       * texture clears being viewed incorrectly for certain values. Float
+       * texture clears to 1.0 (0x3F80_0000) are encoded as 1 in the surface
+       * state. Integer texture clears to 1 (0x1) share the same encoding. To
+       * avoid this conflict, only allow clearing with ones if the image format
+       * type is immutable.
+       */
+      if (GEN_GEN <= 8) {
+         if (!iview->image->fmts_flt_xor_int &&
+             !att_state->clear_color_is_zero) {
+            att_state->fast_clear = false;
+         } else if (iview->image->fmts_flt_xor_int &&
+                    !att_state->clear_color_is_zero_one) {
+            att_state->fast_clear = false;
+         }
+      }
 
       /* We only allow fast clears to the first slice of an image (level 0,
        * layer 0) and only for the entire slice.  This guarantees us that, at
-- 
2.19.0



More information about the mesa-stable mailing list