From a87805fdd805b3a6e45969b4372bfd72f4f2080b Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 3 Jun 2025 11:25:44 +0200 Subject: [PATCH] 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 Reviewed-by: Mary Guillemard Reviewed-by: Erik Faye-Lund Part-of: --- src/gallium/drivers/panfrost/pan_cmdstream.c | 31 +++---- .../drivers/panfrost/pan_mod_conv_cso.c | 83 +++++++++++++------ .../drivers/panfrost/pan_mod_conv_cso.h | 29 +++++-- 3 files changed, 94 insertions(+), 49 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 894b4a5beb6..7a2324369c4 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -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); diff --git a/src/gallium/drivers/panfrost/pan_mod_conv_cso.c b/src/gallium/drivers/panfrost/pan_mod_conv_cso.c index 121da18a3a9..417c9cc0537 100644 --- a/src/gallium/drivers/panfrost/pan_mod_conv_cso.c +++ b/src/gallium/drivers/panfrost/pan_mod_conv_cso.c @@ -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); diff --git a/src/gallium/drivers/panfrost/pan_mod_conv_cso.h b/src/gallium/drivers/panfrost/pan_mod_conv_cso.h index 2032bb1f2bf..6e19c27ff4a 100644 --- a/src/gallium/drivers/panfrost/pan_mod_conv_cso.h +++ b/src/gallium/drivers/panfrost/pan_mod_conv_cso.h @@ -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)))