diff options
Diffstat (limited to 'src/intel/isl')
-rw-r--r-- | src/intel/isl/isl.c | 130 | ||||
-rw-r--r-- | src/intel/isl/isl.h | 7 | ||||
-rw-r--r-- | src/intel/isl/isl_drm.c | 1 | ||||
-rw-r--r-- | src/intel/isl/isl_format_layout.csv | 5 | ||||
-rw-r--r-- | src/intel/isl/isl_gen12.c | 8 |
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: |