panfrost: Unify row stride and AFBC row stride

Row stride is defined in terms of header blocks for AFBC. Usually,
afbc.row_stride is used for AFBC images and row_stride for non-AFBC images;
however, the nonsense non-AFBC stride leaked into the UABI. So handle that in
the legacy conversion path and use a unified row stride (equal to
afbc.row_stride for AFBC images and row_stride otherwise).

Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16201>
This commit is contained in:
Alyssa Rosenzweig 2022-04-27 14:09:01 -04:00 committed by Marge Bot
parent 1842e14a73
commit 579fd30209
4 changed files with 40 additions and 13 deletions

View file

@ -206,7 +206,7 @@ pan_prepare_zs(const struct pan_fb_info *fb,
#if PAN_ARCH >= 6
const struct pan_image_slice_layout *slice = &zs->image->layout.slices[level];
ext->zs_afbc_row_stride = slice->afbc.row_stride /
ext->zs_afbc_row_stride = slice->row_stride /
AFBC_HEADER_BYTES_PER_TILE;
#else
ext->zs_block_format = MALI_BLOCK_FORMAT_AFBC;
@ -448,7 +448,7 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned idx,
const struct pan_image_slice_layout *slice = &rt->image->layout.slices[level];
#if PAN_ARCH >= 6
cfg->afbc.row_stride = slice->afbc.row_stride /
cfg->afbc.row_stride = slice->row_stride /
AFBC_HEADER_BYTES_PER_TILE;
cfg->afbc.afbc_wide_block_enable =
panfrost_afbc_is_wide(rt->image->layout.modifier);

View file

@ -169,9 +169,17 @@ panfrost_get_legacy_stride(const struct pan_image_layout *layout,
unsigned level)
{
unsigned row_stride = layout->slices[level].row_stride;
unsigned bh = panfrost_block_size(layout->modifier, layout->format).height;
struct pan_block_size block_size =
panfrost_block_size(layout->modifier, layout->format);
return row_stride / bh;
if (drm_is_afbc(layout->modifier)) {
unsigned width = u_minify(layout->width, level);
width = ALIGN_POT(width, block_size.width);
return width * util_format_get_blocksize(layout->format);
} else {
return row_stride / block_size.height;
}
}
unsigned
@ -179,7 +187,16 @@ panfrost_from_legacy_stride(unsigned legacy_stride,
enum pipe_format format,
uint64_t modifier)
{
return legacy_stride * panfrost_block_size(modifier, format).height;
struct pan_block_size block_size =
panfrost_block_size(modifier, format);
if (drm_is_afbc(modifier)) {
unsigned width = legacy_stride / util_format_get_blocksize(format);
return (width / block_size.width) * AFBC_HEADER_BYTES_PER_TILE;
} else {
return legacy_stride * block_size.height;
}
}
/* Computes the offset into a texture at a particular level/face. Add to
@ -247,7 +264,7 @@ pan_image_layout_init(struct pan_image_layout *layout,
unsigned row_stride = fmt_blocksize * effective_width * block_size.height;
if (explicit_layout) {
if (explicit_layout && !afbc) {
/* Make sure the explicit stride is valid */
if (explicit_layout->row_stride < row_stride)
return false;
@ -258,8 +275,6 @@ pan_image_layout_init(struct pan_image_layout *layout,
row_stride = ALIGN_POT(row_stride, 64);
}
slice->row_stride = row_stride;
unsigned slice_one_size = row_stride * (effective_height / block_size.height);
/* Compute AFBC sizes if necessary */
@ -268,10 +283,13 @@ pan_image_layout_init(struct pan_image_layout *layout,
panfrost_afbc_header_size(width, height);
/* Stride between two rows of AFBC headers */
slice->afbc.row_stride =
slice->row_stride =
(effective_width / block_size.width) *
AFBC_HEADER_BYTES_PER_TILE;
if (explicit_layout && explicit_layout->row_stride < slice->row_stride)
return false;
/* AFBC body size */
slice->afbc.body_size = slice_one_size;
@ -289,6 +307,8 @@ pan_image_layout_init(struct pan_image_layout *layout,
slice_one_size += slice->afbc.header_size;
slice->afbc.surface_stride = slice_one_size;
}
} else {
slice->row_stride = row_stride;
}
unsigned slice_full_size =

View file

@ -242,7 +242,7 @@ panfrost_get_surface_strides(const struct pan_image_layout *layout,
if (drm_is_afbc(layout->modifier)) {
/* Pre v7 don't have a row stride field. This field is
* repurposed as a Y offset which we don't use */
*row_stride = PAN_ARCH < 7 ? 0 : slice->afbc.row_stride;
*row_stride = PAN_ARCH < 7 ? 0 : slice->row_stride;
*surf_stride = slice->afbc.surface_stride;
} else {
*row_stride = slice->row_stride;

View file

@ -49,7 +49,17 @@ extern uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT];
struct pan_image_slice_layout {
unsigned offset;
/* For AFBC images, the number of bytes between two rows of AFBC
* headers.
*
* For non-AFBC images, the number of bytes between two rows of texels.
* For linear images, this will equal the logical stride. For
* images that are compressed or interleaved, this will be greater than
* the logical stride.
*/
unsigned row_stride;
unsigned surface_stride;
struct {
@ -59,9 +69,6 @@ struct pan_image_slice_layout {
/* Size of the AFBC body */
unsigned body_size;
/* Stride between two rows of AFBC headers */
unsigned row_stride;
/* Stride between AFBC headers of two consecutive surfaces.
* For 3D textures, this must be set to header size since
* AFBC headers are allocated together, for 2D arrays this