OSDN Git Service

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 a91c720..5fd6ade 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 5b7458a..2a840f4 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 196ecf7..cd8c242 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 d914262..81c9e39 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 44dd462..c177b48 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: