diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 0711cb4390c..88483185390 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -3611,11 +3611,17 @@ panfrost_afbc_size(struct panfrost_batch *batch, struct panfrost_resource *src, .src = src->plane.base + slice->offset_B, .metadata = metadata->ptr.gpu + offset, }; + unsigned stride_sb = + pan_afbc_stride_blocks(src->image.props.modifier, slice->row_stride_B); + unsigned nr_sblocks = + stride_sb * pan_afbc_height_blocks( + src->image.props.modifier, + u_minify(src->image.props.extent_px.height, level)); panfrost_batch_read_rsrc(batch, src, PIPE_SHADER_COMPUTE); panfrost_batch_write_bo(batch, metadata, PIPE_SHADER_COMPUTE); - LAUNCH_AFBC_CONV_SHADER(size, batch, src, consts, slice->afbc.nr_sblocks); + LAUNCH_AFBC_CONV_SHADER(size, batch, src, consts, nr_sblocks); } static void @@ -3628,21 +3634,28 @@ panfrost_afbc_pack(struct panfrost_batch *batch, struct panfrost_resource *src, MESA_TRACE_FUNC(); struct pan_image_slice_layout *src_slice = &src->plane.layout.slices[level]; + unsigned src_stride_sb = + pan_afbc_stride_blocks(src->image.props.modifier, src_slice->row_stride_B); + unsigned dst_stride_sb = + pan_afbc_stride_blocks(src->image.props.modifier, dst_slice->row_stride_B); + unsigned nr_sblocks = + src_stride_sb * pan_afbc_height_blocks( + src->image.props.modifier, + u_minify(src->image.props.extent_px.height, level)); struct panfrost_afbc_pack_info consts = { .src = src->plane.base + src_slice->offset_B, .dst = dst->ptr.gpu + dst_slice->offset_B, .metadata = metadata->ptr.gpu + metadata_offset_B, .header_size = dst_slice->afbc.header_size_B, - .src_stride = src_slice->afbc.stride_sb, - .dst_stride = dst_slice->afbc.stride_sb, + .src_stride = src_stride_sb, + .dst_stride = dst_stride_sb, }; panfrost_batch_read_rsrc(batch, src, PIPE_SHADER_COMPUTE); panfrost_batch_write_bo(batch, dst, PIPE_SHADER_COMPUTE); panfrost_batch_add_bo(batch, metadata, PIPE_SHADER_COMPUTE); - LAUNCH_AFBC_CONV_SHADER(pack, batch, src, consts, - dst_slice->afbc.nr_sblocks); + LAUNCH_AFBC_CONV_SHADER(pack, batch, src, consts, nr_sblocks); } static void diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index 426c7f99d13..ffba29fbde3 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -1946,7 +1946,13 @@ panfrost_get_afbc_superblock_sizes(struct panfrost_context *ctx, for (int level = first_level; level <= last_level; ++level) { struct pan_image_slice_layout *slice = &rsrc->plane.layout.slices[level]; - unsigned sz = slice->afbc.nr_sblocks * sizeof(struct pan_afbc_block_info); + unsigned stride_sb = + pan_afbc_stride_blocks(rsrc->image.props.modifier, slice->row_stride_B); + unsigned nr_sblocks = + stride_sb * pan_afbc_height_blocks( + rsrc->image.props.modifier, + u_minify(rsrc->image.props.extent_px.height, level)); + unsigned sz = nr_sblocks * sizeof(struct pan_afbc_block_info); out_offsets[level - first_level] = metadata_size; metadata_size += sz; } @@ -2012,7 +2018,10 @@ panfrost_pack_afbc(struct panfrost_context *ctx, struct pan_image_slice_layout *dst_slice = &slice_infos[level]; unsigned src_stride = pan_afbc_stride_blocks(src_modifier, src_slice->row_stride_B); - + unsigned src_nr_sblocks = + src_stride * + pan_afbc_height_blocks( + src_modifier, u_minify(prsrc->image.props.extent_px.height, level)); uint32_t offset = 0; struct pan_afbc_block_info *meta = metadata_bo->ptr.cpu + metadata_offsets[level]; @@ -2027,13 +2036,12 @@ panfrost_pack_afbc(struct panfrost_context *ctx, alignas(16) struct pan_afbc_block_info meta_chunk[64 * 16]; unsigned nr_blocks_per_chunk = ARRAY_SIZE(meta_chunk); - for (unsigned i = 0; i < src_slice->afbc.nr_sblocks; - i += nr_blocks_per_chunk) { - unsigned nr_sblocks = MIN2(nr_blocks_per_chunk, - src_slice->afbc.nr_sblocks - i); + for (unsigned i = 0; i < src_nr_sblocks; i += nr_blocks_per_chunk) { + unsigned nr_sblocks = MIN2(nr_blocks_per_chunk, src_nr_sblocks - i); - util_streaming_load_memcpy(meta_chunk, &meta[i], nr_sblocks - * sizeof(struct pan_afbc_block_info)); + util_streaming_load_memcpy( + meta_chunk, &meta[i], + nr_sblocks * sizeof(struct pan_afbc_block_info)); for (unsigned j = 0; j < nr_sblocks; j++) { unsigned idx = j; @@ -2055,8 +2063,6 @@ panfrost_pack_afbc(struct panfrost_context *ctx, unsigned dst_height = DIV_ROUND_UP(height, pan_afbc_superblock_height(dst_modifier)); - dst_slice->afbc.stride_sb = dst_stride; - dst_slice->afbc.nr_sblocks = dst_stride * dst_height; dst_slice->afbc.header_size_B = ALIGN_POT(dst_stride * dst_height * AFBC_HEADER_BYTES_PER_TILE, pan_afbc_body_align(dev->arch, dst_modifier)); diff --git a/src/panfrost/lib/pan_afbc.h b/src/panfrost/lib/pan_afbc.h index 2099058439d..413d757ec73 100644 --- a/src/panfrost/lib/pan_afbc.h +++ b/src/panfrost/lib/pan_afbc.h @@ -260,6 +260,17 @@ pan_afbc_stride_blocks(uint64_t modifier, uint32_t row_stride_bytes) (AFBC_HEADER_BYTES_PER_TILE * pan_afbc_tile_size(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) +{ + return ALIGN_POT( + DIV_ROUND_UP(height_px, pan_afbc_superblock_height(modifier)), + pan_afbc_tile_size(modifier)); +} + static inline enum pipe_format pan_afbc_unswizzled_format(unsigned arch, enum pipe_format format) { diff --git a/src/panfrost/lib/pan_layout.c b/src/panfrost/lib/pan_layout.c index b5f7d6788a0..286dcb137eb 100644 --- a/src/panfrost/lib/pan_layout.c +++ b/src/panfrost/lib/pan_layout.c @@ -472,12 +472,13 @@ pan_image_layout_init( effective_height_el; } - slice->afbc.stride_sb = + const unsigned stride_sb = pan_afbc_stride_blocks(props->modifier, slice->row_stride_B); - slice->afbc.nr_sblocks = slice->afbc.stride_sb * - (effective_height_px / block_size_el.height); + const unsigned nr_sblocks = + stride_sb * (effective_height_px / block_size_el.height); + slice->afbc.header_size_B = - ALIGN_POT(slice->afbc.nr_sblocks * AFBC_HEADER_BYTES_PER_TILE, + ALIGN_POT(nr_sblocks * AFBC_HEADER_BYTES_PER_TILE, pan_afbc_body_align(arch, props->modifier)); /* AFBC body size */ diff --git a/src/panfrost/lib/pan_layout.h b/src/panfrost/lib/pan_layout.h index 360ec75bfdd..aaeec6e2ccb 100644 --- a/src/panfrost/lib/pan_layout.h +++ b/src/panfrost/lib/pan_layout.h @@ -50,12 +50,6 @@ struct pan_image_slice_layout { unsigned surface_stride_B; struct { - /* Stride in number of superblocks */ - unsigned stride_sb; - - /* Number of superblocks */ - unsigned nr_sblocks; - /* Size of the AFBC header preceding each slice */ unsigned header_size_B;