pan/layout: Allow bigger size/surface stride on v12+

v11 started extending the size/surface stride of a few descriptors to
allow bigger images. Add the necessary code to take that into account.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Reviewed-by: Christoph Pillmayer <christoph.pillmayer@arm.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Tested-by: Mary Guillemard <mary.guillemard@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35731>
This commit is contained in:
Boris Brezillon 2025-06-24 11:31:43 +02:00 committed by Marge Bot
parent 7a763bb0a3
commit c2c91e78fd
4 changed files with 83 additions and 41 deletions

View file

@ -229,6 +229,16 @@ get_afbc_att_mem_props(struct pan_image_plane_ref pref, unsigned mip_level,
*header = plane->base + slayout->offset_B + (stride_B * layer_or_z_slice); *header = plane->base + slayout->offset_B + (stride_B * layer_or_z_slice);
} }
#if PAN_ARCH <= 10
#define SET_SURFACE_STRIDE(cfg__, val__) (cfg__).surface_stride = val__
#else
#define SET_SURFACE_STRIDE(cfg__, val__) \
do { \
(cfg__).surface_stride = val__ & BITFIELD_MASK(32); \
(cfg__).surface_stride_hi = val__ >> 32; \
} while (0)
#endif
void void
GENX(pan_emit_linear_s_attachment)(const struct pan_fb_info *fb, GENX(pan_emit_linear_s_attachment)(const struct pan_fb_info *fb,
unsigned layer_or_z_slice, void *payload) unsigned layer_or_z_slice, void *payload)
@ -245,7 +255,7 @@ GENX(pan_emit_linear_s_attachment)(const struct pan_fb_info *fb,
cfg.block_format = MALI_BLOCK_FORMAT_LINEAR; cfg.block_format = MALI_BLOCK_FORMAT_LINEAR;
cfg.base = base; cfg.base = base;
cfg.row_stride = row_stride; cfg.row_stride = row_stride;
cfg.surface_stride = surf_stride; SET_SURFACE_STRIDE(cfg, surf_stride);
} }
} }
@ -289,7 +299,7 @@ GENX(pan_emit_u_tiled_s_attachment)(const struct pan_fb_info *fb,
cfg.block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED; cfg.block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
cfg.base = base; cfg.base = base;
cfg.row_stride = row_stride; cfg.row_stride = row_stride;
cfg.surface_stride = surf_stride; SET_SURFACE_STRIDE(cfg, surf_stride);
} }
} }
@ -309,7 +319,7 @@ GENX(pan_emit_linear_zs_attachment)(const struct pan_fb_info *fb,
cfg.block_format = MALI_BLOCK_FORMAT_LINEAR; cfg.block_format = MALI_BLOCK_FORMAT_LINEAR;
cfg.base = base; cfg.base = base;
cfg.row_stride = row_stride; cfg.row_stride = row_stride;
cfg.surface_stride = surf_stride; SET_SURFACE_STRIDE(cfg, surf_stride);
} }
} }
@ -329,7 +339,7 @@ GENX(pan_emit_u_tiled_zs_attachment)(const struct pan_fb_info *fb,
cfg.block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED; cfg.block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
cfg.base = base; cfg.base = base;
cfg.row_stride = row_stride; cfg.row_stride = row_stride;
cfg.surface_stride = surf_stride; SET_SURFACE_STRIDE(cfg, surf_stride);
} }
} }

View file

@ -42,7 +42,7 @@ struct pan_afbc_image_slice_layout {
/* For 3D textures, this is the stride in bytes between AFBC headers of two /* For 3D textures, this is the stride in bytes between AFBC headers of two
* consecutive Z slices. For 2D, this is the total size of the 2D level. * consecutive Z slices. For 2D, this is the total size of the 2D level.
*/ */
uint32_t surface_stride_B; uint64_t surface_stride_B;
}; };
struct pan_tiled_or_linear_image_slice_layout { struct pan_tiled_or_linear_image_slice_layout {
@ -53,7 +53,7 @@ struct pan_tiled_or_linear_image_slice_layout {
* consecutive Z slices. For 2DMS textures, this is the stride in bytes * consecutive Z slices. For 2DMS textures, this is the stride in bytes
* between two sample planes. * between two sample planes.
*/ */
uint32_t surface_stride_B; uint64_t surface_stride_B;
}; };
struct pan_image_slice_layout { struct pan_image_slice_layout {

View file

@ -16,6 +16,14 @@
#include "util/format/u_format.h" #include "util/format/u_format.h"
#if PAN_ARCH <= 10
#define MAX_SIZE_B u_uintN_max(32)
#define MAX_SLICE_STRIDE_B u_uintN_max(32)
#else
#define MAX_SIZE_B u_uintN_max(48)
#define MAX_SLICE_STRIDE_B u_uintN_max(37)
#endif
static bool static bool
pan_mod_afbc_match(uint64_t mod) pan_mod_afbc_match(uint64_t mod)
{ {
@ -267,14 +275,15 @@ pan_mod_afrc_init_slice_layout(
(uint64_t)slayout->tiled_or_linear.row_stride_B * (uint64_t)slayout->tiled_or_linear.row_stride_B *
DIV_ROUND_UP(aligned_extent_px.height, aligned_extent_px.height); DIV_ROUND_UP(aligned_extent_px.height, aligned_extent_px.height);
/* Surface stride is passed as a 32-bit unsigned integer to RT/ZS and texture
* descriptors, make sure it fits. */
if (surf_stride_B > UINT32_MAX)
return false;
slayout->tiled_or_linear.surface_stride_B = surf_stride_B; slayout->tiled_or_linear.surface_stride_B = surf_stride_B;
slayout->size_B = slayout->size_B =
surf_stride_B * aligned_extent_px.depth * props->nr_samples; surf_stride_B * aligned_extent_px.depth * props->nr_samples;
/* Make sure the stride/size fits in the descriptor fields. */
if (slayout->size_B > MAX_SIZE_B ||
slayout->tiled_or_linear.surface_stride_B > MAX_SLICE_STRIDE_B)
return false;
return true; return true;
} }
@ -389,13 +398,14 @@ pan_mod_u_tiled_init_slice_layout(
DIV_ROUND_UP(mip_extent_el.height, tile_extent_el.height); DIV_ROUND_UP(mip_extent_el.height, tile_extent_el.height);
surf_stride_B = ALIGN_POT(surf_stride_B, (uint64_t)align_mask + 1); surf_stride_B = ALIGN_POT(surf_stride_B, (uint64_t)align_mask + 1);
/* Surface stride is passed as a 32-bit unsigned integer to RT/ZS and texture
* descriptors, make sure it fits. */
if (surf_stride_B > UINT32_MAX)
return false;
slayout->tiled_or_linear.surface_stride_B = surf_stride_B; slayout->tiled_or_linear.surface_stride_B = surf_stride_B;
slayout->size_B = surf_stride_B * mip_extent_el.depth * props->nr_samples; slayout->size_B = surf_stride_B * mip_extent_el.depth * props->nr_samples;
/* Make sure the stride/size fits in the descriptor fields. */
if (slayout->size_B > MAX_SIZE_B ||
slayout->tiled_or_linear.surface_stride_B > MAX_SLICE_STRIDE_B)
return false;
return true; return true;
} }

View file

@ -339,11 +339,30 @@ translate_superblock_size(uint64_t modifier)
} while (0) } while (0)
#endif #endif
#if PAN_ARCH > 10
#define PLANE_SET_SIZE(cfg__, size__) \
do { \
(cfg__).size = size__ & BITFIELD_MASK(32); \
(cfg__).size_hi = size__ >> 32; \
} while (0)
#define PLANE_SET_SLICE_STRIDE(cfg__, size__) \
do { \
(cfg__).slice_stride = size__ & BITFIELD_MASK(32); \
(cfg__).slice_stride_hi = size__ >> 32; \
} while (0)
#elif PAN_ARCH >= 9
#define PLANE_SET_SIZE(cfg__, size__) (cfg__).size = size__
#define PLANE_SET_SLICE_STRIDE(cfg__, size__) \
(cfg__).slice_stride = size__
#endif
static void static void
pan_emit_bview_plane(const struct pan_buffer_view *bview, void *payload) pan_emit_bview_plane(const struct pan_buffer_view *bview, void *payload)
{ {
const struct util_format_description *desc = const struct util_format_description *desc =
util_format_description(bview->format); util_format_description(bview->format);
uint64_t size =
(uint64_t)util_format_get_blocksize(bview->format) * bview->width_el;
if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC) { if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC) {
bool srgb = (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB); bool srgb = (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
@ -363,8 +382,7 @@ pan_emit_bview_plane(const struct pan_buffer_view *bview, void *payload)
cfg.block_height = pan_astc_dim_3d(desc->block.height); cfg.block_height = pan_astc_dim_3d(desc->block.height);
cfg.block_depth = pan_astc_dim_3d(desc->block.depth); cfg.block_depth = pan_astc_dim_3d(desc->block.depth);
cfg.pointer = bview->base; cfg.pointer = bview->base;
cfg.size = PLANE_SET_SIZE(cfg, size);
util_format_get_blocksize(bview->format) * bview->width_el;
PLANE_SET_EXTENT(cfg, bview->width_el, 1); PLANE_SET_EXTENT(cfg, bview->width_el, 1);
} }
} else { } else {
@ -374,8 +392,7 @@ pan_emit_bview_plane(const struct pan_buffer_view *bview, void *payload)
cfg.decode_wide = wide; cfg.decode_wide = wide;
cfg.block_width = pan_astc_dim_2d(desc->block.width); cfg.block_width = pan_astc_dim_2d(desc->block.width);
cfg.block_height = pan_astc_dim_2d(desc->block.height); cfg.block_height = pan_astc_dim_2d(desc->block.height);
cfg.size = PLANE_SET_SIZE(cfg, size);
util_format_get_blocksize(bview->format) * bview->width_el;
cfg.pointer = bview->base; cfg.pointer = bview->base;
PLANE_SET_EXTENT(cfg, bview->width_el, 1); PLANE_SET_EXTENT(cfg, bview->width_el, 1);
} }
@ -384,7 +401,7 @@ pan_emit_bview_plane(const struct pan_buffer_view *bview, void *payload)
pan_cast_and_pack(payload, GENERIC_PLANE, cfg) { pan_cast_and_pack(payload, GENERIC_PLANE, cfg) {
cfg.clump_ordering = MALI_CLUMP_ORDERING_LINEAR; cfg.clump_ordering = MALI_CLUMP_ORDERING_LINEAR;
cfg.clump_format = pan_clump_format(bview->format); cfg.clump_format = pan_clump_format(bview->format);
cfg.size = util_format_get_blocksize(bview->format) * bview->width_el; PLANE_SET_SIZE(cfg, size);
cfg.pointer = bview->base; cfg.pointer = bview->base;
cfg.clump_ordering = MALI_CLUMP_ORDERING_LINEAR; cfg.clump_ordering = MALI_CLUMP_ORDERING_LINEAR;
PLANE_SET_EXTENT(cfg, bview->width_el, 1); PLANE_SET_EXTENT(cfg, bview->width_el, 1);
@ -396,8 +413,8 @@ static void
get_linear_or_u_tiled_plane_props(const struct pan_image_view *iview, get_linear_or_u_tiled_plane_props(const struct pan_image_view *iview,
int plane_idx, unsigned mip_level, int plane_idx, unsigned mip_level,
unsigned layer_or_z_slice, uint64_t *pointer, unsigned layer_or_z_slice, uint64_t *pointer,
uint32_t *row_stride, uint32_t *slice_stride, uint32_t *row_stride, uint64_t *slice_stride,
uint32_t *size) uint64_t *size)
{ {
const struct util_format_description *desc = const struct util_format_description *desc =
util_format_description(iview->format); util_format_description(iview->format);
@ -439,8 +456,8 @@ emit_generic_plane(const struct pan_image_view *iview, int plane_idx,
? pan_image_view_get_s_plane(iview) ? pan_image_view_get_s_plane(iview)
: pan_image_view_get_plane(iview, plane_idx); : pan_image_view_get_plane(iview, plane_idx);
const struct pan_image_props *props = &pref.image->props; const struct pan_image_props *props = &pref.image->props;
uint32_t plane_size, row_stride, slice_stride; uint64_t plane_addr, plane_size, slice_stride;
uint64_t plane_addr; uint32_t row_stride;
/* 3-planar formats must use Chroma 2p planes for the U V planes. */ /* 3-planar formats must use Chroma 2p planes for the U V planes. */
assert(plane_idx == 0 || desc->layout != UTIL_FORMAT_LAYOUT_PLANAR3); assert(plane_idx == 0 || desc->layout != UTIL_FORMAT_LAYOUT_PLANAR3);
@ -457,10 +474,10 @@ emit_generic_plane(const struct pan_image_view *iview, int plane_idx,
? MALI_CLUMP_ORDERING_TILED_U_INTERLEAVED ? MALI_CLUMP_ORDERING_TILED_U_INTERLEAVED
: MALI_CLUMP_ORDERING_LINEAR; : MALI_CLUMP_ORDERING_LINEAR;
cfg.clump_format = pan_clump_format(iview->format); cfg.clump_format = pan_clump_format(iview->format);
cfg.size = plane_size; PLANE_SET_SIZE(cfg, plane_size);
cfg.pointer = plane_addr; cfg.pointer = plane_addr;
cfg.row_stride = row_stride; cfg.row_stride = row_stride;
cfg.slice_stride = slice_stride; PLANE_SET_SLICE_STRIDE(cfg, slice_stride);
PLANE_SET_EXTENT(cfg, u_minify(props->extent_px.width, mip_level), PLANE_SET_EXTENT(cfg, u_minify(props->extent_px.width, mip_level),
u_minify(props->extent_px.height, mip_level)); u_minify(props->extent_px.height, mip_level));
} }
@ -476,8 +493,8 @@ emit_astc_plane(const struct pan_image_view *iview, int plane_idx,
pan_image_view_get_plane(iview, plane_idx); pan_image_view_get_plane(iview, plane_idx);
const struct pan_image_props *props = &pref.image->props; const struct pan_image_props *props = &pref.image->props;
bool srgb = (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB); bool srgb = (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
uint32_t plane_size, row_stride, slice_stride; uint64_t plane_addr, plane_size, slice_stride;
uint64_t plane_addr; uint32_t row_stride;
/* sRGB formats decode to RGBA8 sRGB, which is narrow. /* sRGB formats decode to RGBA8 sRGB, which is narrow.
* *
@ -501,10 +518,10 @@ emit_astc_plane(const struct pan_image_view *iview, int plane_idx,
: MALI_CLUMP_ORDERING_LINEAR; \ : MALI_CLUMP_ORDERING_LINEAR; \
cfg.decode_hdr = iview->astc.hdr; \ cfg.decode_hdr = iview->astc.hdr; \
cfg.decode_wide = wide; \ cfg.decode_wide = wide; \
cfg.size = plane_size; \ PLANE_SET_SIZE(cfg, plane_size); \
cfg.pointer = plane_addr; \ cfg.pointer = plane_addr; \
cfg.row_stride = row_stride; \ cfg.row_stride = row_stride; \
cfg.slice_stride = slice_stride; \ PLANE_SET_SLICE_STRIDE(cfg, slice_stride); \
PLANE_SET_EXTENT(cfg, u_minify(props->extent_px.width, mip_level), \ PLANE_SET_EXTENT(cfg, u_minify(props->extent_px.width, mip_level), \
u_minify(props->extent_px.height, mip_level)) u_minify(props->extent_px.height, mip_level))
@ -554,9 +571,10 @@ emit_linear_or_u_tiled_chroma_2p_plane(const struct pan_image_view *iview,
util_format_description(iview->format); util_format_description(iview->format);
const struct pan_image_plane_ref pref1 = pan_image_view_get_plane(iview, 1); const struct pan_image_plane_ref pref1 = pan_image_view_get_plane(iview, 1);
const struct pan_image_props *props = &pref1.image->props; const struct pan_image_props *props = &pref1.image->props;
uint64_t cplane1_addr, cplane2_addr; uint64_t cplane1_addr, cplane2_addr, cplane1_slice_stride, cplane1_size;
uint32_t cplane1_row_stride, cplane1_slice_stride, cplane1_size; ASSERTED uint64_t cplane2_slice_stride, cplane2_size;
ASSERTED uint32_t cplane2_row_stride, cplane2_slice_stride, cplane2_size; ASSERTED uint32_t cplane2_row_stride;
uint32_t cplane1_row_stride;
get_linear_or_u_tiled_plane_props(iview, 1, mip_level, get_linear_or_u_tiled_plane_props(iview, 1, mip_level,
layer_or_z_slice, &cplane1_addr, &cplane1_row_stride, layer_or_z_slice, &cplane1_addr, &cplane1_row_stride,
@ -579,7 +597,7 @@ emit_linear_or_u_tiled_chroma_2p_plane(const struct pan_image_view *iview,
? MALI_CLUMP_ORDERING_TILED_U_INTERLEAVED ? MALI_CLUMP_ORDERING_TILED_U_INTERLEAVED
: MALI_CLUMP_ORDERING_LINEAR; : MALI_CLUMP_ORDERING_LINEAR;
cfg.clump_format = pan_clump_format(iview->format); cfg.clump_format = pan_clump_format(iview->format);
cfg.size = cplane1_size; PLANE_SET_SIZE(cfg, cplane1_size);
cfg.pointer = cplane1_addr; cfg.pointer = cplane1_addr;
cfg.row_stride = cplane1_row_stride; cfg.row_stride = cplane1_row_stride;
PLANE_SET_EXTENT(cfg, u_minify(props->extent_px.width, mip_level), PLANE_SET_EXTENT(cfg, u_minify(props->extent_px.width, mip_level),
@ -595,8 +613,8 @@ static void
get_afbc_plane_props(const struct pan_image_view *iview, int plane_idx, get_afbc_plane_props(const struct pan_image_view *iview, int plane_idx,
unsigned mip_level, unsigned layer_or_z_slice, unsigned mip_level, unsigned layer_or_z_slice,
uint64_t *header_pointer, uint32_t *header_row_stride, uint64_t *header_pointer, uint32_t *header_row_stride,
uint32_t *header_slice_size, uint32_t *header_slice_stride, uint32_t *header_slice_size, uint64_t *header_slice_stride,
uint32_t *size) uint64_t *size)
{ {
const struct util_format_description *desc = const struct util_format_description *desc =
util_format_description(iview->format); util_format_description(iview->format);
@ -647,9 +665,8 @@ emit_afbc_plane(const struct pan_image_view *iview, int plane_idx,
: pan_image_view_get_plane(iview, plane_idx); : pan_image_view_get_plane(iview, plane_idx);
const struct pan_image *image = pref.image; const struct pan_image *image = pref.image;
const struct pan_image_props *props = &image->props; const struct pan_image_props *props = &image->props;
uint32_t header_slice_size, header_row_stride, header_slice_stride; uint64_t header_slice_stride, plane_size, header_addr;
uint32_t plane_size; uint32_t header_slice_size, header_row_stride;
uint64_t header_addr;
get_afbc_plane_props(iview, plane_idx, mip_level, layer_or_z_slice, get_afbc_plane_props(iview, plane_idx, mip_level, layer_or_z_slice,
&header_addr, &header_row_stride, &header_slice_size, &header_addr, &header_row_stride, &header_slice_size,
@ -668,11 +685,16 @@ emit_afbc_plane(const struct pan_image_view *iview, int plane_idx,
cfg.prefetch = true; cfg.prefetch = true;
cfg.compression_mode = cfg.compression_mode =
pan_afbc_compression_mode(iview->format, plane_idx); pan_afbc_compression_mode(iview->format, plane_idx);
cfg.size = plane_size; PLANE_SET_SIZE(cfg, plane_size);
cfg.pointer = header_addr; cfg.pointer = header_addr;
cfg.header_row_stride = header_row_stride; cfg.header_row_stride = header_row_stride;
cfg.header_slice_size = header_slice_size; cfg.header_slice_size = header_slice_size;
#if PAN_ARCH <= 10
cfg.header_slice_stride = header_slice_stride; cfg.header_slice_stride = header_slice_stride;
#else
cfg.header_slice_stride = header_slice_stride & BITFIELD_MASK(32);
cfg.header_slice_stride_hi = header_slice_stride >> 32;
#endif
PLANE_SET_EXTENT(cfg, u_minify(props->extent_px.width, mip_level), PLANE_SET_EXTENT(cfg, u_minify(props->extent_px.width, mip_level),
u_minify(props->extent_px.height, mip_level)); u_minify(props->extent_px.height, mip_level));
} }