isl: Redefine the CCS layout for Gen12
authorNanley Chery <nanley.g.chery@intel.com>
Wed, 20 Mar 2019 01:23:46 +0000 (18:23 -0700)
committerNanley Chery <nanley.g.chery@intel.com>
Mon, 28 Oct 2019 17:47:05 +0000 (10:47 -0700)
The CCS could be described in a number of ways, but this format was
chosen to minimize churn in the drivers. We may decide on an different
direction in the future.

v2. Increase alignment for display surfaces. (Nanley)

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> (v1)
Acked-by: Kenneth Graunke <kenneth@whitecape.org>
src/intel/isl/isl.c
src/intel/isl/isl.h
src/intel/isl/isl_drm.c
src/intel/isl/isl_format_layout.csv
src/intel/isl/isl_gen12.c

index a91c7204f6612b64ad24883aa09e3e73e7ce3dff..5fd6aded2aed34e22fef080ffb6c8d21ad3ae9c1 100644 (file)
@@ -311,6 +311,29 @@ isl_tiling_get_info(enum isl_tiling tiling,
       phys_B = isl_extent2d(128, 32);
       break;
 
+   case ISL_TILING_GEN12_CCS:
+      /* From the Bspec, Gen Graphics > Gen12 > Memory Data Formats > Memory
+       * Compression > Memory Compression - Gen12:
+       *
+       *    4 bits of auxiliary plane data are required for 2 cachelines of
+       *    main surface data. This results in a single cacheline of auxiliary
+       *    plane data mapping to 4 4K pages of main surface data for the 4K
+       *    pages (tile Y ) and 1 64K Tile Ys page.
+       *
+       * The Y-tiled pairing bit of 9 shown in the table below that Bspec
+       * section expresses that the 2 cachelines of main surface data are
+       * horizontally adjacent.
+       *
+       * TODO: Handle Ys, Yf and their pairing bits.
+       *
+       * Therefore, each CCS cacheline represents a 512Bx32 row area and each
+       * element represents a 32Bx4 row area.
+       */
+      assert(format_bpb == 4);
+      logical_el = isl_extent2d(16, 8);
+      phys_B = isl_extent2d(64, 1);
+      break;
+
    default:
       unreachable("not reached");
    } /* end switch */
@@ -391,7 +414,11 @@ isl_surf_choose_tiling(const struct isl_device *dev,
    /* CCS surfaces always use the CCS tiling */
    if (info->usage & ISL_SURF_USAGE_CCS_BIT) {
       assert(isl_format_get_layout(info->format)->txc == ISL_TXC_CCS);
-      assert(tiling_flags == ISL_TILING_CCS_BIT);
+      UNUSED bool ivb_ccs = ISL_DEV_GEN(dev) < 12 &&
+                            tiling_flags == ISL_TILING_CCS_BIT;
+      UNUSED bool tgl_ccs = ISL_DEV_GEN(dev) >= 12 &&
+                            tiling_flags == ISL_TILING_GEN12_CCS_BIT;
+      assert(ivb_ccs != tgl_ccs);
       *tiling = isl_tiling_flag_to_enum(tiling_flags);
       return true;
    }
@@ -919,7 +946,8 @@ isl_calc_array_pitch_el_rows_gen4_2d(
    assert(pitch_sa_rows % fmtl->bh == 0);
    uint32_t pitch_el_rows = pitch_sa_rows / fmtl->bh;
 
-   if (ISL_DEV_GEN(dev) >= 9 && fmtl->txc == ISL_TXC_CCS) {
+   if (ISL_DEV_GEN(dev) >= 9 && ISL_DEV_GEN(dev) <= 11 &&
+       fmtl->txc == ISL_TXC_CCS) {
       /*
        * From the Sky Lake PRM Vol 7, "MCS Buffer for Render Target(s)" (p. 632):
        *
@@ -937,6 +965,8 @@ isl_calc_array_pitch_el_rows_gen4_2d(
        * The first restriction is already handled by isl_choose_image_alignment_el
        * but the second restriction, which is an extension of the first, only
        * applies to qpitch and must be applied here.
+       *
+       * The second restriction disappears on Gen12.
        */
       assert(fmtl->bh == 4);
       pitch_el_rows = isl_align(pitch_el_rows, 256 / 4);
@@ -1544,6 +1574,15 @@ isl_surf_init_s(const struct isl_device *dev,
                                    tile_info.phys_extent_B.height;
       assert(isl_is_pow2(info->min_alignment_B) && isl_is_pow2(tile_size_B));
       base_alignment_B = MAX(info->min_alignment_B, tile_size_B);
+
+      /* The diagram in the Bspec section Memory Compression - Gen12, shows
+       * that the CCS is indexed in 256B chunks. However, the
+       * PLANE_AUX_DIST::Auxiliary Surface Distance field is in units of 4K
+       * pages. We currently don't assign the usage field like we do for main
+       * surfaces, so just use 4K for now.
+       */
+      if (tiling == ISL_TILING_GEN12_CCS)
+         base_alignment_B = MAX(base_alignment_B, 4096);
    }
 
    if (ISL_DEV_GEN(dev) >= 12) {
@@ -1817,9 +1856,35 @@ isl_surf_get_ccs_surf(const struct isl_device *dev,
        (surf->levels > 1 || surf->logical_level0_px.array_len > 1))
       return false;
 
+   /* On Gen12, 8BPP surfaces cannot be compressed if any level is not
+    * 32Bx4row-aligned. For now, just reject the cases where alignment
+    * matters.
+    */
+   if (ISL_DEV_GEN(dev) >= 12 &&
+       isl_format_get_layout(surf->format)->bpb == 8 && surf->levels >= 3) {
+      isl_finishme("%s:%s: CCS for 8BPP textures with 3+ miplevels is "
+                   "disabled, but support for more levels is possible.",
+                   __FILE__, __func__);
+      return false;
+   }
+
+   /* On Gen12, all CCS-compressed surface pitches must be multiples of 512B.
+    */
+   if (ISL_DEV_GEN(dev) >= 12 && surf->row_pitch_B % 512 != 0)
+      return false;
+
    if (isl_format_is_compressed(surf->format))
       return false;
 
+   /* According to GEN:BUG:1406738321, 3D textures need a blit to a new
+    * surface in order to perform a resolve. For now, just disable CCS.
+    */
+   if (ISL_DEV_GEN(dev) >= 12 && surf->dim == ISL_SURF_DIM_3D) {
+      isl_finishme("%s:%s: CCS for 3D textures is disabled, but a workaround"
+                   " is available.", __FILE__, __func__);
+      return false;
+   }
+
    /* TODO: More conditions where it can fail. */
 
    /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
@@ -1836,7 +1901,21 @@ isl_surf_get_ccs_surf(const struct isl_device *dev,
     *     TiledY/TileYs/TileYf non-MSRTs only.
     */
    enum isl_format ccs_format;
-   if (ISL_DEV_GEN(dev) >= 9) {
+   if (ISL_DEV_GEN(dev) >= 12) {
+      /* TODO: Handle the other tiling formats */
+      if (surf->tiling != ISL_TILING_Y0)
+         return false;
+
+      switch (isl_format_get_layout(surf->format)->bpb) {
+      case 8:     ccs_format = ISL_FORMAT_GEN12_CCS_8BPP_Y0;    break;
+      case 16:    ccs_format = ISL_FORMAT_GEN12_CCS_16BPP_Y0;   break;
+      case 32:    ccs_format = ISL_FORMAT_GEN12_CCS_32BPP_Y0;   break;
+      case 64:    ccs_format = ISL_FORMAT_GEN12_CCS_64BPP_Y0;   break;
+      case 128:   ccs_format = ISL_FORMAT_GEN12_CCS_128BPP_Y0;  break;
+      default:
+         return false;
+      }
+   } else if (ISL_DEV_GEN(dev) >= 9) {
       if (!isl_tiling_is_any_y(surf->tiling))
          return false;
 
@@ -1867,18 +1946,39 @@ isl_surf_get_ccs_surf(const struct isl_device *dev,
       return false;
    }
 
-   return isl_surf_init(dev, ccs_surf,
-                        .dim = surf->dim,
-                        .format = ccs_format,
-                        .width = surf->logical_level0_px.width,
-                        .height = surf->logical_level0_px.height,
-                        .depth = surf->logical_level0_px.depth,
-                        .levels = surf->levels,
-                        .array_len = surf->logical_level0_px.array_len,
-                        .samples = 1,
-                        .row_pitch_B = row_pitch_B,
-                        .usage = ISL_SURF_USAGE_CCS_BIT,
-                        .tiling_flags = ISL_TILING_CCS_BIT);
+   if (ISL_DEV_GEN(dev) >= 12) {
+      /* On Gen12, 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.
+       */
+      const bool ok =
+         isl_surf_init(dev, ccs_surf,
+                       .dim = ISL_SURF_DIM_2D,
+                       .format = ccs_format,
+                       .width = isl_surf_get_row_pitch_el(surf),
+                       .height = surf->size_B / surf->row_pitch_B,
+                       .depth = 1,
+                       .levels = 1,
+                       .array_len = 1,
+                       .samples = 1,
+                       .row_pitch_B = row_pitch_B,
+                       .usage = ISL_SURF_USAGE_CCS_BIT,
+                       .tiling_flags = ISL_TILING_GEN12_CCS_BIT);
+      assert(!ok || ccs_surf->size_B == surf->size_B / 256);
+      return ok;
+   } else {
+      return isl_surf_init(dev, ccs_surf,
+                           .dim = surf->dim,
+                           .format = ccs_format,
+                           .width = surf->logical_level0_px.width,
+                           .height = surf->logical_level0_px.height,
+                           .depth = surf->logical_level0_px.depth,
+                           .levels = surf->levels,
+                           .array_len = surf->logical_level0_px.array_len,
+                           .samples = 1,
+                           .row_pitch_B = row_pitch_B,
+                           .usage = ISL_SURF_USAGE_CCS_BIT,
+                           .tiling_flags = ISL_TILING_CCS_BIT);
+   }
 }
 
 #define isl_genX_call(dev, func, ...)              \
index 5b7458a228524fcf7b45dd92a93b8f5a1ace49e9..2a840f48f72aac68dc0c129fe6e2854f01721e0a 100644 (file)
@@ -389,6 +389,11 @@ enum isl_format {
    ISL_FORMAT_GEN9_CCS_32BPP,
    ISL_FORMAT_GEN9_CCS_64BPP,
    ISL_FORMAT_GEN9_CCS_128BPP,
+   ISL_FORMAT_GEN12_CCS_8BPP_Y0,
+   ISL_FORMAT_GEN12_CCS_16BPP_Y0,
+   ISL_FORMAT_GEN12_CCS_32BPP_Y0,
+   ISL_FORMAT_GEN12_CCS_64BPP_Y0,
+   ISL_FORMAT_GEN12_CCS_128BPP_Y0,
 
    /* An upper bound on the supported format enumerations */
    ISL_NUM_FORMATS,
@@ -465,6 +470,7 @@ enum isl_tiling {
    ISL_TILING_Ys, /**< Standard 64K tiling. The 's' means "sixty-four". */
    ISL_TILING_HIZ, /**< Tiling format for HiZ surfaces */
    ISL_TILING_CCS, /**< Tiling format for CCS surfaces */
+   ISL_TILING_GEN12_CCS, /**< Tiling format for Gen12 CCS surfaces */
 };
 
 /**
@@ -480,6 +486,7 @@ typedef uint32_t isl_tiling_flags_t;
 #define ISL_TILING_Ys_BIT                 (1u << ISL_TILING_Ys)
 #define ISL_TILING_HIZ_BIT                (1u << ISL_TILING_HIZ)
 #define ISL_TILING_CCS_BIT                (1u << ISL_TILING_CCS)
+#define ISL_TILING_GEN12_CCS_BIT          (1u << ISL_TILING_GEN12_CCS)
 #define ISL_TILING_ANY_MASK               (~0u)
 #define ISL_TILING_NON_LINEAR_MASK        (~ISL_TILING_LINEAR_BIT)
 
index 196ecf7f88c4b644fe8bbb5abce785622affc3b1..cd8c2422e57e9bc1550542be93a24db1bd09f5ca 100644 (file)
@@ -48,6 +48,7 @@ isl_tiling_to_i915_tiling(enum isl_tiling tiling)
    case ISL_TILING_W:
    case ISL_TILING_Yf:
    case ISL_TILING_Ys:
+   case ISL_TILING_GEN12_CCS:
       return I915_TILING_NONE;
    }
 
index d9142623f07bc81f0bb09457bccabb3c18cbbf94..81c9e39d7352157dbc5a025da4facc7f32e3a2b1 100644 (file)
@@ -343,3 +343,8 @@ GEN7_CCS_128BPP_Y           ,   1,  2,  4,  1,     ,     ,     ,     ,     ,
 GEN9_CCS_32BPP              ,   2,  8,  4,  1,     ,     ,     ,     ,     ,     ,    ,      ,       ,   ccs
 GEN9_CCS_64BPP              ,   2,  4,  4,  1,     ,     ,     ,     ,     ,     ,    ,      ,       ,   ccs
 GEN9_CCS_128BPP             ,   2,  2,  4,  1,     ,     ,     ,     ,     ,     ,    ,      ,       ,   ccs
+GEN12_CCS_8BPP_Y0           ,   4, 32,  4,  1,     ,     ,     ,     ,     ,     ,    ,      ,       ,   ccs
+GEN12_CCS_16BPP_Y0          ,   4, 16,  4,  1,     ,     ,     ,     ,     ,     ,    ,      ,       ,   ccs
+GEN12_CCS_32BPP_Y0          ,   4,  8,  4,  1,     ,     ,     ,     ,     ,     ,    ,      ,       ,   ccs
+GEN12_CCS_64BPP_Y0          ,   4,  4,  4,  1,     ,     ,     ,     ,     ,     ,    ,      ,       ,   ccs
+GEN12_CCS_128BPP_Y0         ,   4,  2,  4,  1,     ,     ,     ,     ,     ,     ,    ,      ,       ,   ccs
index 44dd462cbbd317487a8a05d24ee196e185b3bb9f..c177b4872139a974dfd2dddff2cf7e46c2a87d52 100644 (file)
@@ -36,6 +36,14 @@ isl_gen12_choose_image_alignment_el(const struct isl_device *dev,
    /* Handled by isl_choose_image_alignment_el */
    assert(info->format != ISL_FORMAT_HIZ);
 
+   const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
+   if (fmtl->txc == ISL_TXC_CCS) {
+      /* This CCS compresses a 2D-view of the entire surface. */
+      assert(info->levels == 1 && info->array_len == 1 && info->depth == 1);
+      *image_align_el = isl_extent3d(1, 1, 1);
+      return;
+   }
+
    if (isl_surf_usage_is_depth(info->usage)) {
       /* The alignment parameters for depth buffers are summarized in the
        * following table: