pan/afbc: Cache the pan_afbc_mode selection

One we have selected a pan_afbc_mode (AKA AFBC format) for an image,
there's no reason for it change, so let's cache that at the
pan_image_layout level and re-use it when we can instead of doing
the pipe format -> afbc mode conversion over and over again.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Eric R. Smith <eric.smith@collabora.com>
Reviewed-by: Christoph Pillmayer <christoph.pillmayer@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37158>
This commit is contained in:
Boris Brezillon 2025-09-04 15:10:57 +02:00 committed by Marge Bot
parent f57cc49683
commit 8c208bc41e
7 changed files with 59 additions and 18 deletions

View file

@ -599,8 +599,7 @@ pan_afbc_can_ytr(enum pipe_format format)
}
static inline bool
pan_afbc_can_split(unsigned arch, enum pipe_format format, uint64_t modifier,
unsigned plane_idx)
pan_afbc_can_split(unsigned arch, enum pan_afbc_mode mode, uint64_t modifier)
{
unsigned block_width = pan_afbc_superblock_width(modifier);
@ -610,7 +609,6 @@ pan_afbc_can_split(unsigned arch, enum pipe_format format, uint64_t modifier,
if (block_width == 16) {
return true;
} else if (block_width == 32) {
enum pan_afbc_mode mode = pan_afbc_format(arch, format, plane_idx);
return (mode == PAN_AFBC_MODE_R8G8B8A8 ||
mode == PAN_AFBC_MODE_R10G10B10A2);
}
@ -640,13 +638,13 @@ pan_afbc_can_tile(unsigned arch)
#if PAN_ARCH >= 9
static inline enum mali_afbc_compression_mode
pan_afbc_compression_mode(enum pipe_format format, unsigned plane_idx)
pan_afbc_compression_mode(enum pan_afbc_mode mode)
{
/* Map canonical formats to the hardware enum. This only
* needs to handle the subset of formats returned by
* pan_afbc_format.
*/
switch (pan_afbc_format(PAN_ARCH, format, plane_idx)) {
switch (mode) {
case PAN_AFBC_MODE_R8:
return MALI_AFBC_COMPRESSION_MODE_R8;
case PAN_AFBC_MODE_R8G8:
@ -698,16 +696,16 @@ pan_afbc_compression_mode(enum pipe_format format, unsigned plane_idx)
static inline enum mali_afbc_compression_mode
pan_afbc_decompression_mode(enum pipe_format view_format,
enum pipe_format img_format, unsigned plane_idx)
enum pan_afbc_mode img_mode)
{
/* There are special cases for texture views of stencil images. */
if (img_format == PIPE_FORMAT_Z24_UNORM_S8_UINT &&
if (img_mode == PAN_AFBC_MODE_R8G8B8A8 &&
view_format == PIPE_FORMAT_X24S8_UINT)
return MALI_AFBC_COMPRESSION_MODE_X24S8;
else if (view_format == PIPE_FORMAT_S8_UINT)
return MALI_AFBC_COMPRESSION_MODE_S8;
return pan_afbc_compression_mode(img_format, plane_idx);
return pan_afbc_compression_mode(img_mode);
}
#endif

View file

@ -710,8 +710,8 @@ GENX(pan_emit_afbc_color_attachment)(const struct pan_fb_info *fb,
cfg.header = header;
cfg.body_offset = body_offset;
cfg.row_stride = hdr_row_stride;
cfg.compression_mode =
pan_afbc_compression_mode(image->props.format, pref.plane_idx);
cfg.compression_mode = pan_afbc_compression_mode(
image->planes[pref.plane_idx]->layout.afbc.mode);
#else
cfg.header = header;
cfg.body = header + body_offset;

View file

@ -113,6 +113,11 @@ pan_image_layout_init(
if (plane_idx >= util_format_get_num_planes(props->format))
return false;
/* Init plane layout data. */
if (mod_handler->init_plane_layout &&
!mod_handler->init_plane_layout(props, plane_idx, layout))
return false;
/* MSAA is implemented as a 3D texture with z corresponding to the
* sample #, horrifyingly enough */

View file

@ -110,6 +110,12 @@ struct pan_image_props {
struct pan_image_layout {
struct pan_image_slice_layout slices[MAX_MIP_LEVELS];
union {
struct {
int mode;
} afbc;
};
/* Image plane data size in bytes */
uint64_t data_size_B;
uint64_t array_stride_B;

View file

@ -51,6 +51,20 @@ pan_mod_afbc_get_wsi_row_pitch(const struct pan_image *image,
return tile_row_payload_size_B / pan_afbc_superblock_height(props->modifier);
}
static bool
pan_mod_afbc_init_plane_layout(const struct pan_image_props *props,
unsigned plane_idx,
struct pan_image_layout *plane_layout)
{
enum pan_afbc_mode mode =
pan_afbc_format(PAN_ARCH, props->format, plane_idx);
if (mode == PAN_AFBC_MODE_INVALID)
return false;
plane_layout->afbc.mode = mode;
return true;
}
static bool
pan_mod_afbc_init_slice_layout(
const struct pan_image_props *props, unsigned plane_idx,
@ -184,9 +198,17 @@ pan_mod_afbc_test_props(const struct pan_kmod_dev_props *dprops,
if (!pan_query_afbc(dprops))
return PAN_MOD_NOT_SUPPORTED;
unsigned plane_count = util_format_get_num_planes(iprops->format);
const struct util_format_description *fdesc =
util_format_description(iprops->format);
/* Check if the format is supported first. */
if (!pan_afbc_supports_format(PAN_ARCH, iprops->format))
return PAN_MOD_NOT_SUPPORTED;
enum pan_afbc_mode plane_modes[3];
for (unsigned p = 0; p < plane_count; p++) {
plane_modes[p] = pan_afbc_format(PAN_ARCH, iprops->format, p);
if (plane_modes[p] == PAN_AFBC_MODE_INVALID)
return PAN_MOD_NOT_SUPPORTED;
}
/* AFBC can't do multisampling. */
if (iprops->nr_samples > 1)
@ -197,10 +219,6 @@ pan_mod_afbc_test_props(const struct pan_kmod_dev_props *dprops,
iprops->dim != MALI_TEXTURE_DIMENSION_2D)
return PAN_MOD_NOT_SUPPORTED;
unsigned plane_count = util_format_get_num_planes(iprops->format);
const struct util_format_description *fdesc =
util_format_description(iprops->format);
/* ZS buffer descriptors can't pass split/wide/YTR modifiers. */
if (iusage && (iusage->bind & PAN_BIND_DEPTH_STENCIL) &&
(pan_afbc_superblock_width(iprops->modifier) != 16 ||
@ -215,7 +233,7 @@ pan_mod_afbc_test_props(const struct pan_kmod_dev_props *dprops,
/* Make sure all planes support split mode. */
if ((iprops->modifier & AFBC_FORMAT_MOD_SPLIT)) {
for (unsigned p = 0; p < plane_count; p++) {
if (!pan_afbc_can_split(PAN_ARCH, iprops->format, iprops->modifier, p))
if (!pan_afbc_can_split(PAN_ARCH, plane_modes[p], iprops->modifier))
return PAN_MOD_NOT_SUPPORTED;
}
}
@ -328,6 +346,8 @@ pan_mod_afrc_get_wsi_row_pitch(const struct pan_image *image,
tile_extent_px.height;
}
#define pan_mod_afrc_init_plane_layout NULL
static bool
pan_mod_afrc_init_slice_layout(
const struct pan_image_props *props, unsigned plane_idx,
@ -453,6 +473,8 @@ pan_mod_u_tiled_get_wsi_row_pitch(const struct pan_image *image,
pan_u_interleaved_tile_size_el(props->format).height;
}
#define pan_mod_u_tiled_init_plane_layout NULL
static bool
pan_mod_u_tiled_init_slice_layout(
const struct pan_image_props *props, unsigned plane_idx,
@ -589,6 +611,8 @@ pan_mod_linear_get_wsi_row_pitch(const struct pan_image *image,
return layout->slices[mip_level].tiled_or_linear.row_stride_B;
}
#define pan_mod_linear_init_plane_layout NULL
static bool
pan_mod_linear_init_slice_layout(
const struct pan_image_props *props, unsigned plane_idx,
@ -689,6 +713,7 @@ pan_mod_linear_init_slice_layout(
.match = pan_mod_##__name##_match, \
.test_props = pan_mod_##__name##_test_props, \
.get_wsi_row_pitch = pan_mod_##__name##_get_wsi_row_pitch, \
.init_plane_layout = pan_mod_##__name##_init_plane_layout, \
.init_slice_layout = pan_mod_##__name##_init_slice_layout, \
.emit_tex_payload_entry = pan_mod_##__name##_emit_tex_payload_entry, \
EMIT_ATT(__name), \

View file

@ -40,6 +40,13 @@ struct pan_mod_handler {
const struct pan_image_props *iprops,
const struct pan_image_usage *iusage);
/* Optional method used to initialize modifier-specific per-plane layout
* data. This is called before init_slice_layout().
*/
bool (*init_plane_layout)(const struct pan_image_props *props,
unsigned plane_idx,
struct pan_image_layout *plane_layout);
bool (*init_slice_layout)(
const struct pan_image_props *props, unsigned plane_idx,
struct pan_image_extent mip_extent_px,

View file

@ -684,7 +684,7 @@ emit_afbc_plane(const struct pan_image_view *iview, int plane_idx,
cfg.tiled_header = (props->modifier & AFBC_FORMAT_MOD_TILED);
cfg.prefetch = true;
cfg.compression_mode = pan_afbc_decompression_mode(
iview->format, props->format, pref.plane_idx);
iview->format, image->planes[pref.plane_idx]->layout.afbc.mode);
PLANE_SET_SIZE(cfg, plane_size);
cfg.pointer = header_addr;
cfg.header_row_stride = header_row_stride;