From 4ffe73547d074496fcefe943da2439e43a115922 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 16 Dec 2020 14:48:57 +0100 Subject: [PATCH] panfrost: Fix calculation of body/header pointers for 3D AFBC When using 3D AFBC, all headers are placed at the beginning instead of being interleaved with each surface body, which forces us to adjust the calculation in that case. Signed-off-by: Boris Brezillon Reviewed-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/panfrost/pan_mfbd.c | 19 ++++++++++------- src/gallium/drivers/panfrost/pan_resource.c | 23 +++++++++++++++++++++ src/gallium/drivers/panfrost/pan_resource.h | 5 +++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c index 95ecd1d2632..0c2847a2381 100644 --- a/src/gallium/drivers/panfrost/pan_mfbd.c +++ b/src/gallium/drivers/panfrost/pan_mfbd.c @@ -147,7 +147,6 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf, unsigned nr_samples = surf->texture->nr_samples; unsigned layer_stride = (nr_samples > 1) ? rsrc->layout.slices[level].surface_stride : 0; - mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); if (layer_stride) rt->writeback_msaa = MALI_MSAA_LAYERED; @@ -159,6 +158,8 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf, panfrost_mfbd_rt_init_format(dev, surf, rt); if (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR) { + mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); + if (version >= 7) rt->bifrost_v7.writeback_block_format = MALI_BLOCK_FORMAT_V7_LINEAR; else @@ -168,6 +169,8 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf, rt->rgb.row_stride = row_stride; rt->rgb.surface_stride = layer_stride; } else if (rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { + mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); + if (version >= 7) rt->bifrost_v7.writeback_block_format = MALI_BLOCK_FORMAT_V7_TILED_U_INTERLEAVED; else @@ -192,8 +195,9 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf, rt->afbc.body_size = slice->afbc.body_size; } - rt->afbc.header = base; - rt->afbc.body = base + slice->afbc.header_size; + panfrost_get_afbc_pointers(rsrc, level, first_layer, + &rt->afbc.header, + &rt->afbc.body); if (rsrc->layout.modifier & AFBC_FORMAT_MOD_YTR) rt->afbc.yuv_transform_enable = true; @@ -291,8 +295,6 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, unsigned first_layer = zs_surf->u.tex.first_layer; assert(zs_surf->u.tex.last_layer == first_layer); - mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); - if (version < 7) ext->zs_msaa = nr_samples > 1 ? MALI_MSAA_LAYERED : MALI_MSAA_SINGLE; else @@ -301,8 +303,9 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, if (drm_is_afbc(rsrc->layout.modifier)) { struct panfrost_slice *slice = &rsrc->layout.slices[level]; - ext->zs_afbc_header = base; - ext->zs_afbc_body = base + slice->afbc.header_size; + panfrost_get_afbc_pointers(rsrc, level, first_layer, + &ext->zs_afbc_header, + &ext->zs_afbc_body); if (version >= 7) { ext->zs_block_format_v7 = MALI_BLOCK_FORMAT_V7_AFBC; @@ -317,6 +320,8 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, } else { assert(rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED || rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR); + mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); + /* TODO: Z32F(S8) support, which is always linear */ ext->zs_writeback_base = base; diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index d55a050a065..a4fb966649b 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -1278,6 +1278,29 @@ panfrost_get_texture_address(struct panfrost_resource *rsrc, array_idx, surface_idx); } +void +panfrost_get_afbc_pointers(struct panfrost_resource *rsrc, + unsigned level, unsigned layer, + mali_ptr *header, mali_ptr *body) +{ + assert(drm_is_afbc(rsrc->layout.modifier)); + + struct panfrost_slice *slice = &rsrc->layout.slices[level]; + + if (rsrc->base.target == PIPE_TEXTURE_3D) { + *header = rsrc->bo->ptr.gpu + slice->offset + + (layer * slice->afbc.surface_stride); + *body = rsrc->bo->ptr.gpu + slice->offset + + slice->afbc.header_size + + (slice->surface_stride * layer); + } else { + *header = rsrc->bo->ptr.gpu + + panfrost_texture_offset(&rsrc->layout, + level, layer, 0); + *body = *header + slice->afbc.header_size; + } +} + static void panfrost_resource_set_stencil(struct pipe_resource *prsrc, struct pipe_resource *stencil) diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h index 6a8104d7166..fa2d89039c7 100644 --- a/src/gallium/drivers/panfrost/pan_resource.h +++ b/src/gallium/drivers/panfrost/pan_resource.h @@ -99,6 +99,11 @@ panfrost_get_texture_address(struct panfrost_resource *rsrc, unsigned level, unsigned layer, unsigned sample); +void +panfrost_get_afbc_pointers(struct panfrost_resource *rsrc, + unsigned level, unsigned layer, + mali_ptr *header, mali_ptr *body); + void panfrost_resource_screen_init(struct pipe_screen *screen); void panfrost_resource_context_init(struct pipe_context *pctx);