isl: Add and use isl_tiling_get_intratile_range_el/sa

Consolidates the logic for calculating the intratile extent of a slice of a
surface to avoid duplicating code in the next patch.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40149>
This commit is contained in:
Calder Young 2026-02-21 18:15:44 -08:00 committed by Marge Bot
parent f5c848ef57
commit fd7c094f7b
2 changed files with 221 additions and 45 deletions

View file

@ -4899,53 +4899,30 @@ isl_surf_get_image_range_B_tile(const struct isl_surf *surf,
const uint32_t subimage_h_el = isl_align_div_npot(subimage_h_sa, fmtl->bh);
/* Find the last pixel */
uint32_t end_x_offset_el = start_x_offset_el + subimage_w_el - 1;
uint32_t end_y_offset_el = start_y_offset_el + subimage_h_el - 1;
/* 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;
const struct isl_extent4d subimage_extent_el = {
.w = subimage_w_el,
.h = subimage_h_el,
.d = 1,
.a = 1,
};
UNUSED uint32_t x_offset_el, y_offset_el, z_offset_el, array_slice;
isl_tiling_get_intratile_offset_el(surf->tiling, surf->dim,
surf->msaa_layout, fmtl->bpb,
surf->samples,
surf->row_pitch_B,
surf->array_pitch_el_rows,
start_x_offset_el,
start_y_offset_el,
start_z_offset_el,
start_array_slice,
start_tile_B,
&x_offset_el,
&y_offset_el,
&z_offset_el,
&array_slice);
isl_tiling_get_intratile_offset_el(surf->tiling, surf->dim,
surf->msaa_layout, fmtl->bpb,
surf->samples,
surf->row_pitch_B,
surf->array_pitch_el_rows,
end_x_offset_el,
end_y_offset_el,
end_z_offset_el,
end_array_slice,
end_tile_B,
&x_offset_el,
&y_offset_el,
&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.
*/
*end_tile_B = ALIGN_NPOT(*end_tile_B + 1, tile_info.phys_extent_B.w *
tile_info.phys_extent_B.h);
isl_tiling_get_intratile_range_el(surf->tiling, surf->dim,
surf->msaa_layout, fmtl->bpb,
surf->samples,
surf->row_pitch_B,
surf->array_pitch_el_rows,
start_x_offset_el,
start_y_offset_el,
start_z_offset_el,
start_array_slice,
subimage_extent_el,
start_tile_B,
end_tile_B,
&x_offset_el,
&y_offset_el,
&z_offset_el,
&array_slice);
assert(*end_tile_B <= surf->size_B);
}
@ -5325,6 +5302,72 @@ isl_tiling_get_intratile_offset_el(enum isl_tiling tiling,
(uint64_t)x_offset_tl * tile_info.phys_extent_B.h * tile_info.phys_extent_B.w;
}
void
isl_tiling_get_intratile_range_el(enum isl_tiling tiling,
enum isl_surf_dim dim,
enum isl_msaa_layout msaa_layout,
uint32_t bpb,
uint32_t samples,
uint32_t row_pitch_B,
uint32_t array_pitch_el_rows,
uint32_t total_x_offset_el,
uint32_t total_y_offset_el,
uint32_t total_z_offset_el,
uint32_t total_array_offset,
struct isl_extent4d total_extent_el,
uint64_t *start_offset_B,
uint64_t *end_offset_B,
uint32_t *x_offset_el,
uint32_t *y_offset_el,
uint32_t *z_offset_el,
uint32_t *array_offset)
{
isl_tiling_get_intratile_offset_el(tiling, dim,
msaa_layout, bpb,
samples,
row_pitch_B,
array_pitch_el_rows,
total_x_offset_el,
total_y_offset_el,
total_z_offset_el,
total_array_offset,
start_offset_B,
x_offset_el,
y_offset_el,
z_offset_el,
array_offset);
UNUSED uint32_t _x_offset_el, _y_offset_el, _z_offset_el, _array_slice;
isl_tiling_get_intratile_offset_el(tiling, dim,
msaa_layout, bpb,
samples,
row_pitch_B,
array_pitch_el_rows,
total_x_offset_el + total_extent_el.w - 1,
total_y_offset_el + total_extent_el.h - 1,
total_z_offset_el + total_extent_el.d - 1,
total_array_offset + total_extent_el.a - 1,
end_offset_B,
&_x_offset_el,
&_y_offset_el,
&_z_offset_el,
&_array_slice);
if (tiling != ISL_TILING_LINEAR) {
struct isl_tile_info tile_info;
isl_tiling_get_info(tiling, dim, msaa_layout, bpb, samples, &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.
*/
*end_offset_B = ALIGN_NPOT(*end_offset_B + 1, tile_info.phys_extent_B.w *
tile_info.phys_extent_B.h);
} else {
*end_offset_B += bpb / 8;
}
}
uint64_t
isl_surf_get_sampler_overfetch_size_B(const struct isl_device *dev,
const struct isl_surf *surf,

View file

@ -3311,6 +3311,139 @@ isl_tiling_get_intratile_offset_sa(enum isl_tiling tiling,
*z_offset_sa *= fmtl->bd;
}
/**
* Calculate the intratile extent of a slice of a surface, in elements.
*
* This function takes a coordinate and extent in global tile space and
* returns the byte offset to the specific range of tiles as well as the
* offset within those tiles to the given coordinate in tile space. The
* returned x/y/z/array offsets are guaranteed to lie within the first tile.
*
* :param tiling: |in| The tiling of the surface
* :param bpb: |in| The size of the surface format in bits per
* block
* :param array_pitch_el_rows: |in| The array pitch of the surface for flat 2D
* tilings such as ISL_TILING_Y0
* :param total_x_offset_el: |in| The X offset in tile space, in elements
* :param total_y_offset_el: |in| The Y offset in tile space, in elements
* :param total_z_offset_el: |in| The Z offset in tile space, in elements
* :param total_array_offset: |in| The array offset in tile space
* :param total_extent_el: |in| The extent in tile space
* :param tile_start_B: |out| The returned byte offset to the start of
* the first tile
* :param tile_end_B: |out| The returned byte offset to the end of
* the last tile
* :param x_offset_el: |out| The X offset within the tile, in elements
* :param y_offset_el: |out| The Y offset within the tile, in elements
* :param z_offset_el: |out| The Z offset within the tile, in elements
* :param array_offset: |out| The array offset within the tile
*/
void
isl_tiling_get_intratile_range_el(enum isl_tiling tiling,
enum isl_surf_dim dim,
enum isl_msaa_layout msaa_layout,
uint32_t bpb,
uint32_t samples,
uint32_t row_pitch_B,
uint32_t array_pitch_el_rows,
uint32_t total_x_offset_el,
uint32_t total_y_offset_el,
uint32_t total_z_offset_el,
uint32_t total_array_offset,
struct isl_extent4d total_extent_el,
uint64_t *tile_start_B,
uint64_t *tile_end_B,
uint32_t *x_offset_el,
uint32_t *y_offset_el,
uint32_t *z_offset_el,
uint32_t *array_offset);
/**
* Calculate the intratile extent of a slice of a surface, in samples.
*
* This function takes a coordinate and extent in global tile space and
* returns the byte offset to the specific range of tiles as well as the
* offset within those tiles to the given coordinate in tile space. The
* returned x/y/z/array offsets are guaranteed to lie within the first tile.
*
* :param tiling: |in| The tiling of the surface
* :param bpb: |in| The size of the surface format in bits per
* block
* :param array_pitch_el_rows: |in| The array pitch of the surface for flat 2D
* tilings such as ISL_TILING_Y0
* :param total_x_offset_sa: |in| The X offset in tile space, in samples
* :param total_y_offset_sa: |in| The Y offset in tile space, in samples
* :param total_z_offset_sa: |in| The Z offset in tile space, in samples
* :param total_array_offset: |in| The array offset in tile space
* :param total_extent_sa: |in| The extent in tile space
* :param tile_start_B: |out| The returned byte offset to the start of
* the first tile
* :param tile_end_B: |out| The returned byte offset to the end of
* the last tile
* :param x_offset_sa: |out| The X offset within the tile, in samples
* :param y_offset_sa: |out| The Y offset within the tile, in samples
* :param z_offset_sa: |out| The Z offset within the tile, in samples
* :param array_offset: |out| The array offset within the tile
*/
static inline void
isl_tiling_get_intratile_range_sa(enum isl_tiling tiling,
enum isl_surf_dim dim,
enum isl_msaa_layout msaa_layout,
enum isl_format format,
uint32_t samples,
uint32_t row_pitch_B,
uint32_t array_pitch_el_rows,
uint32_t total_x_offset_sa,
uint32_t total_y_offset_sa,
uint32_t total_z_offset_sa,
uint32_t total_array_offset,
struct isl_extent4d total_extent_sa,
uint64_t *tile_start_B,
uint64_t *tile_end_B,
uint32_t *x_offset_sa,
uint32_t *y_offset_sa,
uint32_t *z_offset_sa,
uint32_t *array_offset)
{
const struct isl_format_layout *fmtl = isl_format_get_layout(format);
/* For computing the intratile offsets, we actually want a strange unit
* which is samples for multisampled surfaces but elements for compressed
* surfaces.
*/
assert(total_x_offset_sa % fmtl->bw == 0);
assert(total_y_offset_sa % fmtl->bh == 0);
assert(total_z_offset_sa % fmtl->bd == 0);
assert(total_extent_sa.w % fmtl->bw == 0);
assert(total_extent_sa.h % fmtl->bh == 0);
assert(total_extent_sa.d % fmtl->bd == 0);
const uint32_t total_x_offset_el = total_x_offset_sa / fmtl->bw;
const uint32_t total_y_offset_el = total_y_offset_sa / fmtl->bh;
const uint32_t total_z_offset_el = total_z_offset_sa / fmtl->bd;
const struct isl_extent4d total_extent_el = {
.w = total_extent_sa.w / fmtl->bw,
.h = total_extent_sa.h / fmtl->bh,
.d = total_extent_sa.d / fmtl->bd,
.a = total_extent_sa.a
};
isl_tiling_get_intratile_range_el(tiling, dim, msaa_layout, fmtl->bpb,
samples, row_pitch_B,
array_pitch_el_rows,
total_x_offset_el,
total_y_offset_el,
total_z_offset_el,
total_array_offset,
total_extent_el,
tile_start_B,
tile_end_B,
x_offset_sa, y_offset_sa,
z_offset_sa, array_offset);
*x_offset_sa *= fmtl->bw;
*y_offset_sa *= fmtl->bh;
*z_offset_sa *= fmtl->bd;
}
/**
* Calculates the size of a sampling engine surface, including the maximum
* number of extra padding bytes that could be fetched due to caching.