diff options
Diffstat (limited to 'src/intel/isl/isl.c')
-rw-r--r-- | src/intel/isl/isl.c | 130 |
1 files changed, 115 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, ...) \ |