899
943
* Height, width, and layout of MCS buffer in this case must match with
900
944
* Render Target height, width, and layout. MCS buffer is tiledY.
902
* To avoid wasting memory, choose the smallest alignment possible:
903
* HALIGN_4 and VALIGN_4.
946
* Pick a vertical and horizontal alignment that matches the main render
947
* target. Vertical alignment is important for properly spacing an array
948
* of MCS images. Horizontal alignment is not expected to matter because
949
* MCS is not mipmapped. Regardless, we pick a valid value here.
905
*image_align_el = isl_extent3d(4, 4, 1);
951
if (ISL_GFX_VERX10(dev) >= 125) {
952
*image_align_el = isl_extent3d(128 * 8 / fmtl->bpb, 4, 1);
953
} else if (ISL_GFX_VER(dev) >= 8) {
954
*image_align_el = isl_extent3d(16, 4, 1);
956
*image_align_el = isl_extent3d(4, 4, 1);
907
959
} else if (fmtl->txc == ISL_TXC_HIZ) {
908
960
assert(ISL_GFX_VER(dev) >= 6);
1763
1815
return likely(bits != 0 && 1 <= n && n <= (1 << bits));
1818
void PRINTFLIKE(4, 5)
1819
_isl_notify_failure(const struct isl_surf_init_info *surf_info,
1820
const char *file, int line, const char *fmt, ...)
1822
if (!INTEL_DEBUG(DEBUG_ISL))
1828
int ret = vsnprintf(msg, sizeof(msg), fmt, ap);
1829
assert(ret < sizeof(msg));
1832
#define PRINT_USAGE(bit, str) \
1833
(surf_info->usage & ISL_SURF_USAGE_##bit##_BIT) ? ("+"str) : ""
1834
#define PRINT_TILING(bit, str) \
1835
(surf_info->tiling_flags & ISL_TILING_##bit##_BIT) ? ("+"str) : ""
1837
snprintf(msg + ret, sizeof(msg) - ret,
1838
" extent=%ux%ux%u dim=%s msaa=%ux levels=%u rpitch=%u fmt=%s "
1839
"usages=%s%s%s%s%s%s%s%s%s%s%s%s%s%s "
1840
"tiling_flags=%s%s%s%s%s%s%s%s%s%s%s",
1841
surf_info->width, surf_info->height,
1842
surf_info->dim == ISL_SURF_DIM_3D ?
1843
surf_info->depth : surf_info->array_len,
1844
surf_info->dim == ISL_SURF_DIM_1D ? "1d" :
1845
surf_info->dim == ISL_SURF_DIM_2D ? "2d" : "3d",
1846
surf_info->samples, surf_info->levels,
1847
surf_info->row_pitch_B,
1848
isl_format_get_name(surf_info->format) + strlen("ISL_FORMAT_"),
1850
PRINT_USAGE(RENDER_TARGET, "rt"),
1851
PRINT_USAGE(DEPTH, "depth"),
1852
PRINT_USAGE(STENCIL, "stenc"),
1853
PRINT_USAGE(TEXTURE, "tex"),
1854
PRINT_USAGE(CUBE, "cube"),
1855
PRINT_USAGE(DISABLE_AUX, "noaux"),
1856
PRINT_USAGE(DISPLAY, "disp"),
1857
PRINT_USAGE(HIZ, "hiz"),
1858
PRINT_USAGE(MCS, "mcs"),
1859
PRINT_USAGE(CCS, "ccs"),
1860
PRINT_USAGE(VERTEX_BUFFER, "vb"),
1861
PRINT_USAGE(INDEX_BUFFER, "ib"),
1862
PRINT_USAGE(CONSTANT_BUFFER, "const"),
1863
PRINT_USAGE(STAGING, "stage"),
1865
PRINT_TILING(LINEAR, "linear"),
1866
PRINT_TILING(W, "W"),
1867
PRINT_TILING(X, "X"),
1868
PRINT_TILING(Y0, "Y0"),
1869
PRINT_TILING(Yf, "Yf"),
1870
PRINT_TILING(Ys, "Ys"),
1871
PRINT_TILING(4, "4"),
1872
PRINT_TILING(64, "64"),
1873
PRINT_TILING(HIZ, "hiz"),
1874
PRINT_TILING(CCS, "ccs"),
1875
PRINT_TILING(GFX12_CCS, "ccs12"));
1880
mesa_logd("%s:%i: %s", file, line, msg);
1767
1884
isl_calc_row_pitch(const struct isl_device *dev,
1768
1885
const struct isl_surf_init_info *surf_info,
1802
1927
if ((surf_info->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT |
1803
1928
ISL_SURF_USAGE_TEXTURE_BIT |
1804
1929
ISL_SURF_USAGE_STORAGE_BIT)) &&
1805
!pitch_in_range(row_pitch_B, RENDER_SURFACE_STATE_SurfacePitch_bits(dev->info)))
1930
!pitch_in_range(row_pitch_B, RENDER_SURFACE_STATE_SurfacePitch_bits(dev->info))) {
1931
return notify_failure(surf_info,
1932
"row pitch (%uB) not in range of "
1933
"RENDER_SURFACE_STATE::SurfacePitch",
1808
1937
if ((surf_info->usage & (ISL_SURF_USAGE_CCS_BIT |
1809
1938
ISL_SURF_USAGE_MCS_BIT)) &&
1810
!pitch_in_range(row_pitch_tl, RENDER_SURFACE_STATE_AuxiliarySurfacePitch_bits(dev->info)))
1939
!pitch_in_range(row_pitch_tl, RENDER_SURFACE_STATE_AuxiliarySurfacePitch_bits(dev->info))) {
1940
return notify_failure(surf_info,
1941
"row_pitch_tl=%u not in range of "
1942
"RENDER_SURFACE_STATE::AuxiliarySurfacePitch",
1813
1946
if ((surf_info->usage & ISL_SURF_USAGE_DEPTH_BIT) &&
1814
!pitch_in_range(row_pitch_B, _3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info)))
1947
!pitch_in_range(row_pitch_B, _3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info))) {
1948
return notify_failure(surf_info,
1949
"row pitch (%uB) not in range of "
1950
"3DSTATE_DEPTH_BUFFER::SurfacePitch",
1817
1954
if ((surf_info->usage & ISL_SURF_USAGE_HIZ_BIT) &&
1818
!pitch_in_range(row_pitch_B, _3DSTATE_HIER_DEPTH_BUFFER_SurfacePitch_bits(dev->info)))
1955
!pitch_in_range(row_pitch_B, _3DSTATE_HIER_DEPTH_BUFFER_SurfacePitch_bits(dev->info))) {
1956
return notify_failure(surf_info,
1957
"row pitch (%uB) not in range of "
1958
"3DSTATE_HIER_DEPTH_BUFFER::SurfacePitch",
1821
1962
const uint32_t stencil_pitch_bits = dev->use_separate_stencil ?
1822
1963
_3DSTATE_STENCIL_BUFFER_SurfacePitch_bits(dev->info) :
1823
1964
_3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info);
1825
1966
if ((surf_info->usage & ISL_SURF_USAGE_STENCIL_BIT) &&
1826
!pitch_in_range(row_pitch_B, stencil_pitch_bits))
1967
!pitch_in_range(row_pitch_B, stencil_pitch_bits)) {
1968
return notify_failure(surf_info,
1969
"row pitch (%uB) not in range of "
1970
"3DSTATE_STENCIL_BUFFER/3DSTATE_DEPTH_BUFFER::SurfacePitch",
1829
1974
if ((surf_info->usage & ISL_SURF_USAGE_CPB_BIT) &&
1830
1975
!pitch_in_range(row_pitch_B, _3DSTATE_CPSIZE_CONTROL_BUFFER_SurfacePitch_bits(dev->info)))
1984
isl_calc_size(const struct isl_device *dev,
1985
const struct isl_surf_init_info *info,
1986
const struct isl_tile_info *tile_info,
1987
const struct isl_extent4d *phys_total_el,
1988
uint32_t array_pitch_el_rows,
1989
uint32_t row_pitch_B,
1990
uint64_t *out_size_B)
1993
if (tile_info->tiling == ISL_TILING_LINEAR) {
1994
/* LINEAR tiling has no concept of intra-tile arrays */
1995
assert(phys_total_el->d == 1 && phys_total_el->a == 1);
1997
size_B = (uint64_t) row_pitch_B * phys_total_el->h;
2000
/* Pitches must make sense with the tiling */
2001
assert(row_pitch_B % tile_info->phys_extent_B.width == 0);
2003
uint32_t array_slices, array_pitch_tl_rows;
2004
if (phys_total_el->d > 1) {
2005
assert(phys_total_el->a == 1);
2006
array_pitch_tl_rows = isl_assert_div(array_pitch_el_rows,
2007
tile_info->logical_extent_el.h);
2008
array_slices = isl_align_div(phys_total_el->d,
2009
tile_info->logical_extent_el.d);
2010
} else if (phys_total_el->a > 1) {
2011
assert(phys_total_el->d == 1);
2012
array_pitch_tl_rows = isl_assert_div(array_pitch_el_rows,
2013
tile_info->logical_extent_el.h);
2014
array_slices = isl_align_div(phys_total_el->a,
2015
tile_info->logical_extent_el.a);
2017
assert(phys_total_el->d == 1 && phys_total_el->a == 1);
2018
array_pitch_tl_rows = 0;
2022
const uint32_t total_h_tl =
2023
(array_slices - 1) * array_pitch_tl_rows +
2024
isl_align_div(phys_total_el->h, tile_info->logical_extent_el.height);
2026
size_B = (uint64_t) total_h_tl * tile_info->phys_extent_B.height *
2030
if (ISL_GFX_VER(dev) < 9) {
2031
/* From the Broadwell PRM Vol 5, Surface Layout:
2033
* "In addition to restrictions on maximum height, width, and depth,
2034
* surfaces are also restricted to a maximum size in bytes. This
2035
* maximum is 2 GB for all products and all surface types."
2037
* This comment is applicable to all Pre-gfx9 platforms.
2039
if (size_B > (uint64_t) 1 << 31) {
2040
return notify_failure(
2042
"calculated size (%"PRIu64"B) exceeds platform limit of (1 << 31)",
2045
} else if (ISL_GFX_VER(dev) < 11) {
2046
/* From the Skylake PRM Vol 5, Maximum Surface Size in Bytes:
2047
* "In addition to restrictions on maximum height, width, and depth,
2048
* surfaces are also restricted to a maximum size of 2^38 bytes.
2049
* All pixels within the surface must be contained within 2^38 bytes
2050
* of the base address."
2052
if (size_B > (uint64_t) 1 << 38) {
2053
return notify_failure(
2055
"calculated size (%"PRIu64"B) exceeds platform limit of (1 << 38)",
2059
/* gfx11+ platforms raised this limit to 2^44 bytes. */
2060
if (size_B > (uint64_t) 1 << 44) {
2061
return notify_failure(
2063
"calculated size (%"PRIu64"B) exceeds platform limit of (1 << 44)",
2068
*out_size_B = size_B;
2073
isl_calc_base_alignment(const struct isl_device *dev,
2074
const struct isl_surf_init_info *info,
2075
const struct isl_tile_info *tile_info)
2077
uint32_t base_alignment_B;
2078
if (tile_info->tiling == ISL_TILING_LINEAR) {
2079
/* From the Broadwell PRM Vol 2d,
2080
* RENDER_SURFACE_STATE::SurfaceBaseAddress:
2082
* "The Base Address for linear render target surfaces and surfaces
2083
* accessed with the typed surface read/write data port messages must
2084
* be element-size aligned, for non-YUV surface formats, or a
2085
* multiple of 2 element-sizes for YUV surface formats. Other linear
2086
* surfaces have no alignment requirements (byte alignment is
2089
base_alignment_B = MAX(1, info->min_alignment_B);
2090
if (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) {
2091
if (isl_format_is_yuv(info->format)) {
2093
MAX(base_alignment_B, tile_info->format_bpb / 4);
2096
MAX(base_alignment_B, tile_info->format_bpb / 8);
2099
base_alignment_B = isl_round_up_to_power_of_two(base_alignment_B);
2101
/* From the Skylake PRM Vol 2c, PLANE_STRIDE::Stride:
2103
* "For Linear memory, this field specifies the stride in chunks of
2104
* 64 bytes (1 cache line)."
2106
if (isl_surf_usage_is_display(info->usage))
2107
base_alignment_B = MAX(base_alignment_B, 64);
2109
const uint32_t tile_size_B = tile_info->phys_extent_B.width *
2110
tile_info->phys_extent_B.height;
2111
assert(isl_is_pow2(info->min_alignment_B) && isl_is_pow2(tile_size_B));
2112
base_alignment_B = MAX(info->min_alignment_B, tile_size_B);
2114
/* The diagram in the Bspec section Memory Compression - Gfx12, shows
2115
* that the CCS is indexed in 256B chunks. However, the
2116
* PLANE_AUX_DIST::Auxiliary Surface Distance field is in units of 4K
2117
* pages. We currently don't assign the usage field like we do for main
2118
* surfaces, so just use 4K for now.
2120
if (tile_info->tiling == ISL_TILING_GFX12_CCS)
2121
base_alignment_B = MAX(base_alignment_B, 4096);
2123
/* Platforms using an aux map require that images be granularity-aligned
2124
* if they're going to used with CCS. This is because the Aux
2125
* translation table maps main surface addresses to aux addresses at a
2126
* granularity in the main surface. Because we don't know for sure in
2127
* ISL if a surface will use CCS, we have to guess based on the
2128
* DISABLE_AUX usage bit. The one thing we do know is that we haven't
2129
* enable CCS on linear images yet so we can avoid the extra alignment
2132
if (dev->info->has_aux_map &&
2133
!(info->usage & ISL_SURF_USAGE_DISABLE_AUX_BIT)) {
2134
base_alignment_B = MAX(base_alignment_B, dev->info->verx10 >= 125 ?
2135
1024 * 1024 : 64 * 1024);
2139
return base_alignment_B;
1839
2143
isl_surf_init_s(const struct isl_device *dev,
1840
2144
struct isl_surf *surf,
1895
2199
&phys_total_el, &row_pitch_B))
1898
uint32_t base_alignment_B;
1899
2202
uint64_t size_B;
1900
if (tiling == ISL_TILING_LINEAR) {
1901
/* LINEAR tiling has no concept of intra-tile arrays */
1902
assert(phys_total_el.d == 1 && phys_total_el.a == 1);
1904
size_B = (uint64_t) row_pitch_B * phys_total_el.h;
1906
/* From the Broadwell PRM Vol 2d, RENDER_SURFACE_STATE::SurfaceBaseAddress:
1908
* "The Base Address for linear render target surfaces and surfaces
1909
* accessed with the typed surface read/write data port messages must
1910
* be element-size aligned, for non-YUV surface formats, or a
1911
* multiple of 2 element-sizes for YUV surface formats. Other linear
1912
* surfaces have no alignment requirements (byte alignment is
1915
base_alignment_B = MAX(1, info->min_alignment_B);
1916
if (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) {
1917
if (isl_format_is_yuv(info->format)) {
1918
base_alignment_B = MAX(base_alignment_B, fmtl->bpb / 4);
1920
base_alignment_B = MAX(base_alignment_B, fmtl->bpb / 8);
1923
base_alignment_B = isl_round_up_to_power_of_two(base_alignment_B);
1925
/* From the Skylake PRM Vol 2c, PLANE_STRIDE::Stride:
1927
* "For Linear memory, this field specifies the stride in chunks of
1928
* 64 bytes (1 cache line)."
1930
if (isl_surf_usage_is_display(info->usage))
1931
base_alignment_B = MAX(base_alignment_B, 64);
1933
/* Pitches must make sense with the tiling */
1934
assert(row_pitch_B % tile_info.phys_extent_B.width == 0);
1936
uint32_t array_slices, array_pitch_tl_rows;
1937
if (phys_total_el.d > 1) {
1938
assert(phys_total_el.a == 1);
1939
array_pitch_tl_rows = isl_assert_div(array_pitch_el_rows,
1940
tile_info.logical_extent_el.h);
1941
array_slices = isl_align_div(phys_total_el.d,
1942
tile_info.logical_extent_el.d);
1943
} else if (phys_total_el.a > 1) {
1944
assert(phys_total_el.d == 1);
1945
array_pitch_tl_rows = isl_assert_div(array_pitch_el_rows,
1946
tile_info.logical_extent_el.h);
1947
array_slices = isl_align_div(phys_total_el.a,
1948
tile_info.logical_extent_el.a);
1950
assert(phys_total_el.d == 1 && phys_total_el.a == 1);
1951
array_pitch_tl_rows = 0;
1955
const uint32_t total_h_tl =
1956
(array_slices - 1) * array_pitch_tl_rows +
1957
isl_align_div(phys_total_el.h, tile_info.logical_extent_el.height);
1959
size_B = (uint64_t) total_h_tl * tile_info.phys_extent_B.height * row_pitch_B;
1961
const uint32_t tile_size_B = tile_info.phys_extent_B.width *
1962
tile_info.phys_extent_B.height;
1963
assert(isl_is_pow2(info->min_alignment_B) && isl_is_pow2(tile_size_B));
1964
base_alignment_B = MAX(info->min_alignment_B, tile_size_B);
1966
/* The diagram in the Bspec section Memory Compression - Gfx12, shows
1967
* that the CCS is indexed in 256B chunks. However, the
1968
* PLANE_AUX_DIST::Auxiliary Surface Distance field is in units of 4K
1969
* pages. We currently don't assign the usage field like we do for main
1970
* surfaces, so just use 4K for now.
1972
if (tiling == ISL_TILING_GFX12_CCS)
1973
base_alignment_B = MAX(base_alignment_B, 4096);
1975
/* Platforms using an aux map require that images be granularity-aligned
1976
* if they're going to used with CCS. This is because the Aux translation
1977
* table maps main surface addresses to aux addresses at a granularity in
1978
* the main surface. Because we don't know for sure in ISL if a surface
1979
* will use CCS, we have to guess based on the DISABLE_AUX usage bit. The
1980
* one thing we do know is that we haven't enable CCS on linear images
1981
* yet so we can avoid the extra alignment there.
1983
if (dev->info->has_aux_map &&
1984
!(info->usage & ISL_SURF_USAGE_DISABLE_AUX_BIT)) {
1985
base_alignment_B = MAX(base_alignment_B, dev->info->verx10 >= 125 ?
1986
1024 * 1024 : 64 * 1024);
1990
if (ISL_GFX_VER(dev) < 9) {
1991
/* From the Broadwell PRM Vol 5, Surface Layout:
1993
* "In addition to restrictions on maximum height, width, and depth,
1994
* surfaces are also restricted to a maximum size in bytes. This
1995
* maximum is 2 GB for all products and all surface types."
1997
* This comment is applicable to all Pre-gfx9 platforms.
1999
if (size_B > (uint64_t) 1 << 31)
2001
} else if (ISL_GFX_VER(dev) < 11) {
2002
/* From the Skylake PRM Vol 5, Maximum Surface Size in Bytes:
2003
* "In addition to restrictions on maximum height, width, and depth,
2004
* surfaces are also restricted to a maximum size of 2^38 bytes.
2005
* All pixels within the surface must be contained within 2^38 bytes
2006
* of the base address."
2008
if (size_B > (uint64_t) 1 << 38)
2011
/* gfx11+ platforms raised this limit to 2^44 bytes. */
2012
if (size_B > (uint64_t) 1 << 44)
2203
if (!isl_calc_size(dev, info, &tile_info, &phys_total_el,
2204
array_pitch_el_rows, row_pitch_B, &size_B))
2207
const uint32_t base_alignment_B =
2208
isl_calc_base_alignment(dev, info, &tile_info);
2016
2210
*surf = (struct isl_surf) {
2017
2211
.dim = info->dim,