mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-26 18:40:33 +01:00
panfrost: add utils for AFRC fixed-rate support
There are mainly two parameters to control the fixed-rate
compression:
- Block size: the size (16, 24 or 32 bytes) that will take a
coding unit (format dependent).
- AFRC format: the pixel format and paging tile layout
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28813>
This commit is contained in:
parent
fb95e8ada0
commit
2dae926850
5 changed files with 221 additions and 0 deletions
|
|
@ -55,6 +55,7 @@ libpanfrost_lib_files = files(
|
||||||
'pan_encoder.h',
|
'pan_encoder.h',
|
||||||
|
|
||||||
'pan_afbc.c',
|
'pan_afbc.c',
|
||||||
|
'pan_afrc.c',
|
||||||
'pan_attributes.c',
|
'pan_attributes.c',
|
||||||
'pan_blend.c',
|
'pan_blend.c',
|
||||||
'pan_clear.c',
|
'pan_clear.c',
|
||||||
|
|
|
||||||
82
src/panfrost/lib/pan_afrc.c
Normal file
82
src/panfrost/lib/pan_afrc.c
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Collabora, Ltd.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pan_texture.h"
|
||||||
|
|
||||||
|
/* Arm Fixed-Rate Compression (AFRC) is a lossy compression scheme natively
|
||||||
|
* implemented in Mali GPUs. AFRC images can only be rendered or textured
|
||||||
|
* from. It is currently not possible to do image reads or writes to such
|
||||||
|
* resources.
|
||||||
|
*
|
||||||
|
* AFRC divides the image into an array of fixed-size coding units which are
|
||||||
|
* grouped into paging tiles. The size of the coding units (clump size)
|
||||||
|
* depends on the image format and the pixel layout (whether it is optimized
|
||||||
|
* for 2D locality and rotation, or for scan line order access). The last
|
||||||
|
* parameter is the size of the compressed block that can be either 16, 24,
|
||||||
|
* or 32 bytes.
|
||||||
|
*
|
||||||
|
* The compression rate can be calculated by dividing the compressed block
|
||||||
|
* size by the uncompressed block size (clump size multiplied by the component
|
||||||
|
* size and the number of components).
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct pan_afrc_format_info
|
||||||
|
panfrost_afrc_get_format_info(enum pipe_format format)
|
||||||
|
{
|
||||||
|
const struct util_format_description *desc = util_format_description(format);
|
||||||
|
struct pan_afrc_format_info info = {0};
|
||||||
|
|
||||||
|
/* No AFRC(ZS). */
|
||||||
|
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
|
||||||
|
return info;
|
||||||
|
|
||||||
|
unsigned bpc = 0;
|
||||||
|
for (unsigned c = 0; c < desc->nr_channels; c++) {
|
||||||
|
if (bpc && bpc != desc->channel[c].size)
|
||||||
|
return info;
|
||||||
|
|
||||||
|
bpc = desc->channel[0].size;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.bpc = bpc;
|
||||||
|
|
||||||
|
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_YUV) {
|
||||||
|
if (desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED)
|
||||||
|
info.ichange_fmt = PAN_AFRC_ICHANGE_FORMAT_YUV444;
|
||||||
|
else if (util_format_is_subsampled_422(format))
|
||||||
|
info.ichange_fmt = PAN_AFRC_ICHANGE_FORMAT_YUV422;
|
||||||
|
else
|
||||||
|
info.ichange_fmt = PAN_AFRC_ICHANGE_FORMAT_YUV420;
|
||||||
|
} else {
|
||||||
|
assert(desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
|
||||||
|
desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
|
||||||
|
info.ichange_fmt = PAN_AFRC_ICHANGE_FORMAT_RAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.num_planes = util_format_get_num_planes(format);
|
||||||
|
info.num_comps = util_format_get_nr_components(format);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
@ -116,6 +116,16 @@ panfrost_afbc_subblock_size(uint64_t modifier)
|
||||||
return (struct pan_block_size){4, 4};
|
return (struct pan_block_size){4, 4};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given an AFRC modifier, return whether the layout is optimized for scan
|
||||||
|
* order (vs rotation order).
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
panfrost_afrc_is_scan(uint64_t modifier)
|
||||||
|
{
|
||||||
|
return modifier & AFRC_FORMAT_MOD_LAYOUT_SCAN;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a format, determine the tile size used for u-interleaving. For formats
|
* Given a format, determine the tile size used for u-interleaving. For formats
|
||||||
* that are already block compressed, this is 4x4. For all other formats, this
|
* that are already block compressed, this is 4x4. For all other formats, this
|
||||||
|
|
|
||||||
|
|
@ -735,3 +735,96 @@ GENX(pan_afbc_compression_mode)(enum pipe_format format)
|
||||||
unreachable("all AFBC formats handled");
|
unreachable("all AFBC formats handled");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if PAN_ARCH >= 10
|
||||||
|
enum mali_afrc_format
|
||||||
|
GENX(pan_afrc_format)(struct pan_afrc_format_info info, uint64_t modifier,
|
||||||
|
unsigned plane)
|
||||||
|
{
|
||||||
|
bool scan = panfrost_afrc_is_scan(modifier);
|
||||||
|
|
||||||
|
assert(info.bpc == 8 || info.bpc == 10);
|
||||||
|
assert(info.num_comps > 0 && info.num_comps <= 4);
|
||||||
|
|
||||||
|
switch (info.ichange_fmt) {
|
||||||
|
case PAN_AFRC_ICHANGE_FORMAT_RAW:
|
||||||
|
assert(plane == 0);
|
||||||
|
|
||||||
|
if (info.bpc == 8)
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R8_SCAN : MALI_AFRC_FORMAT_R8_ROT) +
|
||||||
|
(info.num_comps - 1);
|
||||||
|
|
||||||
|
assert(info.num_comps == 4);
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R10G10B10A10_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R10G10B10A10_ROT);
|
||||||
|
|
||||||
|
case PAN_AFRC_ICHANGE_FORMAT_YUV444:
|
||||||
|
if (info.bpc == 8) {
|
||||||
|
if (plane == 0 || info.num_planes == 3)
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R8_444_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R8_444_ROT);
|
||||||
|
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R8G8_444_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R8G8_444_ROT);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(info.num_planes == 3);
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R10_444_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R10_444_ROT);
|
||||||
|
|
||||||
|
case PAN_AFRC_ICHANGE_FORMAT_YUV422:
|
||||||
|
if (info.bpc == 8) {
|
||||||
|
if (plane == 0 || info.num_planes == 3)
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R8_422_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R8_422_ROT);
|
||||||
|
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R8G8_422_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R8G8_422_ROT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plane == 0 || info.num_planes == 3)
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R10_422_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R10_422_ROT);
|
||||||
|
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R10G10_422_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R10G10_422_ROT);
|
||||||
|
|
||||||
|
case PAN_AFRC_ICHANGE_FORMAT_YUV420:
|
||||||
|
if (info.bpc == 8) {
|
||||||
|
if (plane == 0 || info.num_planes == 3)
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R8_420_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R8_420_ROT);
|
||||||
|
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R8G8_420_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R8G8_420_ROT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plane == 0 || info.num_planes == 3)
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R10_420_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R10_420_ROT);
|
||||||
|
|
||||||
|
return (scan ? MALI_AFRC_FORMAT_R10G10_420_SCAN
|
||||||
|
: MALI_AFRC_FORMAT_R10G10_420_ROT);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return MALI_AFRC_FORMAT_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mali_afrc_block_size
|
||||||
|
GENX(pan_afrc_block_size)(uint64_t modifier, unsigned index)
|
||||||
|
{
|
||||||
|
/* Clump size flag for planes 1 and 2 is shifted by 4 bits */
|
||||||
|
unsigned shift = index == 0 ? 0 : 4;
|
||||||
|
uint64_t flag = (modifier >> shift) & AFRC_FORMAT_MOD_CU_SIZE_MASK;
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
switch (flag) {
|
||||||
|
case AFRC_FORMAT_MOD_CU_SIZE_16: return MALI_AFRC_BLOCK_SIZE_16;
|
||||||
|
case AFRC_FORMAT_MOD_CU_SIZE_24: return MALI_AFRC_BLOCK_SIZE_24;
|
||||||
|
case AFRC_FORMAT_MOD_CU_SIZE_32: return MALI_AFRC_BLOCK_SIZE_32;
|
||||||
|
default: unreachable("invalid code unit size");
|
||||||
|
}
|
||||||
|
/* clang-format on */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -278,6 +278,29 @@ uint32_t pan_slice_align(uint64_t modifier);
|
||||||
|
|
||||||
uint32_t pan_afbc_body_align(uint64_t modifier);
|
uint32_t pan_afbc_body_align(uint64_t modifier);
|
||||||
|
|
||||||
|
/* AFRC */
|
||||||
|
|
||||||
|
#define AFRC_CLUMPS_PER_TILE 64
|
||||||
|
|
||||||
|
enum pan_afrc_interchange_format {
|
||||||
|
PAN_AFRC_ICHANGE_FORMAT_RAW,
|
||||||
|
PAN_AFRC_ICHANGE_FORMAT_YUV444,
|
||||||
|
PAN_AFRC_ICHANGE_FORMAT_YUV422,
|
||||||
|
PAN_AFRC_ICHANGE_FORMAT_YUV420,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pan_afrc_format_info {
|
||||||
|
unsigned bpc : 4;
|
||||||
|
unsigned num_comps : 3;
|
||||||
|
unsigned ichange_fmt : 2;
|
||||||
|
unsigned num_planes : 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pan_afrc_format_info
|
||||||
|
panfrost_afrc_get_format_info(enum pipe_format format);
|
||||||
|
|
||||||
|
bool panfrost_afrc_is_scan(uint64_t modifier);
|
||||||
|
|
||||||
struct pan_block_size panfrost_block_size(uint64_t modifier,
|
struct pan_block_size panfrost_block_size(uint64_t modifier,
|
||||||
enum pipe_format format);
|
enum pipe_format format);
|
||||||
|
|
||||||
|
|
@ -302,6 +325,10 @@ unsigned panfrost_texture_offset(const struct pan_image_layout *layout,
|
||||||
((mod >> 52) == \
|
((mod >> 52) == \
|
||||||
(DRM_FORMAT_MOD_ARM_TYPE_AFBC | (DRM_FORMAT_MOD_VENDOR_ARM << 4)))
|
(DRM_FORMAT_MOD_ARM_TYPE_AFBC | (DRM_FORMAT_MOD_VENDOR_ARM << 4)))
|
||||||
|
|
||||||
|
#define drm_is_afrc(mod) \
|
||||||
|
((mod >> 52) == \
|
||||||
|
(DRM_FORMAT_MOD_ARM_TYPE_AFRC | (DRM_FORMAT_MOD_VENDOR_ARM << 4)))
|
||||||
|
|
||||||
struct pan_image_explicit_layout {
|
struct pan_image_explicit_layout {
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
unsigned row_stride;
|
unsigned row_stride;
|
||||||
|
|
@ -337,6 +364,14 @@ enum mali_afbc_compression_mode
|
||||||
GENX(pan_afbc_compression_mode)(enum pipe_format format);
|
GENX(pan_afbc_compression_mode)(enum pipe_format format);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if PAN_ARCH >= 10
|
||||||
|
enum mali_afrc_format
|
||||||
|
GENX(pan_afrc_format)(struct pan_afrc_format_info info, uint64_t modifier,
|
||||||
|
unsigned plane);
|
||||||
|
enum mali_afrc_block_size GENX(pan_afrc_block_size)(uint64_t modifier,
|
||||||
|
unsigned index);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern C */
|
} /* extern C */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue