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:
committed by
Marge Bot
parent
e6d53fc1d8
commit
a87805fdd8
@@ -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);
|
||||
|
||||
@@ -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)))
|
||||
|
||||
Reference in New Issue
Block a user