panfrost: Draw a clear line between AFBC and MTK_TILED conversion shaders

Those two types are completely different, and they don't use the same
key attributes. Let's provide two different helpers, and place the key
bits that are AFBC-specific into an struct inside a union. We also add
the modifier to the key to prevent AFBC/MTK_TILED collisions.

Not only this make things clearer, but we also no longer compile
MTK detiling shaders when AFBC shaders are requested (or the other way
around).

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35317>
This commit is contained in:
Boris Brezillon
2025-06-03 11:25:44 +02:00
committed by Marge Bot
parent e6d53fc1d8
commit a87805fdd8
3 changed files with 94 additions and 49 deletions
+16 -15
View File
@@ -3553,9 +3553,9 @@ panfrost_launch_grid(struct pipe_context *pipe,
#define AFBC_BLOCK_ALIGN 16
static void
panfrost_launch_convert_shader(struct panfrost_batch *batch, void *cso,
struct pipe_constant_buffer *cbuf,
unsigned nr_blocks)
panfrost_launch_afbc_conv_shader(struct panfrost_batch *batch, void *cso,
struct pipe_constant_buffer *cbuf,
unsigned nr_blocks)
{
struct pipe_context *pctx = &batch->ctx->base;
void *saved_cso = NULL;
@@ -3583,14 +3583,15 @@ panfrost_launch_convert_shader(struct panfrost_batch *batch, void *cso,
pctx->set_constant_buffer(pctx, PIPE_SHADER_COMPUTE, 0, true, &saved_const);
}
#define LAUNCH_CONVERT_SHADER(name, batch, rsrc, consts, nr_blocks) \
struct pan_mod_convert_shader_data *shaders = \
panfrost_get_mod_convert_shaders(batch->ctx, rsrc, AFBC_BLOCK_ALIGN); \
#define LAUNCH_AFBC_CONV_SHADER(name, batch, rsrc, consts, nr_blocks) \
struct pan_mod_convert_shader_data *shaders = \
panfrost_get_afbc_pack_shaders(batch->ctx, rsrc, AFBC_BLOCK_ALIGN); \
struct pipe_constant_buffer constant_buffer = { \
.buffer_size = sizeof(consts), \
.user_buffer = &consts}; \
panfrost_launch_convert_shader(batch, shaders->name##_cso, &constant_buffer, \
nr_blocks);
.user_buffer = &consts, \
}; \
panfrost_launch_afbc_conv_shader(batch, shaders->afbc.name##_cso, \
&constant_buffer, nr_blocks);
static void
panfrost_afbc_size(struct panfrost_batch *batch, struct panfrost_resource *src,
@@ -3608,7 +3609,7 @@ panfrost_afbc_size(struct panfrost_batch *batch, struct panfrost_resource *src,
panfrost_batch_read_rsrc(batch, src, PIPE_SHADER_COMPUTE);
panfrost_batch_write_bo(batch, metadata, PIPE_SHADER_COMPUTE);
LAUNCH_CONVERT_SHADER(afbc_size, batch, src, consts, slice->afbc.nr_sblocks);
LAUNCH_AFBC_CONV_SHADER(size, batch, src, consts, slice->afbc.nr_sblocks);
}
static void
@@ -3634,8 +3635,8 @@ panfrost_afbc_pack(struct panfrost_batch *batch, struct panfrost_resource *src,
panfrost_batch_write_bo(batch, dst, PIPE_SHADER_COMPUTE);
panfrost_batch_add_bo(batch, metadata, PIPE_SHADER_COMPUTE);
LAUNCH_CONVERT_SHADER(afbc_pack, batch, src, consts,
dst_slice->afbc.nr_sblocks);
LAUNCH_AFBC_CONV_SHADER(pack, batch, src, consts,
dst_slice->afbc.nr_sblocks);
}
static void
@@ -3712,8 +3713,8 @@ panfrost_mtk_detile_compute(struct panfrost_context *ctx, struct pipe_blit_info
pipe->set_shader_images(pipe, PIPE_SHADER_COMPUTE, 0, 4, 0, image);
/* launch the compute shader */
struct pan_mod_convert_shader_data *shaders =
panfrost_get_mod_convert_shaders(ctx, pan_resource(y_dst ? y_dst : uv_dst), AFBC_BLOCK_ALIGN);
struct pan_mod_convert_shader_data *shader =
panfrost_get_mtk_detile_shader(ctx);
struct pipe_constant_buffer cbuf = {
.buffer_size = sizeof(consts),
.user_buffer = &consts};
@@ -3734,7 +3735,7 @@ panfrost_mtk_detile_compute(struct panfrost_context *ctx, struct pipe_blit_info
struct panfrost_constant_buffer *pbuf =
&batch->ctx->constant_buffer[PIPE_SHADER_COMPUTE];
void *saved_cso = batch->ctx->uncompiled[PIPE_SHADER_COMPUTE];
void *cso = shaders->mtk_detile_cso;
void *cso = shader->mtk_tiled.detile_cso;
util_copy_constant_buffer(&pbuf->cb[0], &saved_const, true);
pipe->bind_compute_state(pipe, cso);
+57 -26
View File
@@ -214,9 +214,11 @@ copy_superblock(nir_builder *b, nir_def *dst, nir_def *dst_idx, nir_def *hdr_sz,
panfrost_afbc_get_info_field(size, b, field)
static nir_shader *
panfrost_create_afbc_size_shader(struct panfrost_screen *screen, unsigned bpp,
unsigned align)
panfrost_create_afbc_size_shader(struct panfrost_screen *screen,
const struct pan_mod_convert_shader_key *key)
{
unsigned bpp = key->afbc.bpp;
unsigned align = key->afbc.align;
struct panfrost_device *dev = pan_device(&screen->base);
nir_builder b = nir_builder_init_simple_shader(
@@ -250,9 +252,11 @@ panfrost_create_afbc_size_shader(struct panfrost_screen *screen, unsigned bpp,
panfrost_afbc_get_info_field(pack, b, field)
static nir_shader *
panfrost_create_afbc_pack_shader(struct panfrost_screen *screen, unsigned align,
bool tiled)
panfrost_create_afbc_pack_shader(struct panfrost_screen *screen,
const struct pan_mod_convert_shader_key *key)
{
unsigned align = key->afbc.align;
bool tiled = key->mod & AFBC_FORMAT_MOD_TILED;
struct panfrost_device *dev = pan_device(&screen->base);
nir_builder b = nir_builder_init_simple_shader(
MESA_SHADER_COMPUTE, pan_shader_get_compiler_options(dev->arch),
@@ -333,8 +337,8 @@ pan_mtk_tiled_from_linear(nir_builder *b, nir_def *linear, nir_def *tiles_per_st
}
static nir_shader *
panfrost_create_mtk_detile_shader(struct panfrost_screen *screen, unsigned align,
bool is_tiled)
panfrost_create_mtk_tiled_detile_shader(
struct panfrost_screen *screen, const struct pan_mod_convert_shader_key *key)
{
const struct panfrost_device *device = &screen->dev;
bool tint_yuv = (device->debug & PAN_DBG_YUV) != 0;
@@ -443,18 +447,12 @@ panfrost_create_mtk_detile_shader(struct panfrost_screen *screen, unsigned align
return b.shader;
}
struct pan_mod_convert_shader_data *
panfrost_get_mod_convert_shaders(struct panfrost_context *ctx,
struct panfrost_resource *rsrc, unsigned align)
static struct pan_mod_convert_shader_data *
get_mod_convert_shaders(struct panfrost_context *ctx,
const struct pan_mod_convert_shader_key *key)
{
struct pipe_context *pctx = &ctx->base;
struct panfrost_screen *screen = pan_screen(ctx->base.screen);
bool tiled = rsrc->modifier & AFBC_FORMAT_MOD_TILED;
struct pan_mod_convert_shader_key key = {
.bpp = util_format_get_blocksizebits(rsrc->base.format),
.align = align,
.tiled = tiled,
};
pthread_mutex_lock(&ctx->mod_convert_shaders.lock);
struct hash_entry *he =
@@ -466,22 +464,26 @@ panfrost_get_mod_convert_shaders(struct panfrost_context *ctx,
return shader;
shader = rzalloc(ctx->mod_convert_shaders.shaders, struct pan_mod_convert_shader_data);
shader->key = key;
shader->key = *key;
#define COMPILE_SHADER(name, ...) \
#define COMPILE_SHADER(type, name, key) \
{ \
nir_shader *nir = \
panfrost_create_##name##_shader(screen, __VA_ARGS__); \
nir_shader *nir = panfrost_create_##type##_##name##_shader(screen, key); \
nir->info.num_ubos = 1; \
/* "default" UBO is maybe not correct here, but in panfrost we're */ \
/* using this as an indicator for whether UBO0 is a user UBO */ \
nir->info.first_ubo_is_default_ubo = true; \
shader->name##_cso = pipe_shader_from_nir(pctx, nir); \
shader->type.name##_cso = pipe_shader_from_nir(pctx, nir); \
}
COMPILE_SHADER(afbc_size, key.bpp, key.align);
COMPILE_SHADER(afbc_pack, key.align, key.tiled);
COMPILE_SHADER(mtk_detile, key.bpp, key.align);
if (drm_is_afbc(key->mod)) {
COMPILE_SHADER(afbc, size, key);
COMPILE_SHADER(afbc, pack, key);
} else if (drm_is_mtk_tiled(key->mod)) {
COMPILE_SHADER(mtk_tiled, detile, key);
} else {
unreachable("Unsupported conversion");
}
#undef COMPILE_SHADER
@@ -492,6 +494,31 @@ panfrost_get_mod_convert_shaders(struct panfrost_context *ctx,
return shader;
}
struct pan_mod_convert_shader_data *
panfrost_get_afbc_pack_shaders(struct panfrost_context *ctx,
struct panfrost_resource *rsrc, unsigned align)
{
struct pan_mod_convert_shader_key key = {
.mod = DRM_FORMAT_MOD_ARM_AFBC(rsrc->modifier & AFBC_FORMAT_MOD_TILED),
.afbc = {
.bpp = util_format_get_blocksizebits(rsrc->base.format),
.align = align,
},
};
return get_mod_convert_shaders(ctx, &key);
}
struct pan_mod_convert_shader_data *
panfrost_get_mtk_detile_shader(struct panfrost_context *ctx)
{
struct pan_mod_convert_shader_key key = {
.mod = DRM_FORMAT_MOD_MTK_16L_32S_TILE,
};
return get_mod_convert_shaders(ctx, &key);
}
DERIVE_HASH_TABLE(pan_mod_convert_shader_key);
void
@@ -507,9 +534,13 @@ panfrost_afbc_context_destroy(struct panfrost_context *ctx)
hash_table_foreach(ctx->mod_convert_shaders.shaders, he) {
assert(he->data);
struct pan_mod_convert_shader_data *shader = he->data;
ctx->base.delete_compute_state(&ctx->base, shader->afbc_size_cso);
ctx->base.delete_compute_state(&ctx->base, shader->afbc_pack_cso);
ctx->base.delete_compute_state(&ctx->base, shader->mtk_detile_cso);
if (drm_is_afbc(shader->key.mod)) {
ctx->base.delete_compute_state(&ctx->base, shader->afbc.size_cso);
ctx->base.delete_compute_state(&ctx->base, shader->afbc.pack_cso);
} else if (drm_is_mtk_tiled(shader->key.mod)) {
ctx->base.delete_compute_state(&ctx->base, shader->mtk_tiled.detile_cso);
}
}
_mesa_hash_table_destroy(ctx->mod_convert_shaders.shaders, NULL);
@@ -35,16 +35,26 @@ struct panfrost_resource;
struct panfrost_screen;
struct pan_mod_convert_shader_key {
unsigned bpp;
unsigned align;
bool tiled;
uint64_t mod;
union {
struct {
unsigned bpp;
unsigned align;
} afbc;
};
};
struct pan_mod_convert_shader_data {
struct pan_mod_convert_shader_key key;
void *afbc_size_cso;
void *afbc_pack_cso;
void *mtk_detile_cso;
union {
struct {
void *size_cso;
void *pack_cso;
} afbc;
struct {
void *detile_cso;
} mtk_tiled;
};
};
struct pan_mod_convert_shaders {
@@ -83,8 +93,11 @@ void panfrost_afbc_context_init(struct panfrost_context *ctx);
void panfrost_afbc_context_destroy(struct panfrost_context *ctx);
struct pan_mod_convert_shader_data *
panfrost_get_mod_convert_shaders(struct panfrost_context *ctx,
struct panfrost_resource *rsrc, unsigned align);
panfrost_get_afbc_pack_shaders(struct panfrost_context *ctx,
struct panfrost_resource *rsrc, unsigned align);
struct pan_mod_convert_shader_data *
panfrost_get_mtk_detile_shader(struct panfrost_context *ctx);
#define drm_is_mtk_tiled(mod) \
((mod >> 52) == (0 | (DRM_FORMAT_MOD_VENDOR_MTK << 4)))