Commit 126c9562 authored by Nanley Chery's avatar Nanley Chery
Browse files

isl: Redefine the CCS layout for Gen12



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's avatarKenneth Graunke <kenneth@whitecape.org>
parent 1e912802
......@@ -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, ...) \
......
......@@ -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)
......
......@@ -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;
}
......
......@@ -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
......@@ -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:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment