From acb8dcfebdde56a748ec50a3fbecf27912974be9 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 21 Jul 2020 12:34:33 -0400 Subject: [PATCH] panfrost: Choose AFBC when available There are lots of reasons we might fallback on u-interleaved tiling, but when we can use AFBC, it's a big win. Signed-off-by: Alyssa Rosenzweig Tested-by: Icecream95 Part-of: --- src/gallium/drivers/panfrost/pan_resource.c | 63 ++++++++++++++++++++- src/panfrost/include/panfrost-quirks.h | 11 +++- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index 8226b4b3c3e..7606bfb17b5 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -382,7 +382,9 @@ panfrost_setup_slices(struct panfrost_resource *pres, size_t *bo_size) * that the contents frequently change, tiling will be a loss. * * Due to incomplete information on some platforms, we may need to force tiling - * in some cases */ + * in some cases. + * + * On platforms where it is supported, AFBC is even better. */ static bool panfrost_can_linear(struct panfrost_device *dev, const struct panfrost_resource *pres) @@ -392,6 +394,53 @@ panfrost_can_linear(struct panfrost_device *dev, const struct panfrost_resource (dev->quirks & (MIDGARD_SFBD | IS_BIFROST))); } +static bool +panfrost_should_afbc(struct panfrost_device *dev, const struct panfrost_resource *pres) +{ + /* AFBC resources may be rendered to, textured from, or shared across + * processes, but may not be used as e.g buffers */ + const unsigned valid_binding = + PIPE_BIND_DEPTH_STENCIL | + PIPE_BIND_RENDER_TARGET | + PIPE_BIND_BLENDABLE | + PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED; + + if (pres->base.bind & ~valid_binding) + return false; + + /* AFBC introduced with Mali T760 */ + if (dev->quirks & MIDGARD_NO_AFBC) + return false; + + /* AFBC<-->staging is expensive */ + if (pres->base.usage == PIPE_USAGE_STREAM) + return false; + + /* Only a small selection of formats are AFBC'able */ + if (!panfrost_format_supports_afbc(pres->internal_format)) + return false; + + /* AFBC does not support layered (GLES3 style) multisampling. Use + * EXT_multisampled_render_to_texture instead */ + if (pres->base.nr_samples > 1) + return false; + + /* TODO: Is AFBC of 3D textures possible? */ + if ((pres->base.target != PIPE_TEXTURE_2D) && (pres->base.target != PIPE_TEXTURE_RECT)) + return false; + + /* For one tile, AFBC is a loss compared to u-interleaved */ + if (pres->base.width0 <= 16 && pres->base.height0 <= 16) + return false; + + /* Otherwise, we'd prefer AFBC as it is dramatically more efficient + * than linear or usually even u-interleaved */ + return true; +} + static bool panfrost_should_tile(struct panfrost_device *dev, const struct panfrost_resource *pres) { @@ -400,7 +449,9 @@ panfrost_should_tile(struct panfrost_device *dev, const struct panfrost_resource PIPE_BIND_RENDER_TARGET | PIPE_BIND_BLENDABLE | PIPE_BIND_SAMPLER_VIEW | - PIPE_BIND_DISPLAY_TARGET; + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED; unsigned bpp = util_format_get_blocksizebits(pres->internal_format); @@ -425,7 +476,13 @@ static uint64_t panfrost_best_modifier(struct panfrost_device *dev, const struct panfrost_resource *pres) { - if (panfrost_should_tile(dev, pres)) + if (panfrost_should_afbc(dev, pres)) { + uint64_t afbc = + AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | + AFBC_FORMAT_MOD_SPARSE; + + return DRM_FORMAT_MOD_ARM_AFBC(afbc); + } else if (panfrost_should_tile(dev, pres)) return DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED; else return DRM_FORMAT_MOD_LINEAR; diff --git a/src/panfrost/include/panfrost-quirks.h b/src/panfrost/include/panfrost-quirks.h index c4b03a165aa..4b88e83aabe 100644 --- a/src/panfrost/include/panfrost-quirks.h +++ b/src/panfrost/include/panfrost-quirks.h @@ -68,13 +68,17 @@ /* Has some missing formats for typed loads */ #define MIDGARD_MISSING_LOADS (1 << 9) +/* Lack support for AFBC */ +#define MIDGARD_NO_AFBC (1 << 10) + /* Quirk collections common to particular uarchs */ #define MIDGARD_QUIRKS (MIDGARD_BROKEN_FP16 | HAS_SWIZZLES \ | MIDGARD_NO_TYPED_BLEND_STORES \ | MIDGARD_MISSING_LOADS) -#define BIFROST_QUIRKS (IS_BIFROST | NO_BLEND_PACKS) +/* TODO: AFBC on Bifrost */ +#define BIFROST_QUIRKS (IS_BIFROST | NO_BLEND_PACKS | MIDGARD_NO_AFBC) static inline unsigned panfrost_get_quirks(unsigned gpu_id) @@ -84,10 +88,11 @@ panfrost_get_quirks(unsigned gpu_id) case 0x620: return MIDGARD_QUIRKS | MIDGARD_SFBD | MIDGARD_NO_TYPED_BLEND_LOADS - | NO_BLEND_PACKS; + | NO_BLEND_PACKS | MIDGARD_NO_AFBC; case 0x720: - return MIDGARD_QUIRKS | MIDGARD_SFBD | MIDGARD_NO_HIER_TILING; + return MIDGARD_QUIRKS | MIDGARD_SFBD | MIDGARD_NO_HIER_TILING + | MIDGARD_NO_AFBC; case 0x820: case 0x830: -- 2.30.2