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