From 4af57952b126bf399c1063e83dbe305b3d4db013 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 21 Sep 2023 10:16:43 +0200 Subject: [PATCH] panfrost: Add support for AFBC(split) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Boris Brezillon Reviewed-by: Lars-Ivar Hesselberg Simonsen Reviewed-by: Louis-Francis Ratté-Boulianne Acked-by: Erik Faye-Lund Part-of: --- src/gallium/drivers/panfrost/pan_resource.c | 1 + src/gallium/drivers/panfrost/pan_screen.c | 18 ++++++++++++------ src/panfrost/lib/pan_afbc.c | 20 ++++++++++++++++++++ src/panfrost/lib/pan_desc.c | 4 ++++ src/panfrost/lib/pan_texture.c | 4 ++++ src/panfrost/lib/pan_texture.h | 3 +++ 6 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index 6949c3fa320..c96ee858761 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -391,6 +391,7 @@ panfrost_should_pack_afbc(struct panfrost_device *dev, return panfrost_afbc_can_pack(prsrc->base.format) && panfrost_is_2d(prsrc) && drm_is_afbc(prsrc->image.layout.modifier) && (prsrc->image.layout.modifier & AFBC_FORMAT_MOD_SPARSE) && + !(prsrc->image.layout.modifier & AFBC_FORMAT_MOD_SPLIT) && (prsrc->base.bind & ~valid_binding) == 0 && !prsrc->modifier_constant && prsrc->base.array_size == 1 && prsrc->base.width0 >= 32 && prsrc->base.height0 >= 32 ; diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index 741d1949f72..da4cf21a911 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -699,14 +699,20 @@ panfrost_walk_dmabuf_modifiers(struct pipe_screen *screen, unsigned count = 0; for (unsigned i = 0; i < PAN_MODIFIER_COUNT; ++i) { - if (drm_is_afbc(pan_best_modifiers[i]) && !afbc) - continue; + if (drm_is_afbc(pan_best_modifiers[i])) { + if (!afbc) + continue; - if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_YTR) && !ytr) - continue; + if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_SPLIT) && + !panfrost_afbc_can_split(dev->arch, format, pan_best_modifiers[i])) + continue; - if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_TILED) && !tiled_afbc) - continue; + if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_YTR) && !ytr) + continue; + + if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_TILED) && !tiled_afbc) + continue; + } if (drm_is_afrc(pan_best_modifiers[i]) && !afrc) continue; diff --git a/src/panfrost/lib/pan_afbc.c b/src/panfrost/lib/pan_afbc.c index 59302f58750..e676ac35540 100644 --- a/src/panfrost/lib/pan_afbc.c +++ b/src/panfrost/lib/pan_afbc.c @@ -178,6 +178,26 @@ panfrost_afbc_can_ytr(enum pipe_format format) return desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB; } +bool +panfrost_afbc_can_split(unsigned arch, enum pipe_format format, + uint64_t modifier) +{ + unsigned block_width = panfrost_afbc_superblock_width(modifier); + + if (arch < 6) + return false; + + if (block_width == 16) { + return true; + } else if (block_width == 32) { + enum pan_afbc_mode mode = panfrost_afbc_format(arch, format); + return (mode == PAN_AFBC_MODE_R8G8B8A8 || + mode == PAN_AFBC_MODE_R10G10B10A2); + } + + return false; +} + /* Only support packing for RGB formats for now. */ bool diff --git a/src/panfrost/lib/pan_desc.c b/src/panfrost/lib/pan_desc.c index 8f9649ef9b3..baf1f0770a6 100644 --- a/src/panfrost/lib/pan_desc.c +++ b/src/panfrost/lib/pan_desc.c @@ -543,6 +543,8 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned layer_idx, cfg->afbc.yuv_transform = true; cfg->afbc.wide_block = panfrost_afbc_is_wide(image->layout.modifier); + cfg->afbc.split_block = + (image->layout.modifier & AFBC_FORMAT_MOD_SPLIT); cfg->afbc.header = surf.afbc.header; cfg->afbc.body_offset = surf.afbc.body - surf.afbc.header; assert(surf.afbc.body >= surf.afbc.header); @@ -557,6 +559,8 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned layer_idx, pan_afbc_stride_blocks(image->layout.modifier, slice->row_stride); cfg->afbc.afbc_wide_block_enable = panfrost_afbc_is_wide(image->layout.modifier); + cfg->afbc.afbc_split_block_enable = + (image->layout.modifier & AFBC_FORMAT_MOD_SPLIT); #else cfg->afbc.chunk_size = 9; cfg->afbc.sparse = true; diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c index 86d1090f2d1..edb9470d56a 100644 --- a/src/panfrost/lib/pan_texture.c +++ b/src/panfrost/lib/pan_texture.c @@ -94,6 +94,9 @@ panfrost_compression_tag(const struct util_format_description *desc, if (panfrost_afbc_is_wide(modifier)) flags |= MALI_AFBC_SURFACE_FLAG_WIDE_BLOCK; + + if (modifier & AFBC_FORMAT_MOD_SPLIT) + flags |= MALI_AFBC_SURFACE_FLAG_SPLIT_BLOCK; #endif #if PAN_ARCH >= 7 @@ -418,6 +421,7 @@ panfrost_emit_plane(const struct pan_image_view *iview, int index, cfg.plane_type = MALI_PLANE_TYPE_AFBC; cfg.afbc.superblock_size = translate_superblock_size(layout->modifier); cfg.afbc.ytr = (layout->modifier & AFBC_FORMAT_MOD_YTR); + cfg.afbc.split_block = (layout->modifier & AFBC_FORMAT_MOD_SPLIT); cfg.afbc.tiled_header = (layout->modifier & AFBC_FORMAT_MOD_TILED); cfg.afbc.prefetch = true; cfg.afbc.compression_mode = GENX(pan_afbc_compression_mode)(format); diff --git a/src/panfrost/lib/pan_texture.h b/src/panfrost/lib/pan_texture.h index f2297d00605..5842bf2e175 100644 --- a/src/panfrost/lib/pan_texture.h +++ b/src/panfrost/lib/pan_texture.h @@ -242,6 +242,9 @@ panfrost_format_supports_afbc(unsigned arch, enum pipe_format format) bool panfrost_afbc_can_ytr(enum pipe_format format); +bool panfrost_afbc_can_split(unsigned arch, enum pipe_format format, + uint64_t modifier); + bool panfrost_afbc_can_pack(enum pipe_format format); /*