mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-11 13:30:31 +01:00
Merge branch 'perf/shrink-miptrees' into 'main'
intel/isl: Omit unused space when sizing mipmaps See merge request mesa/mesa!39593
This commit is contained in:
commit
01ece261a8
1 changed files with 108 additions and 60 deletions
|
|
@ -3161,13 +3161,13 @@ isl_calc_row_pitch(const struct isl_device *dev,
|
|||
}
|
||||
|
||||
static bool
|
||||
isl_calc_size(const struct isl_device *dev,
|
||||
const struct isl_surf_init_info *info,
|
||||
const struct isl_tile_info *tile_info,
|
||||
const struct isl_extent4d *phys_total_el,
|
||||
uint32_t array_pitch_el_rows,
|
||||
uint32_t row_pitch_B,
|
||||
uint64_t *out_size_B)
|
||||
isl_calc_initial_size(const struct isl_device *dev,
|
||||
const struct isl_surf_init_info *info,
|
||||
const struct isl_tile_info *tile_info,
|
||||
const struct isl_extent4d *phys_total_el,
|
||||
uint32_t array_pitch_el_rows,
|
||||
uint32_t row_pitch_B,
|
||||
uint64_t *out_size_B)
|
||||
{
|
||||
uint64_t size_B;
|
||||
if (tile_info->tiling == ISL_TILING_LINEAR) {
|
||||
|
|
@ -3205,50 +3205,6 @@ isl_calc_size(const struct isl_device *dev,
|
|||
|
||||
size_B = (uint64_t) total_h_tl * tile_info->phys_extent_B.height *
|
||||
row_pitch_B;
|
||||
|
||||
/* Bspec 57340 (r59562):
|
||||
*
|
||||
* When allocating memory, MCS buffer size is extended by 4KB over
|
||||
* its original calculated size. First 4KB page of the MCS is
|
||||
* reserved for internal HW usage.
|
||||
*
|
||||
* Allocate an extra 4KB page reserved for hardware at the beginning of
|
||||
* MCS buffer on Xe2. The start address of MCS is the head of the 4KB
|
||||
* page. Any manipulation on the content of MCS should start after 4KB
|
||||
* from the start address.
|
||||
*/
|
||||
if (dev->info->ver >= 20 && info->usage & ISL_SURF_USAGE_MCS_BIT)
|
||||
size_B += 4096;
|
||||
}
|
||||
|
||||
/* If for some reason we can't support the appropriate tiling format and
|
||||
* end up falling to linear or some other format, make sure the image size
|
||||
* and alignment are aligned to the expected block size so we can at least
|
||||
* do opaque binds.
|
||||
*/
|
||||
if (info->usage & ISL_SURF_USAGE_SPARSE_BIT)
|
||||
size_B = isl_align(size_B, 64 * 1024);
|
||||
|
||||
/* Pre-gfx9: from the Broadwell PRM Vol 5, Surface Layout:
|
||||
* "In addition to restrictions on maximum height, width, and depth,
|
||||
* surfaces are also restricted to a maximum size in bytes. This
|
||||
* maximum is 2 GB for all products and all surface types."
|
||||
*
|
||||
* gfx9-10: from the Skylake PRM Vol 5, Maximum Surface Size in Bytes:
|
||||
* "In addition to restrictions on maximum height, width, and depth,
|
||||
* surfaces are also restricted to a maximum size of 2^38 bytes.
|
||||
* All pixels within the surface must be contained within 2^38 bytes
|
||||
* of the base address."
|
||||
*
|
||||
* gfx11+ platforms raised this limit to 2^44 bytes.
|
||||
*/
|
||||
uint64_t max_surface_B = 1ull << (ISL_GFX_VER(dev) >= 11 ? 44 :
|
||||
ISL_GFX_VER(dev) >= 9 ? 38 : 31);
|
||||
if (size_B > max_surface_B) {
|
||||
return notify_failure(
|
||||
info,
|
||||
"calculated size (%"PRIu64"B) exceeds platform limit of %"PRIu64"B",
|
||||
size_B, max_surface_B);
|
||||
}
|
||||
|
||||
*out_size_B = size_B;
|
||||
|
|
@ -3371,6 +3327,90 @@ isl_calc_base_alignment(const struct isl_device *dev,
|
|||
return base_alignment_B;
|
||||
}
|
||||
|
||||
static bool
|
||||
isl_calc_final_size(const struct isl_device *dev,
|
||||
const struct isl_surf_init_info *restrict info,
|
||||
struct isl_surf *surf)
|
||||
{
|
||||
/* Remove extra padding if the row-pitch is flexible. A fixed row pitch
|
||||
* could indicate that an image is being redescribed or imported/exported.
|
||||
*/
|
||||
if (info->row_pitch_B == 0) {
|
||||
uint64_t end_tile_B_max = 0;
|
||||
for (int lod = 0; lod < surf->levels; lod++) {
|
||||
uint64_t start_tile_B, end_tile_B;
|
||||
if (surf->dim == ISL_SURF_DIM_3D) {
|
||||
int last_z = u_minify(surf->logical_level0_px.d, lod) - 1;
|
||||
isl_surf_get_image_range_B_tile(surf, lod, 0, last_z,
|
||||
&start_tile_B, &end_tile_B);
|
||||
} else {
|
||||
int last_layer = surf->logical_level0_px.a - 1;
|
||||
isl_surf_get_image_range_B_tile(surf, lod, last_layer, 0,
|
||||
&start_tile_B, &end_tile_B);
|
||||
}
|
||||
|
||||
end_tile_B_max = MAX2(end_tile_B_max, end_tile_B);
|
||||
|
||||
/* There's no padding if this LOD has a pixel in the last tile. */
|
||||
if (end_tile_B_max == surf->size_B)
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t padding_B = surf->size_B - end_tile_B_max;
|
||||
if (padding_B > 0) {
|
||||
print_info(info, "Omitted %ld 4KB page(s) of padding.",
|
||||
padding_B / 4096);
|
||||
surf->size_B = end_tile_B_max;
|
||||
}
|
||||
}
|
||||
|
||||
/* If for some reason we can't support the appropriate tiling format and
|
||||
* end up falling to linear or some other format, make sure the image size
|
||||
* and alignment are aligned to the expected block size so we can at least
|
||||
* do opaque binds.
|
||||
*/
|
||||
if (surf->usage & ISL_SURF_USAGE_SPARSE_BIT)
|
||||
surf->size_B = isl_align(surf->size_B, 64 * 1024);
|
||||
|
||||
/* Bspec 57340 (r59562):
|
||||
*
|
||||
* When allocating memory, MCS buffer size is extended by 4KB over
|
||||
* its original calculated size. First 4KB page of the MCS is
|
||||
* reserved for internal HW usage.
|
||||
*
|
||||
* Allocate an extra 4KB page reserved for hardware at the beginning of
|
||||
* MCS buffer on Xe2. The start address of MCS is the head of the 4KB
|
||||
* page. Any manipulation on the content of MCS should start after 4KB
|
||||
* from the start address.
|
||||
*/
|
||||
if (dev->info->ver >= 20 && surf->usage & ISL_SURF_USAGE_MCS_BIT)
|
||||
surf->size_B += 4096;
|
||||
|
||||
/* Pre-gfx9: from the Broadwell PRM Vol 5, Surface Layout:
|
||||
* "In addition to restrictions on maximum height, width, and depth,
|
||||
* surfaces are also restricted to a maximum size in bytes. This
|
||||
* maximum is 2 GB for all products and all surface types."
|
||||
*
|
||||
* gfx9-10: from the Skylake PRM Vol 5, Maximum Surface Size in Bytes:
|
||||
* "In addition to restrictions on maximum height, width, and depth,
|
||||
* surfaces are also restricted to a maximum size of 2^38 bytes.
|
||||
* All pixels within the surface must be contained within 2^38 bytes
|
||||
* of the base address."
|
||||
*
|
||||
* gfx11+ platforms raised this limit to 2^44 bytes.
|
||||
*/
|
||||
uint64_t max_surface_B = 1ull << (ISL_GFX_VER(dev) >= 11 ? 44 :
|
||||
ISL_GFX_VER(dev) >= 9 ? 38 : 31);
|
||||
if (surf->size_B > max_surface_B) {
|
||||
return notify_failure(
|
||||
info,
|
||||
"calculated size (%"PRIu64"B) exceeds platform limit of %"PRIu64"B",
|
||||
surf->size_B, max_surface_B);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
isl_surf_init_s_with_tiling(const struct isl_device *dev,
|
||||
struct isl_surf *surf,
|
||||
|
|
@ -3433,9 +3473,10 @@ isl_surf_init_s_with_tiling(const struct isl_device *dev,
|
|||
&phys_total_el, &row_pitch_B))
|
||||
return false;
|
||||
|
||||
uint64_t size_B;
|
||||
if (!isl_calc_size(dev, info, &tile_info, &phys_total_el,
|
||||
array_pitch_el_rows, row_pitch_B, &size_B))
|
||||
uint64_t initial_size_B;
|
||||
if (!isl_calc_initial_size(dev, info, &tile_info, &phys_total_el,
|
||||
array_pitch_el_rows, row_pitch_B,
|
||||
&initial_size_B))
|
||||
return false;
|
||||
|
||||
const uint32_t base_alignment_B =
|
||||
|
|
@ -3455,7 +3496,7 @@ isl_surf_init_s_with_tiling(const struct isl_device *dev,
|
|||
.logical_level0_px = logical_level0_px,
|
||||
.phys_level0_sa = phys_level0_sa,
|
||||
|
||||
.size_B = size_B,
|
||||
.size_B = initial_size_B,
|
||||
.alignment_B = base_alignment_B,
|
||||
.row_pitch_B = row_pitch_B,
|
||||
.array_pitch_el_rows = array_pitch_el_rows,
|
||||
|
|
@ -3465,7 +3506,7 @@ isl_surf_init_s_with_tiling(const struct isl_device *dev,
|
|||
.usage = info->usage,
|
||||
};
|
||||
|
||||
return true;
|
||||
return isl_calc_final_size(dev, info, surf);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -4724,7 +4765,17 @@ isl_surf_get_image_range_B_tile(const struct isl_surf *surf,
|
|||
|
||||
/* We only consider one Z or array slice */
|
||||
const uint32_t end_z_offset_el = start_z_offset_el;
|
||||
const uint32_t end_array_slice = start_array_slice;
|
||||
uint32_t end_array_slice = start_array_slice;
|
||||
|
||||
/* Find the last sample */
|
||||
struct isl_tile_info tile_info;
|
||||
isl_surf_get_tile_info(surf, &tile_info);
|
||||
if (surf->msaa_layout == ISL_MSAA_LAYOUT_ARRAY) {
|
||||
if (tile_info.logical_extent_el.a > 1)
|
||||
end_array_slice += surf->samples - 1;
|
||||
else
|
||||
end_y_offset_el += (surf->samples - 1) * surf->array_pitch_el_rows;
|
||||
}
|
||||
|
||||
UNUSED uint32_t x_offset_el, y_offset_el, z_offset_el, array_slice;
|
||||
isl_tiling_get_intratile_offset_el(surf->tiling, surf->dim,
|
||||
|
|
@ -4757,9 +4808,6 @@ isl_surf_get_image_range_B_tile(const struct isl_surf *surf,
|
|||
&z_offset_el,
|
||||
&array_slice);
|
||||
|
||||
struct isl_tile_info tile_info;
|
||||
isl_surf_get_tile_info(surf, &tile_info);
|
||||
|
||||
/* We want the range we return to be exclusive but the tile containing the
|
||||
* last pixel (what we just calculated) is inclusive. Add one and round up
|
||||
* to the tile size.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue