From 7e37a31741218f325b2f02dc308a23fe5d40858c Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 16 Dec 2020 10:06:44 +0100 Subject: [PATCH] panfrost: Fix AFBC header_size and slice size calculation 3D AFBC textures have their AFBC headers grouped together at the beginning of the buffer which means the header_size should be multiplied by the depth. 2D arrays have their AFBC headers placed at the beginning of each slice, meaning that the slice size should take them into account. Signed-off-by: Boris Brezillon Reviewed-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/panfrost/pan_resource.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index e1a8c01f1da..96c552f2150 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -350,6 +350,7 @@ panfrost_setup_layout(struct panfrost_device *dev, bool tiled = pres->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED; bool linear = pres->layout.modifier == DRM_FORMAT_MOD_LINEAR; bool should_align = renderable || tiled || afbc; + bool is_3d = res->target == PIPE_TEXTURE_3D; unsigned offset = 0; unsigned tile_h = 1, tile_w = 1, tile_shift = 0; @@ -396,19 +397,29 @@ panfrost_setup_layout(struct panfrost_device *dev, slice->row_stride = stride * (tile_h >> tile_shift); unsigned slice_one_size = slice->line_stride * effective_height; - unsigned slice_full_size = - slice_one_size * effective_depth * nr_samples; - - slice->surface_stride = slice_one_size; /* Compute AFBC sizes if necessary */ if (afbc) { slice->afbc.header_size = panfrost_afbc_header_size(width, height); - offset += slice->afbc.header_size; + /* 3D AFBC resources have all headers placed at the + * beginning instead of having them split per depth + * level + */ + if (is_3d) + slice->afbc.header_size *= effective_depth; + else + slice_one_size += slice->afbc.header_size; } + unsigned slice_full_size = + slice_one_size * effective_depth * nr_samples; + + slice->surface_stride = slice_one_size; + + /* Compute AFBC sizes if necessary */ + offset += slice_full_size; /* Add a checksum region if necessary */