mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-08 23:00:28 +01:00
intel/blorp: Optimize non-zero-layer fast-clears
Allow surface redescription when fast-clearing a layer > 0. This affects at least five traces in the performance CI, but the CI doesn't report any performance benefit from this. We already had code to handle unaligned rows at the bottom of an image. Now that this handles the misalignment at the top of the image range, we gain some symmetry. Reviewed-by: Jianxun Zhang <jianxun.zhang@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37660>
This commit is contained in:
parent
ba63883692
commit
3e331e4fe9
1 changed files with 91 additions and 13 deletions
|
|
@ -551,7 +551,8 @@ blorp_fast_clear(struct blorp_batch *batch,
|
|||
* range information to do that.
|
||||
*/
|
||||
int64_t size_B = 0;
|
||||
int unaligned_height = 0;
|
||||
int unaligned_top_rows = 0;
|
||||
int unaligned_bottom_rows = 0;
|
||||
struct blorp_address addr = surf->addr;
|
||||
if (ISL_GFX_VERX10(batch->blorp->isl_dev) == 125 &&
|
||||
surf->surf->samples == 1) {
|
||||
|
|
@ -561,22 +562,70 @@ blorp_fast_clear(struct blorp_batch *batch,
|
|||
&start_tile_B, &end_tile_B)) {
|
||||
size_B = end_tile_B - start_tile_B;
|
||||
addr.offset += start_tile_B;
|
||||
} else if (isl_tiling_is_64(surf->surf->tiling) ||
|
||||
isl_tiling_is_std_y(surf->surf->tiling)) {
|
||||
} else if (isl_tiling_is_64(surf->surf->tiling)) {
|
||||
/* If not supported above, clear the range without redescription.
|
||||
* Thankfully, we haven't run into this outside of conformance tests.
|
||||
*/
|
||||
assert(surf->surf->levels > 1 ||
|
||||
surf->surf->logical_level0_px.d != num_layers);
|
||||
} else if (level == 0 && start_layer == 0 && num_layers == 1) {
|
||||
} else if (level == 0 && num_layers == 1) {
|
||||
/* We're clearing a single layer that is not aligned to tile
|
||||
* boundaries. Get the tile-aligned size of the layer and record the
|
||||
* unaligned top and bottom rows. We'll use three strategies to clear
|
||||
* this layer:
|
||||
* 1) We'll clear the unaligned top rows by creating a tile-aligned
|
||||
* 2d-array image with 32 / VALIGN rows. We'll use layered clears
|
||||
* to clear the range of rows corresponding to the original layer
|
||||
* we intend to clear.
|
||||
* 2) We'll clear the naturally tile-aligned area of this layer in
|
||||
* chunks of tiles.
|
||||
* 3) We'll clear the unaligned bottom rows by creating a
|
||||
* tile-aligned image and relying on HW to avoid clearing past the
|
||||
* height of the bottom rows.
|
||||
*/
|
||||
assert(surf->surf->tiling == ISL_TILING_4);
|
||||
assert(surf->surf->levels > 1 ||
|
||||
surf->surf->logical_level0_px.d > 1 ||
|
||||
surf->surf->logical_level0_px.a > 1);
|
||||
const int phys_height0 = align(surf->surf->logical_level0_px.h,
|
||||
surf->surf->image_alignment_el.h);
|
||||
unaligned_height = phys_height0 % 32;
|
||||
size_B = (int64_t)surf->surf->row_pitch_B * (phys_height0 - unaligned_height);
|
||||
|
||||
/* Get the tile-aligned offset to the layer and the y-offset into
|
||||
* that tile which marks the first row.
|
||||
*/
|
||||
uint64_t offset_B;
|
||||
uint32_t x0_offset_el, y0_offset_el;
|
||||
isl_surf_get_image_offset_B_tile_el(surf->surf, level,
|
||||
surf->surf->dim == ISL_SURF_DIM_3D ? 0 : start_layer,
|
||||
surf->surf->dim == ISL_SURF_DIM_3D ? start_layer : 0,
|
||||
&offset_B, &x0_offset_el, &y0_offset_el);
|
||||
assert(x0_offset_el == 0);
|
||||
assert(y0_offset_el < 32);
|
||||
|
||||
/* Get the y-offset of the last row. Include as much padding as
|
||||
* possible so that we can detect a naturally tile-aligned portion of
|
||||
* the image.
|
||||
*/
|
||||
if (surf->surf->dim == ISL_SURF_DIM_3D)
|
||||
assert(surf->surf->array_pitch_el_rows % 32 == 0);
|
||||
uint32_t max_valign = surf->surf->levels > 1 ?
|
||||
surf->surf->image_alignment_el.h :
|
||||
start_layer < surf->surf->logical_level0_px.a - 1 ?
|
||||
surf->surf->array_pitch_el_rows : 32;
|
||||
uint32_t y1_ex_offset_el = y0_offset_el +
|
||||
ALIGN_NPOT(surf->surf->logical_level0_px.h, max_valign);
|
||||
|
||||
/* Now that we have y0 and y1, determine the unaligned row
|
||||
* information, the size and offset.
|
||||
*/
|
||||
int tile_aligned_y1 = ROUND_DOWN_TO(y1_ex_offset_el, 32);
|
||||
int tile_aligned_y0 = align(y0_offset_el, 32);
|
||||
int tile_aligned_rows = tile_aligned_y1 - tile_aligned_y0;
|
||||
if (tile_aligned_rows > 0) {
|
||||
assert(tile_aligned_rows % 32 == 0);
|
||||
size_B = surf->surf->row_pitch_B * tile_aligned_rows;
|
||||
addr.offset += offset_B;
|
||||
unaligned_top_rows = tile_aligned_y0 - y0_offset_el;
|
||||
unaligned_bottom_rows = y1_ex_offset_el - tile_aligned_y1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -605,6 +654,34 @@ blorp_fast_clear(struct blorp_batch *batch,
|
|||
.aux_usage = surf->aux_usage,
|
||||
};
|
||||
|
||||
/* Use coordinate-based clears to clear the area that is not aligned
|
||||
* to a tile.
|
||||
*/
|
||||
if (unaligned_top_rows != 0) {
|
||||
assert(unaligned_top_rows > 0);
|
||||
assert(unaligned_top_rows < 32);
|
||||
assert(level == 0);
|
||||
isl_surf_from_mem(batch->blorp->isl_dev, &isl_surf,
|
||||
mem_surf.addr.offset, surf->surf->row_pitch_B * 32,
|
||||
ISL_TILING_4);
|
||||
int valign = surf->surf->image_alignment_el.h;
|
||||
assert(32 % valign == 0);
|
||||
assert(isl_surf.image_alignment_el.h == valign);
|
||||
assert(isl_surf.logical_level0_px.h == 32);
|
||||
|
||||
isl_surf.logical_level0_px.h = valign;
|
||||
isl_surf.phys_level0_sa.h = valign;
|
||||
isl_surf.logical_level0_px.a = 32 / valign;
|
||||
isl_surf.phys_level0_sa.a = 32 / valign;
|
||||
isl_surf.row_pitch_B = align(isl_surf.row_pitch_B, 16 * 128);
|
||||
|
||||
fast_clear_surf(batch, &mem_surf, isl_surf.format, swizzle, 0,
|
||||
(32 - unaligned_top_rows) / valign,
|
||||
unaligned_top_rows / valign);
|
||||
|
||||
mem_surf.addr.offset += isl_surf.size_B;
|
||||
}
|
||||
|
||||
do {
|
||||
if (mem_surf.addr.offset % _64k == 0) {
|
||||
if (size_B <= _16k * 16 * 32) {
|
||||
|
|
@ -640,15 +717,16 @@ blorp_fast_clear(struct blorp_batch *batch,
|
|||
/* Use coordinate-based clears to clear the area that is not aligned to
|
||||
* a tile.
|
||||
*/
|
||||
if (unaligned_height > 0) {
|
||||
assert(level == 0 && start_layer == 0 && num_layers == 1);
|
||||
assert(surf->surf->tiling == ISL_TILING_4);
|
||||
if (unaligned_bottom_rows != 0) {
|
||||
assert(unaligned_bottom_rows > 0);
|
||||
assert(unaligned_bottom_rows < 32);
|
||||
assert(level == 0);
|
||||
isl_surf_from_mem(batch->blorp->isl_dev, &isl_surf,
|
||||
mem_surf.addr.offset, surf->surf->row_pitch_B * 32,
|
||||
ISL_TILING_4);
|
||||
assert(isl_surf.logical_level0_px.h == 32);
|
||||
isl_surf.logical_level0_px.h = unaligned_height;
|
||||
isl_surf.phys_level0_sa.h = unaligned_height;
|
||||
isl_surf.logical_level0_px.h = unaligned_bottom_rows;
|
||||
isl_surf.phys_level0_sa.h = unaligned_bottom_rows;
|
||||
fast_clear_surf(batch, &mem_surf, isl_surf.format, swizzle,
|
||||
0, 0, isl_surf.logical_level0_px.a);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue