* generate a linear staging buffer and use the GPU to blit AFBC<--->linear.
*/
-#define AFBC_TILE_WIDTH 16
-#define AFBC_TILE_HEIGHT 16
-#define AFBC_CACHE_ALIGN 64
-
/* AFBC supports compressing a few canonical formats. Additional formats are
* available by using a canonical internal format. Given a PIPE format, find
* the canonical AFBC internal format if it exists, or NONE if the format
return panfrost_afbc_format(dev, format) != PIPE_FORMAT_NONE;
}
-unsigned
-panfrost_afbc_header_size(unsigned width, unsigned height)
-{
- /* Align to tile */
- unsigned aligned_width = ALIGN_POT(width, AFBC_TILE_WIDTH);
- unsigned aligned_height = ALIGN_POT(height, AFBC_TILE_HEIGHT);
-
- /* Compute size in tiles, rather than pixels */
- unsigned tile_count_x = aligned_width / AFBC_TILE_WIDTH;
- unsigned tile_count_y = aligned_height / AFBC_TILE_HEIGHT;
- unsigned tile_count = tile_count_x * tile_count_y;
-
- /* Multiply to find the header size */
- unsigned header_bytes = tile_count * AFBC_HEADER_BYTES_PER_TILE;
-
- /* Align and go */
- return ALIGN_POT(header_bytes, AFBC_CACHE_ALIGN);
-
-}
-
/* The lossless colour transform (AFBC_FORMAT_MOD_YTR) requires RGB. */
bool
(AFBC_HEADER_BYTES_PER_TILE * pan_afbc_tile_size(modifier));
}
+/*
+ * Determine the required alignment for the body offset of an AFBC image. For
+ * now, this depends only on whether tiling is in use. These minimum alignments
+ * are required on all current GPUs.
+ */
+static inline uint32_t
+pan_afbc_body_align(uint64_t modifier)
+{
+ return (modifier & AFBC_FORMAT_MOD_TILED) ? 4096 : 64;
+}
+
/* Computes sizes for checksumming, which is 8 bytes per 16x16 tile.
* Checksumming is believed to be a CRC variant (CRC64 based on the size?).
* This feature is also known as "transaction elimination". */
/* Compute AFBC sizes if necessary */
if (afbc) {
- slice->afbc.header_size =
- panfrost_afbc_header_size(width, height);
slice->row_stride =
pan_afbc_row_stride(layout->modifier, effective_width);
+ slice->afbc.header_size =
+ ALIGN_POT(slice->row_stride * (effective_height / align_h),
+ pan_afbc_body_align(layout->modifier));
if (explicit_layout && explicit_layout->row_stride < slice->row_stride)
return false;