summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/intel/isl/isl.c130
-rw-r--r--src/intel/isl/isl.h7
-rw-r--r--src/intel/isl/isl_drm.c1
-rw-r--r--src/intel/isl/isl_format_layout.csv5
-rw-r--r--src/intel/isl/isl_gen12.c8
5 files changed, 136 insertions, 15 deletions
diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c
index a91c7204f66..5fd6aded2ae 100644
--- a/src/intel/isl/isl.c
+++ b/src/intel/isl/isl.c
@@ -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, ...) \
diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h
index 5b7458a2285..2a840f48f72 100644
--- a/src/intel/isl/isl.h
+++ b/src/intel/isl/isl.h
@@ -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)
diff --git a/src/intel/isl/isl_drm.c b/src/intel/isl/isl_drm.c
index 196ecf7f88c..cd8c2422e57 100644
--- a/src/intel/isl/isl_drm.c
+++ b/src/intel/isl/isl_drm.c
@@ -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;
}
diff --git a/src/intel/isl/isl_format_layout.csv b/src/intel/isl/isl_format_layout.csv
index d9142623f07..81c9e39d735 100644
--- a/src/intel/isl/isl_format_layout.csv
+++ b/src/intel/isl/isl_format_layout.csv
@@ -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
diff --git a/src/intel/isl/isl_gen12.c b/src/intel/isl/isl_gen12.c
index 44dd462cbbd..c177b487213 100644
--- a/src/intel/isl/isl_gen12.c
+++ b/src/intel/isl/isl_gen12.c
@@ -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: