#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;
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);
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
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
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;
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 */
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;
slice_one_size += slice->afbc.header_size;
slice->afbc.surface_stride = slice_one_size;
}
+ } else {
+ slice->row_stride = row_stride;
}
unsigned slice_full_size =
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 {
/* 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