Mesa (main): panfrost: Unify row stride and AFBC row stride

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue May 3 14:38:09 UTC 2022


Module: Mesa
Branch: main
Commit: 579fd30209fa5ca7fa2af75f0eee90d2d2984afd
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=579fd30209fa5ca7fa2af75f0eee90d2d2984afd

Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date:   Wed Apr 27 14:09:01 2022 -0400

panfrost: Unify row stride and AFBC row stride

Row stride is defined in terms of header blocks for AFBC. Usually,
afbc.row_stride is used for AFBC images and row_stride for non-AFBC images;
however, the nonsense non-AFBC stride leaked into the UABI. So handle that in
the legacy conversion path and use a unified row stride (equal to
afbc.row_stride for AFBC images and row_stride otherwise).

Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16201>

---

 src/panfrost/lib/pan_cs.c      |  4 ++--
 src/panfrost/lib/pan_layout.c  | 34 +++++++++++++++++++++++++++-------
 src/panfrost/lib/pan_texture.c |  2 +-
 src/panfrost/lib/pan_texture.h | 13 ++++++++++---
 4 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/src/panfrost/lib/pan_cs.c b/src/panfrost/lib/pan_cs.c
index 4ca908dbcbb..880bb1878a8 100644
--- a/src/panfrost/lib/pan_cs.c
+++ b/src/panfrost/lib/pan_cs.c
@@ -206,7 +206,7 @@ pan_prepare_zs(const struct pan_fb_info *fb,
 #if PAN_ARCH >= 6
                 const struct pan_image_slice_layout *slice = &zs->image->layout.slices[level];
 
-                ext->zs_afbc_row_stride = slice->afbc.row_stride /
+                ext->zs_afbc_row_stride = slice->row_stride /
                                           AFBC_HEADER_BYTES_PER_TILE;
 #else
                 ext->zs_block_format = MALI_BLOCK_FORMAT_AFBC;
@@ -448,7 +448,7 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned idx,
                 const struct pan_image_slice_layout *slice = &rt->image->layout.slices[level];
 
 #if PAN_ARCH >= 6
-                cfg->afbc.row_stride = slice->afbc.row_stride /
+                cfg->afbc.row_stride = slice->row_stride /
                                        AFBC_HEADER_BYTES_PER_TILE;
                 cfg->afbc.afbc_wide_block_enable =
                         panfrost_afbc_is_wide(rt->image->layout.modifier);
diff --git a/src/panfrost/lib/pan_layout.c b/src/panfrost/lib/pan_layout.c
index c6642b15669..ee135f2a511 100644
--- a/src/panfrost/lib/pan_layout.c
+++ b/src/panfrost/lib/pan_layout.c
@@ -169,9 +169,17 @@ panfrost_get_legacy_stride(const struct pan_image_layout *layout,
                            unsigned level)
 {
         unsigned row_stride = layout->slices[level].row_stride;
-        unsigned bh = panfrost_block_size(layout->modifier, layout->format).height;
+        struct pan_block_size block_size =
+                panfrost_block_size(layout->modifier, layout->format);
 
-        return row_stride / bh;
+        if (drm_is_afbc(layout->modifier)) {
+                unsigned width = u_minify(layout->width, level);
+                width = ALIGN_POT(width, block_size.width);
+
+                return width * util_format_get_blocksize(layout->format);
+        } else {
+                return row_stride / block_size.height;
+        }
 }
 
 unsigned
@@ -179,7 +187,16 @@ panfrost_from_legacy_stride(unsigned legacy_stride,
                             enum pipe_format format,
                             uint64_t modifier)
 {
-        return legacy_stride * panfrost_block_size(modifier, format).height;
+        struct pan_block_size block_size =
+                panfrost_block_size(modifier, format);
+
+        if (drm_is_afbc(modifier)) {
+                unsigned width = legacy_stride / util_format_get_blocksize(format);
+
+                return (width / block_size.width) * AFBC_HEADER_BYTES_PER_TILE;
+        } else {
+                return legacy_stride * block_size.height;
+        }
 }
 
 /* Computes the offset into a texture at a particular level/face. Add to
@@ -247,7 +264,7 @@ pan_image_layout_init(struct pan_image_layout *layout,
 
                 unsigned row_stride = fmt_blocksize * effective_width * block_size.height;
 
-                if (explicit_layout) {
+                if (explicit_layout && !afbc) {
                         /* Make sure the explicit stride is valid */
                         if (explicit_layout->row_stride < row_stride)
                                 return false;
@@ -258,8 +275,6 @@ pan_image_layout_init(struct pan_image_layout *layout,
                         row_stride = ALIGN_POT(row_stride, 64);
                 }
 
-                slice->row_stride = row_stride;
-
                 unsigned slice_one_size = row_stride * (effective_height / block_size.height);
 
                 /* Compute AFBC sizes if necessary */
@@ -268,10 +283,13 @@ pan_image_layout_init(struct pan_image_layout *layout,
                                 panfrost_afbc_header_size(width, height);
 
                         /* Stride between two rows of AFBC headers */
-                        slice->afbc.row_stride =
+                        slice->row_stride =
                                 (effective_width / block_size.width) *
                                 AFBC_HEADER_BYTES_PER_TILE;
 
+                        if (explicit_layout && explicit_layout->row_stride < slice->row_stride)
+                                return false;
+
                         /* AFBC body size */
                         slice->afbc.body_size = slice_one_size;
 
@@ -289,6 +307,8 @@ pan_image_layout_init(struct pan_image_layout *layout,
                                 slice_one_size += slice->afbc.header_size;
                                 slice->afbc.surface_stride = slice_one_size;
                         }
+                } else {
+                        slice->row_stride = row_stride;
                 }
 
                 unsigned slice_full_size =
diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c
index 9001389d5db..3709ce3b311 100644
--- a/src/panfrost/lib/pan_texture.c
+++ b/src/panfrost/lib/pan_texture.c
@@ -242,7 +242,7 @@ panfrost_get_surface_strides(const struct pan_image_layout *layout,
         if (drm_is_afbc(layout->modifier)) {
                 /* Pre v7 don't have a row stride field. This field is
                  * repurposed as a Y offset which we don't use */
-                *row_stride = PAN_ARCH < 7 ? 0 : slice->afbc.row_stride;
+                *row_stride = PAN_ARCH < 7 ? 0 : slice->row_stride;
                 *surf_stride = slice->afbc.surface_stride;
         } else {
                 *row_stride = slice->row_stride;
diff --git a/src/panfrost/lib/pan_texture.h b/src/panfrost/lib/pan_texture.h
index 9c89923a689..c44777f7534 100644
--- a/src/panfrost/lib/pan_texture.h
+++ b/src/panfrost/lib/pan_texture.h
@@ -49,7 +49,17 @@ extern uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT];
 
 struct pan_image_slice_layout {
         unsigned offset;
+
+        /* For AFBC images, the number of bytes between two rows of AFBC
+         * headers.
+         *
+         * For non-AFBC images, the number of bytes between two rows of texels.
+         * For linear images, this will equal the logical stride. For
+         * images that are compressed or interleaved, this will be greater than
+         * the logical stride.
+         */
         unsigned row_stride;
+
         unsigned surface_stride;
 
         struct {
@@ -59,9 +69,6 @@ struct pan_image_slice_layout {
                 /* Size of the AFBC body */
                 unsigned body_size;
 
-                /* Stride between two rows of AFBC headers */
-                unsigned row_stride;
-
                 /* Stride between AFBC headers of two consecutive surfaces.
                  * For 3D textures, this must be set to header size since
                  * AFBC headers are allocated together, for 2D arrays this



More information about the mesa-commit mailing list