mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 00:30:11 +01:00
panfrost: update AFBC code to handle tiling for 64bpp formats
We had assumed AFBC superblocks were always tiled in an 8x8 pattern, but this is true only for 32bpp and lower formats; for larger formats the pattern is 4x4. This isn't an issue yet, but will be when we support R16G16B16A16 in AFBC. Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35771>
This commit is contained in:
parent
3303a04d4f
commit
7a1ef0cf85
6 changed files with 48 additions and 37 deletions
|
|
@ -3618,10 +3618,11 @@ panfrost_afbc_size(struct panfrost_batch *batch, struct panfrost_resource *src,
|
|||
.src = src->plane.base + slice->offset_B,
|
||||
.layout = layout->ptr.gpu + offset,
|
||||
};
|
||||
unsigned stride_sb = pan_afbc_stride_blocks(src->image.props.modifier,
|
||||
unsigned stride_sb = pan_afbc_stride_blocks(src->image.props.format,
|
||||
src->image.props.modifier,
|
||||
slice->afbc.header.row_stride_B);
|
||||
unsigned nr_sblocks =
|
||||
stride_sb * pan_afbc_height_blocks(
|
||||
stride_sb * pan_afbc_height_blocks(src->image.props.format,
|
||||
src->image.props.modifier,
|
||||
u_minify(src->image.props.extent_px.height, level));
|
||||
|
||||
|
|
@ -3642,12 +3643,12 @@ panfrost_afbc_pack(struct panfrost_batch *batch, struct panfrost_resource *src,
|
|||
|
||||
struct panfrost_device *dev = pan_device(src->base.screen);
|
||||
struct pan_image_slice_layout *src_slice = &src->plane.layout.slices[level];
|
||||
unsigned src_stride_sb = pan_afbc_stride_blocks(
|
||||
unsigned src_stride_sb = pan_afbc_stride_blocks(src->image.props.format,
|
||||
src->image.props.modifier, src_slice->afbc.header.row_stride_B);
|
||||
unsigned dst_stride_sb = pan_afbc_stride_blocks(
|
||||
unsigned dst_stride_sb = pan_afbc_stride_blocks(src->image.props.format,
|
||||
src->image.props.modifier, dst_slice->afbc.header.row_stride_B);
|
||||
unsigned nr_sblocks =
|
||||
src_stride_sb * pan_afbc_height_blocks(
|
||||
src_stride_sb * pan_afbc_height_blocks(src->image.props.format,
|
||||
src->image.props.modifier,
|
||||
u_minify(src->image.props.extent_px.height, level));
|
||||
struct panfrost_afbc_pack_info consts = {
|
||||
|
|
|
|||
|
|
@ -2013,6 +2013,7 @@ pan_resource_afbcp_get_payload_sizes(struct panfrost_context *ctx,
|
|||
|
||||
struct panfrost_screen *screen = pan_screen(ctx->base.screen);
|
||||
struct panfrost_device *dev = pan_device(ctx->base.screen);
|
||||
enum pipe_format format = prsrc->base.format;
|
||||
uint64_t modifier = prsrc->modifier;
|
||||
unsigned last_level = prsrc->base.last_level;
|
||||
unsigned layout_size = 0;
|
||||
|
|
@ -2022,9 +2023,9 @@ pan_resource_afbcp_get_payload_sizes(struct panfrost_context *ctx,
|
|||
&prsrc->plane.layout.slices[level];
|
||||
unsigned nr_blocks =
|
||||
pan_afbc_stride_blocks(
|
||||
modifier, slice->afbc.header.row_stride_B) *
|
||||
format, modifier, slice->afbc.header.row_stride_B) *
|
||||
pan_afbc_height_blocks(
|
||||
modifier, u_minify(prsrc->image.props.extent_px.height, level));
|
||||
format, modifier, u_minify(prsrc->image.props.extent_px.height, level));
|
||||
prsrc->afbcp->layout_offsets[level] = layout_size;
|
||||
layout_size += nr_blocks * sizeof(struct pan_afbc_payload_extent);
|
||||
}
|
||||
|
|
@ -2111,6 +2112,7 @@ pan_resource_afbcp_get_payload_offsets(struct panfrost_context *ctx,
|
|||
|
||||
struct panfrost_device *dev = pan_device(ctx->base.screen);
|
||||
uint64_t modifier = prsrc->modifier;
|
||||
enum pipe_format format = prsrc->base.format;
|
||||
unsigned last_level = prsrc->base.last_level;
|
||||
unsigned total_size = 0;
|
||||
|
||||
|
|
@ -2121,9 +2123,9 @@ pan_resource_afbcp_get_payload_offsets(struct panfrost_context *ctx,
|
|||
&prsrc->afbcp->plane.layout.slices[level];
|
||||
unsigned nr_blocks_total =
|
||||
pan_afbc_stride_blocks(
|
||||
modifier, src_slice->afbc.header.row_stride_B) *
|
||||
format, modifier, src_slice->afbc.header.row_stride_B) *
|
||||
pan_afbc_height_blocks(
|
||||
modifier, u_minify(prsrc->image.props.extent_px.height, level));
|
||||
format, modifier, u_minify(prsrc->image.props.extent_px.height, level));
|
||||
uint32_t body_offset_B = pan_afbc_body_offset(
|
||||
dev->arch, modifier, src_slice->afbc.header.surface_size_B);
|
||||
struct pan_afbc_payload_extent *layout =
|
||||
|
|
|
|||
|
|
@ -387,12 +387,16 @@ pan_afbc_body_offset(unsigned arch, uint64_t modifier, uint32_t header_size)
|
|||
|
||||
/*
|
||||
* Determine the tile size used by AFBC. This tiles superblocks themselves.
|
||||
* Current GPUs support either 8x8 tiling or no tiling (1x1)
|
||||
* Current GPUs support either 8x8 tiling or no tiling (1x1) for most
|
||||
* formats; but note that formats with more than 32bpp use 4x4 tiling
|
||||
*/
|
||||
static inline unsigned
|
||||
pan_afbc_tile_size(uint64_t modifier)
|
||||
pan_afbc_tile_size(enum pipe_format format, uint64_t modifier)
|
||||
{
|
||||
return (modifier & AFBC_FORMAT_MOD_TILED) ? 8 : 1;
|
||||
if ( !(modifier & AFBC_FORMAT_MOD_TILED) ) {
|
||||
return 1;
|
||||
}
|
||||
return util_format_get_blocksizebits(format) <= 32 ? 8 : 4;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -403,11 +407,11 @@ pan_afbc_tile_size(uint64_t modifier)
|
|||
* header blocks are in a tile together.
|
||||
*/
|
||||
static inline uint32_t
|
||||
pan_afbc_row_stride(uint64_t modifier, uint32_t width)
|
||||
pan_afbc_row_stride(enum pipe_format format, uint64_t modifier, uint32_t width)
|
||||
{
|
||||
unsigned block_width = pan_afbc_superblock_width(modifier);
|
||||
|
||||
return (width / block_width) * pan_afbc_tile_size(modifier) *
|
||||
return (width / block_width) * pan_afbc_tile_size(format, modifier) *
|
||||
AFBC_HEADER_BYTES_PER_TILE;
|
||||
}
|
||||
|
||||
|
|
@ -418,21 +422,21 @@ pan_afbc_row_stride(uint64_t modifier, uint32_t width)
|
|||
* blocks, rather than a real row stride. This is required by Bifrost.
|
||||
*/
|
||||
static inline uint32_t
|
||||
pan_afbc_stride_blocks(uint64_t modifier, uint32_t row_stride_bytes)
|
||||
pan_afbc_stride_blocks(enum pipe_format format, uint64_t modifier, uint32_t row_stride_bytes)
|
||||
{
|
||||
return row_stride_bytes /
|
||||
(AFBC_HEADER_BYTES_PER_TILE * pan_afbc_tile_size(modifier));
|
||||
(AFBC_HEADER_BYTES_PER_TILE * pan_afbc_tile_size(format, modifier));
|
||||
}
|
||||
|
||||
/* Returns a height in superblocks taking into account the tile alignment
|
||||
* requirement coming from the modifier.
|
||||
*/
|
||||
static inline uint32_t
|
||||
pan_afbc_height_blocks(uint64_t modifier, uint32_t height_px)
|
||||
pan_afbc_height_blocks(enum pipe_format format, uint64_t modifier, uint32_t height_px)
|
||||
{
|
||||
return ALIGN_POT(
|
||||
DIV_ROUND_UP(height_px, pan_afbc_superblock_height(modifier)),
|
||||
pan_afbc_tile_size(modifier));
|
||||
pan_afbc_tile_size(format, modifier));
|
||||
}
|
||||
|
||||
static inline enum pipe_format
|
||||
|
|
|
|||
|
|
@ -371,7 +371,8 @@ GENX(pan_emit_afbc_zs_attachment)(const struct pan_fb_info *fb,
|
|||
|
||||
#if PAN_ARCH >= 6
|
||||
cfg.header_row_stride =
|
||||
pan_afbc_stride_blocks(pref.image->props.modifier, hdr_row_stride);
|
||||
pan_afbc_stride_blocks(pref.image->props.format,
|
||||
pref.image->props.modifier, hdr_row_stride);
|
||||
#else
|
||||
cfg.body_size = 0x1000;
|
||||
cfg.chunk_size = 9;
|
||||
|
|
@ -727,7 +728,8 @@ GENX(pan_emit_afbc_color_attachment)(const struct pan_fb_info *fb,
|
|||
|
||||
#if PAN_ARCH >= 6
|
||||
cfg.row_stride =
|
||||
pan_afbc_stride_blocks(image->props.modifier, hdr_row_stride);
|
||||
pan_afbc_stride_blocks(image->props.format,
|
||||
image->props.modifier, hdr_row_stride);
|
||||
#else
|
||||
const struct pan_image_plane *plane = image->planes[pref.plane_idx];
|
||||
const struct pan_image_slice_layout *slayout =
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ pan_mod_afbc_get_wsi_row_pitch(const struct pan_image *image,
|
|||
tile_extent_el.width * tile_extent_el.height *
|
||||
pan_format_get_plane_blocksize(props->format, plane_idx);
|
||||
const unsigned tile_row_payload_size_B =
|
||||
pan_afbc_stride_blocks(props->modifier, header_row_stride_B) *
|
||||
pan_afbc_stride_blocks(props->format,
|
||||
props->modifier, header_row_stride_B) *
|
||||
tile_payload_size_B;
|
||||
|
||||
return tile_row_payload_size_B / pan_afbc_superblock_height(props->modifier);
|
||||
|
|
@ -95,10 +96,10 @@ pan_mod_afbc_init_slice_layout(
|
|||
if (props->modifier & AFBC_FORMAT_MOD_TILED) {
|
||||
align_px.width =
|
||||
ALIGN_POT(align_px.width, afbc_tile_extent_px.width *
|
||||
pan_afbc_tile_size(props->modifier));
|
||||
pan_afbc_tile_size(props->format, props->modifier));
|
||||
align_px.height =
|
||||
ALIGN_POT(align_px.height, afbc_tile_extent_px.height *
|
||||
pan_afbc_tile_size(props->modifier));
|
||||
pan_afbc_tile_size(props->format, props->modifier));
|
||||
}
|
||||
|
||||
struct pan_image_extent aligned_extent_px = {
|
||||
|
|
@ -134,7 +135,7 @@ pan_mod_afbc_init_slice_layout(
|
|||
}
|
||||
|
||||
slayout->afbc.header.row_stride_B =
|
||||
pan_afbc_row_stride(props->modifier, width_from_wsi_row_stride);
|
||||
pan_afbc_row_stride(props->format, props->modifier, width_from_wsi_row_stride);
|
||||
if (slayout->afbc.header.row_stride_B & row_align_mask) {
|
||||
mesa_loge("WSI pitch not properly aligned");
|
||||
return false;
|
||||
|
|
@ -150,7 +151,7 @@ pan_mod_afbc_init_slice_layout(
|
|||
* the resource width to get the size. */
|
||||
if (!layout_constraints->strict) {
|
||||
slayout->afbc.header.row_stride_B = ALIGN_POT(
|
||||
pan_afbc_row_stride(props->modifier, aligned_extent_px.width),
|
||||
pan_afbc_row_stride(props->format, props->modifier, aligned_extent_px.width),
|
||||
row_align_mask + 1);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -158,12 +159,13 @@ pan_mod_afbc_init_slice_layout(
|
|||
ALIGN_POT(layout_constraints ? layout_constraints->offset_B : 0,
|
||||
offset_align_mask + 1);
|
||||
slayout->afbc.header.row_stride_B = ALIGN_POT(
|
||||
pan_afbc_row_stride(props->modifier, aligned_extent_px.width),
|
||||
pan_afbc_row_stride(props->format, props->modifier, aligned_extent_px.width),
|
||||
row_align_mask + 1);
|
||||
}
|
||||
|
||||
const unsigned row_stride_sb = pan_afbc_stride_blocks(
|
||||
props->modifier, slayout->afbc.header.row_stride_B);
|
||||
const unsigned row_stride_sb = pan_afbc_stride_blocks(props->format,
|
||||
props->modifier,
|
||||
slayout->afbc.header.row_stride_B);
|
||||
const unsigned surface_stride_sb =
|
||||
row_stride_sb * (aligned_extent_px.height / afbc_tile_extent_px.height);
|
||||
|
||||
|
|
|
|||
|
|
@ -173,10 +173,10 @@ TEST(BlockSize, AFBCSuperblock64x4)
|
|||
* stride calculations.
|
||||
*/
|
||||
static uint32_t
|
||||
pan_afbc_line_stride(uint64_t modifier, uint32_t width)
|
||||
pan_afbc_line_stride(enum pipe_format format, uint64_t modifier, uint32_t width)
|
||||
{
|
||||
return pan_afbc_stride_blocks(modifier,
|
||||
pan_afbc_row_stride(modifier, width));
|
||||
return pan_afbc_stride_blocks(format, modifier,
|
||||
pan_afbc_row_stride(format, modifier, width));
|
||||
}
|
||||
|
||||
/* Which form of the stride we specify is hardware specific (row stride for
|
||||
|
|
@ -196,17 +196,17 @@ TEST(AFBCStride, Linear)
|
|||
|
||||
for (unsigned m = 0; m < ARRAY_SIZE(modifiers); ++m) {
|
||||
uint64_t modifier = modifiers[m];
|
||||
|
||||
enum pipe_format format = PIPE_FORMAT_R8G8B8A8_UNORM;
|
||||
uint32_t sw = pan_afbc_superblock_width(modifier);
|
||||
uint32_t cases[] = {1, 4, 17, 39};
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(cases); ++i) {
|
||||
uint32_t width = sw * cases[i];
|
||||
|
||||
EXPECT_EQ(pan_afbc_row_stride(modifier, width),
|
||||
EXPECT_EQ(pan_afbc_row_stride(format, modifier, width),
|
||||
16 * DIV_ROUND_UP(width, sw));
|
||||
|
||||
EXPECT_EQ(pan_afbc_line_stride(modifier, width),
|
||||
EXPECT_EQ(pan_afbc_line_stride(format, modifier, width),
|
||||
DIV_ROUND_UP(width, sw));
|
||||
}
|
||||
}
|
||||
|
|
@ -225,17 +225,17 @@ TEST(AFBCStride, Tiled)
|
|||
|
||||
for (unsigned m = 0; m < ARRAY_SIZE(modifiers); ++m) {
|
||||
uint64_t modifier = modifiers[m];
|
||||
|
||||
enum pipe_format format = PIPE_FORMAT_R8_UNORM;
|
||||
uint32_t sw = pan_afbc_superblock_width(modifier);
|
||||
uint32_t cases[] = {1, 4, 17, 39};
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(cases); ++i) {
|
||||
uint32_t width = sw * 8 * cases[i];
|
||||
|
||||
EXPECT_EQ(pan_afbc_row_stride(modifier, width),
|
||||
EXPECT_EQ(pan_afbc_row_stride(format, modifier, width),
|
||||
16 * DIV_ROUND_UP(width, (sw * 8)) * 8 * 8);
|
||||
|
||||
EXPECT_EQ(pan_afbc_line_stride(modifier, width),
|
||||
EXPECT_EQ(pan_afbc_line_stride(format, modifier, width),
|
||||
DIV_ROUND_UP(width, sw * 8) * 8);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue