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 = \