isl: Take a hiz_or_mcs_surf in isl_surf_supports_ccs
authorJason Ekstrand <jason@jlekstrand.net>
Fri, 18 Jun 2021 22:12:32 +0000 (17:12 -0500)
committerMarge Bot <eric+marge@anholt.net>
Thu, 24 Jun 2021 13:57:40 +0000 (13:57 +0000)
Whether or not a surface supports CCS on Tigerlake and later is
dependent not only on the main surface but also on the MCS or HiZ
surface, if any.  We were doing some of these checks in
isl_get_ccs_surf based on the extra_aux parameter but not as many as we
probably should.  In particular, we were really only checking HiZ
conditions and nothing for MCS.  It also meant that, in spite of the
symmetry in names, the checks in isl_surf_get_ccs_surf were more
complete than in isl_surf_supports_ccs.

Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11479>

src/intel/isl/isl.c
src/intel/isl/isl.h
src/intel/vulkan/anv_image.c

index 3390604..ed52b37 100644 (file)
@@ -2007,7 +2007,8 @@ isl_surf_get_mcs_surf(const struct isl_device *dev,
 
 bool
 isl_surf_supports_ccs(const struct isl_device *dev,
-                      const struct isl_surf *surf)
+                      const struct isl_surf *surf,
+                      const struct isl_surf *hiz_or_mcs_surf)
 {
    /* CCS support does not exist prior to Gfx7 */
    if (ISL_GFX_VER(dev) <= 6)
@@ -2050,8 +2051,37 @@ isl_surf_supports_ccs(const struct isl_device *dev,
       return false;
 
    if (ISL_GFX_VER(dev) >= 12) {
-      if (isl_surf_usage_is_stencil(surf->usage) && surf->samples > 1)
-         return false;
+      if (isl_surf_usage_is_stencil(surf->usage)) {
+         /* HiZ and MCS aren't allowed with stencil */
+         assert(hiz_or_mcs_surf == NULL || hiz_or_mcs_surf->size_B == 0);
+
+         /* Multi-sampled stencil cannot have CCS */
+         if (surf->samples > 1)
+            return false;
+      } else if (isl_surf_usage_is_depth(surf->usage)) {
+         const struct isl_surf *hiz_surf = hiz_or_mcs_surf;
+
+         /* With depth surfaces, HIZ is required for CCS. */
+         if (hiz_surf == NULL || hiz_surf->size_B == 0)
+            return false;
+
+         assert(hiz_surf->usage & ISL_SURF_USAGE_HIZ_BIT);
+         assert(hiz_surf->tiling == ISL_TILING_HIZ);
+         assert(hiz_surf->format == ISL_FORMAT_HIZ);
+      } else if (surf->samples > 1) {
+         const struct isl_surf *mcs_surf = hiz_or_mcs_surf;
+
+         /* With multisampled color, CCS requires MCS */
+         if (mcs_surf == NULL || mcs_surf->size_B == 0)
+            return false;
+
+         assert(mcs_surf->usage & ISL_SURF_USAGE_MCS_BIT);
+         assert(isl_tiling_is_any_y(mcs_surf->tiling));
+         assert(isl_format_is_mcs(mcs_surf->format));
+      } else {
+         /* Single-sampled color can't have MCS or HiZ */
+         assert(hiz_or_mcs_surf == NULL || hiz_or_mcs_surf->size_B == 0);
+      }
 
       /* On Gfx12, all CCS-compressed surface pitches must be multiples of
        * 512B.
@@ -2093,6 +2123,9 @@ isl_surf_supports_ccs(const struct isl_device *dev,
       if (isl_surf_usage_is_depth_or_stencil(surf->usage))
          return false;
 
+      /* We're single-sampled color so having HiZ or MCS makes no sense */
+      assert(hiz_or_mcs_surf == NULL || hiz_or_mcs_surf->size_B == 0);
+
       /* The PRM doesn't say this explicitly, but fast-clears don't appear to
        * work for 3D textures until gfx9 where the layout of 3D textures
        * changes to match 2D array textures.
@@ -2152,15 +2185,15 @@ isl_surf_get_ccs_surf(const struct isl_device *dev,
       assert(extra_aux_surf);
    assert(!(aux_surf->usage & ISL_SURF_USAGE_CCS_BIT));
 
-   if (!isl_surf_supports_ccs(dev, surf))
+   const struct isl_surf *hiz_or_mcs_surf =
+      aux_surf->size_B > 0 ? aux_surf : NULL;
+   struct isl_surf *ccs_surf =
+      aux_surf->size_B > 0 ? extra_aux_surf : aux_surf;
+
+   if (!isl_surf_supports_ccs(dev, surf, hiz_or_mcs_surf))
       return false;
 
    if (ISL_GFX_VER(dev) >= 12) {
-      /* With depth surfaces, HIZ is required for CCS. */
-      if (surf->usage & ISL_SURF_USAGE_DEPTH_BIT &&
-          aux_surf->tiling != ISL_TILING_HIZ)
-         return false;
-
       enum isl_format ccs_format;
       switch (isl_format_get_layout(surf->format)->bpb) {
       case 8:     ccs_format = ISL_FORMAT_GFX12_CCS_8BPP_Y0;    break;
@@ -2175,8 +2208,6 @@ isl_surf_get_ccs_surf(const struct isl_device *dev,
       /* On Gfx12, the CCS is a scaled-down version of the main surface. We
        * model this as the CCS compressing a 2D-view of the entire surface.
        */
-      struct isl_surf *ccs_surf =
-         aux_surf->size_B > 0 ? extra_aux_surf : aux_surf;
       const bool ok =
          isl_surf_init(dev, ccs_surf,
                        .dim = ISL_SURF_DIM_2D,
@@ -2220,7 +2251,7 @@ isl_surf_get_ccs_surf(const struct isl_device *dev,
          unreachable("Invalid tiling format");
       }
 
-      return isl_surf_init(dev, aux_surf,
+      return isl_surf_init(dev, ccs_surf,
                            .dim = surf->dim,
                            .format = ccs_format,
                            .width = surf->logical_level0_px.width,
index 3ae038f..4b18fbe 100644 (file)
@@ -1799,6 +1799,14 @@ isl_format_has_bc_compression(enum isl_format fmt)
 }
 
 static inline bool
+isl_format_is_mcs(enum isl_format fmt)
+{
+   const struct isl_format_layout *fmtl = isl_format_get_layout(fmt);
+
+   return fmtl->txc == ISL_TXC_MCS;
+}
+
+static inline bool
 isl_format_is_planar(enum isl_format fmt)
 {
    return fmt == ISL_FORMAT_PLANAR_420_8 ||
@@ -2204,7 +2212,8 @@ isl_surf_get_tile_info(const struct isl_surf *surf,
 
 bool
 isl_surf_supports_ccs(const struct isl_device *dev,
-                      const struct isl_surf *surf);
+                      const struct isl_surf *surf,
+                      const struct isl_surf *hiz_or_mcs_surf);
 
 bool
 isl_surf_get_hiz_surf(const struct isl_device *dev,
index 4f6a6e0..9453f3f 100644 (file)
@@ -559,7 +559,8 @@ add_aux_surface_if_supported(struct anv_device *device,
                                  &image->planes[plane].aux_surface.isl);
       assert(ok);
       if (!isl_surf_supports_ccs(&device->isl_dev,
-                                 &image->planes[plane].primary_surface.isl)) {
+                                 &image->planes[plane].primary_surface.isl,
+                                 &image->planes[plane].aux_surface.isl)) {
          image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ;
       } else if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
                                  VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) &&
@@ -593,7 +594,8 @@ add_aux_surface_if_supported(struct anv_device *device,
          return VK_SUCCESS;
 
       if (!isl_surf_supports_ccs(&device->isl_dev,
-                                 &image->planes[plane].primary_surface.isl))
+                                 &image->planes[plane].primary_surface.isl,
+                                 NULL))
          return VK_SUCCESS;
 
       image->planes[plane].aux_usage = ISL_AUX_USAGE_STC_CCS;