panfrost: Fix calculation of body/header pointers for 3D AFBC
authorBoris Brezillon <boris.brezillon@collabora.com>
Wed, 16 Dec 2020 13:48:57 +0000 (14:48 +0100)
committerBoris Brezillon <boris.brezillon@collabora.com>
Mon, 4 Jan 2021 16:05:42 +0000 (17:05 +0100)
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 <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8125>

src/gallium/drivers/panfrost/pan_mfbd.c
src/gallium/drivers/panfrost/pan_resource.c
src/gallium/drivers/panfrost/pan_resource.h

index 95ecd1d..0c2847a 100644 (file)
@@ -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;
index d55a050..a4fb966 100644 (file)
@@ -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)
index 6a8104d..fa2d890 100644 (file)
@@ -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);