From be3890a898559db401c928c98b485af2a068388b Mon Sep 17 00:00:00 2001 From: Asahi Lina Date: Fri, 24 Nov 2023 16:14:38 +0900 Subject: [PATCH] ail: Add explicit specification of mip level strides For compressed textures, mip levels > 0 can have additional stride padding. This (in some cases) affects the tile stride calculation, so it cannot be implicitly represented with the existing members. Add an explicit array containing the stride, in elements, of each miptree level. The tiling code uses this instead of the minified and element-aligned width when computing tile addressing. This commit should be a functional no-op. Signed-off-by: Asahi Lina Part-of: --- src/asahi/layout/layout.c | 4 ++++ src/asahi/layout/layout.h | 8 ++++++++ src/asahi/layout/tiling.c | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/asahi/layout/layout.c b/src/asahi/layout/layout.c index 685867f2033..c99d492a667 100644 --- a/src/asahi/layout/layout.c +++ b/src/asahi/layout/layout.c @@ -122,6 +122,8 @@ ail_initialize_twiddled(struct ail_layout *layout) layout->level_offsets_B[l] = offset_B; offset_B = ALIGN_POT(offset_B + (blocksize_B * size_el), AIL_CACHELINE); + layout->stride_el[l] = util_format_get_nblocksx( + layout->format, u_minify(layout->width_px, l)); layout->tilesize_el[l] = tilesize_el; } @@ -154,6 +156,8 @@ ail_initialize_twiddled(struct ail_layout *layout) unsigned tilesize_el = util_next_power_of_two(u_minify(MIN2(w_el, h_el), l)); layout->tilesize_el[l] = (struct ail_tile){tilesize_el, tilesize_el}; + layout->stride_el[l] = util_format_get_nblocksx( + layout->format, u_minify(layout->width_px, l)); potw_el = u_minify(potw_el, 1); poth_el = u_minify(poth_el, 1); diff --git a/src/asahi/layout/layout.h b/src/asahi/layout/layout.h index 3f67092535b..3bfce0a1a60 100644 --- a/src/asahi/layout/layout.h +++ b/src/asahi/layout/layout.h @@ -110,6 +110,14 @@ struct ail_layout { */ struct ail_tile tilesize_el[AIL_MAX_MIP_LEVELS]; + /** + * If tiling is TWIDDLED, the stride in elements used for each mip level + * within a layer. Calculating level strides is the sole responsibility of + * ail_initialized_twiddled. This is necessary because compressed pixel + * formats may add extra stride padding. + */ + uint32_t stride_el[AIL_MAX_MIP_LEVELS]; + /* Offset of the start of the compression metadata buffer */ uint32_t metadata_offset_B; diff --git a/src/asahi/layout/tiling.c b/src/asahi/layout/tiling.c index af315dec0c7..00e06808d3c 100644 --- a/src/asahi/layout/tiling.c +++ b/src/asahi/layout/tiling.c @@ -70,7 +70,7 @@ ail_space_mask(unsigned x) { \ enum pipe_format format = tiled_layout->format; \ unsigned linear_pitch_el = linear_pitch_B / blocksize_B; \ - unsigned width_el = util_format_get_nblocksx(format, width_px); \ + unsigned stride_el = tiled_layout->stride_el[level]; \ unsigned sx_el = util_format_get_nblocksx(format, sx_px); \ unsigned sy_el = util_format_get_nblocksy(format, sy_px); \ unsigned swidth_el = util_format_get_nblocksx(format, swidth_px); \ @@ -80,7 +80,7 @@ ail_space_mask(unsigned x) \ struct ail_tile tile_size = tiled_layout->tilesize_el[level]; \ unsigned tile_area_el = tile_size.width_el * tile_size.height_el; \ - unsigned tiles_per_row = DIV_ROUND_UP(width_el, tile_size.width_el); \ + unsigned tiles_per_row = DIV_ROUND_UP(stride_el, tile_size.width_el); \ unsigned y_offs_el = ail_space_bits(MOD_POT(sy_el, tile_size.height_el)) \ << 1; \ unsigned x_offs_start_el = \