mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 02:58:05 +02:00
pan: Consolidate AFRC helpers in a single source file
Create a pan_afrc.h header gathering all AFRC-related helpers spread
across pan_layout.c, pan_texture.{c,h} and pan_afbc.c.
By making them inline functions, we also allow for extra compile-time
optimizations.
While at it, we pick a consistent pan_ prefix instead of the
pan_/panfrost_ mix we currently have.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Eric R. Smith <eric.smith@collabora.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Acked-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Ryan Mckeever <ryan.mckeever@collabora.com>
Reviewed-by: Olivia Lee <olivia.lee@collabora.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34767>
This commit is contained in:
parent
0807d26a29
commit
a794ea6f9f
9 changed files with 461 additions and 494 deletions
|
|
@ -50,6 +50,7 @@
|
|||
|
||||
#include "decode.h"
|
||||
#include "pan_afbc.h"
|
||||
#include "pan_afrc.h"
|
||||
#include "pan_bo.h"
|
||||
#include "pan_context.h"
|
||||
#include "pan_resource.h"
|
||||
|
|
@ -435,7 +436,7 @@ panfrost_should_afrc(struct panfrost_device *dev,
|
|||
return false;
|
||||
|
||||
/* Only a small selection of formats are AFRC'able */
|
||||
if (!panfrost_format_supports_afrc(fmt))
|
||||
if (!pan_format_supports_afrc(fmt))
|
||||
return false;
|
||||
|
||||
/* AFRC does not support layered (GLES3 style) multisampling. Use
|
||||
|
|
@ -482,7 +483,7 @@ panfrost_best_modifier(struct pipe_screen *pscreen,
|
|||
* for the next valid one.
|
||||
*/
|
||||
for (int i = afrc_rate; i < 12; ++i) {
|
||||
if (panfrost_afrc_get_modifiers(fmt, i, 0, NULL)) {
|
||||
if (pan_afrc_get_modifiers(fmt, i, 0, NULL)) {
|
||||
afrc_rate = i;
|
||||
break;
|
||||
}
|
||||
|
|
@ -495,7 +496,7 @@ panfrost_best_modifier(struct pipe_screen *pscreen,
|
|||
unsigned num_mods = 0;
|
||||
|
||||
STATIC_ASSERT(PIPE_COMPRESSION_FIXED_RATE_DEFAULT == PAN_AFRC_RATE_DEFAULT);
|
||||
num_mods = panfrost_afrc_get_modifiers(fmt, afrc_rate, 1, &mod);
|
||||
num_mods = pan_afrc_get_modifiers(fmt, afrc_rate, 1, &mod);
|
||||
if (num_mods > 0) {
|
||||
return mod;
|
||||
}
|
||||
|
|
@ -573,7 +574,7 @@ panfrost_resource_setup(struct pipe_screen *screen,
|
|||
|
||||
/* Update the compression rate with the correct value as we
|
||||
* want the real bitrate and not DEFAULT */
|
||||
pres->base.compression_rate = panfrost_afrc_get_rate(fmt, chosen_mod);
|
||||
pres->base.compression_rate = pan_afrc_get_rate(fmt, chosen_mod);
|
||||
|
||||
ASSERTED bool valid =
|
||||
pan_image_layout_init(dev->arch, &pres->image.layout, NULL);
|
||||
|
|
@ -1592,9 +1593,9 @@ pan_legalize_format(struct panfrost_context *ctx,
|
|||
pan_afbc_format(dev->arch, new_format));
|
||||
} else if (drm_is_afrc(rsrc->image.layout.modifier)) {
|
||||
struct pan_afrc_format_info old_info =
|
||||
panfrost_afrc_get_format_info(old_format);
|
||||
pan_afrc_get_format_info(old_format);
|
||||
struct pan_afrc_format_info new_info =
|
||||
panfrost_afrc_get_format_info(new_format);
|
||||
pan_afrc_get_format_info(new_format);
|
||||
compatible = !memcmp(&old_info, &new_info, sizeof(old_info));
|
||||
} else if (drm_is_mtk_tiled(rsrc->image.layout.modifier)) {
|
||||
compatible = false;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include "decode.h"
|
||||
#include "pan_afbc.h"
|
||||
#include "pan_afrc.h"
|
||||
#include "pan_bo.h"
|
||||
#include "pan_fence.h"
|
||||
#include "pan_public.h"
|
||||
|
|
@ -233,7 +234,7 @@ panfrost_query_compression_rates(struct pipe_screen *screen,
|
|||
return;
|
||||
}
|
||||
|
||||
*count = panfrost_afrc_query_rates(format, max, rates);
|
||||
*count = pan_afrc_query_rates(format, max, rates);
|
||||
}
|
||||
|
||||
/* We always support linear and tiled operations, both external and internal.
|
||||
|
|
@ -252,7 +253,7 @@ panfrost_walk_dmabuf_modifiers(struct pipe_screen *screen,
|
|||
dev->has_afbc && pan_format_supports_afbc(dev->arch, format);
|
||||
bool ytr = pan_afbc_can_ytr(format);
|
||||
bool tiled_afbc = pan_afbc_can_tile(dev->arch);
|
||||
bool afrc = allow_afrc && dev->has_afrc && panfrost_format_supports_afrc(format);
|
||||
bool afrc = allow_afrc && dev->has_afrc && pan_format_supports_afrc(format);
|
||||
PAN_SUPPORTED_MODIFIERS(supported_mods);
|
||||
|
||||
unsigned count = 0;
|
||||
|
|
@ -321,7 +322,7 @@ panfrost_query_compression_modifiers(struct pipe_screen *screen,
|
|||
DRM_FORMAT_MOD_INVALID,
|
||||
false /* disallow afrc */);
|
||||
else if (dev->has_afrc)
|
||||
*count = panfrost_afrc_get_modifiers(format, rate, max, modifiers);
|
||||
*count = pan_afrc_get_modifiers(format, rate, max, modifiers);
|
||||
else
|
||||
*count = 0; /* compression requested but not supported */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ endforeach
|
|||
libpanfrost_lib_files = files(
|
||||
'pan_encoder.h',
|
||||
|
||||
'pan_afrc.c',
|
||||
'pan_attributes.c',
|
||||
'pan_blend.c',
|
||||
'pan_clear.c',
|
||||
|
|
|
|||
|
|
@ -1,218 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
bool
|
||||
panfrost_format_supports_afrc(enum pipe_format format)
|
||||
{
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
int c = util_format_get_first_non_void_channel(desc->format);
|
||||
|
||||
if (c == -1)
|
||||
return false;
|
||||
|
||||
return desc->is_array && desc->channel[c].size == 8;
|
||||
}
|
||||
|
||||
struct panfrost_afrc_block_size {
|
||||
unsigned size; /* Block size in bytes */
|
||||
unsigned alignment; /* Buffer alignment */
|
||||
uint64_t modifier_flag; /* Part of the modifier for CU size */
|
||||
};
|
||||
|
||||
#define BLOCK_SIZE(block_size, buffer_alignment) \
|
||||
{ \
|
||||
.size = block_size, .alignment = buffer_alignment, \
|
||||
.modifier_flag = AFRC_FORMAT_MOD_CU_SIZE_##block_size, \
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
const struct panfrost_afrc_block_size panfrost_afrc_block_sizes[] = {
|
||||
BLOCK_SIZE(16, 1024),
|
||||
BLOCK_SIZE(24, 512),
|
||||
BLOCK_SIZE(32, 2048),
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
/* Total number of components in a AFRC coding unit */
|
||||
static unsigned
|
||||
panfrost_afrc_clump_get_nr_components(enum pipe_format format, bool scan)
|
||||
{
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
struct pan_block_size clump_sz = panfrost_afrc_clump_size(format, scan);
|
||||
return clump_sz.width * clump_sz.height * desc->nr_channels;
|
||||
}
|
||||
|
||||
unsigned
|
||||
panfrost_afrc_query_rates(enum pipe_format format, unsigned max,
|
||||
uint32_t *rates)
|
||||
{
|
||||
if (!panfrost_format_supports_afrc(format))
|
||||
return 0;
|
||||
|
||||
unsigned clump_comps = panfrost_afrc_clump_get_nr_components(format, false);
|
||||
unsigned nr_rates = 0;
|
||||
|
||||
/**
|
||||
* From EGL_EXT_surface_compression:
|
||||
*
|
||||
* "For pixel formats with different number of bits per component, the
|
||||
* specified fixed-rate compression rate applies to the component with
|
||||
* the highest number of bits."
|
||||
*
|
||||
* We only support formats where all components have the same size for now.
|
||||
* Let's just use the first component size for calculation.
|
||||
*/
|
||||
unsigned uncompressed_rate =
|
||||
util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0);
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(panfrost_afrc_block_sizes); ++i) {
|
||||
unsigned clump_sz = panfrost_afrc_block_sizes[i].size * 8;
|
||||
unsigned rate = clump_sz / clump_comps;
|
||||
|
||||
if (rate >= uncompressed_rate)
|
||||
continue;
|
||||
|
||||
if (nr_rates < max)
|
||||
rates[nr_rates] = rate;
|
||||
nr_rates++;
|
||||
|
||||
if (max > 0 && nr_rates == max)
|
||||
break;
|
||||
}
|
||||
|
||||
return nr_rates;
|
||||
}
|
||||
|
||||
unsigned
|
||||
panfrost_afrc_get_modifiers(enum pipe_format format, uint32_t rate,
|
||||
unsigned max, uint64_t *modifiers)
|
||||
{
|
||||
if (!panfrost_format_supports_afrc(format))
|
||||
return 0;
|
||||
|
||||
/* For now, the number of components in a clump is always the same no
|
||||
* matter the layout for all supported formats */
|
||||
unsigned clump_comps = panfrost_afrc_clump_get_nr_components(format, false);
|
||||
unsigned count = 0;
|
||||
|
||||
/* FIXME Choose a more sensitive default compression rate? */
|
||||
if (rate == PAN_AFRC_RATE_DEFAULT) {
|
||||
if (max > 0)
|
||||
modifiers[0] = DRM_FORMAT_MOD_ARM_AFRC(AFRC_FORMAT_MOD_CU_SIZE_24);
|
||||
|
||||
if (max > 1)
|
||||
modifiers[1] = DRM_FORMAT_MOD_ARM_AFRC(AFRC_FORMAT_MOD_CU_SIZE_24 |
|
||||
AFRC_FORMAT_MOD_LAYOUT_SCAN);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(panfrost_afrc_block_sizes); ++i) {
|
||||
unsigned clump_sz = panfrost_afrc_block_sizes[i].size * 8;
|
||||
if (rate == clump_sz / clump_comps) {
|
||||
for (unsigned scan = 0; scan < 2; ++scan) {
|
||||
if (count < max) {
|
||||
modifiers[count] = DRM_FORMAT_MOD_ARM_AFRC(
|
||||
panfrost_afrc_block_sizes[i].modifier_flag |
|
||||
(scan ? AFRC_FORMAT_MOD_LAYOUT_SCAN : 0));
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
panfrost_afrc_get_rate(enum pipe_format format, uint64_t modifier)
|
||||
{
|
||||
if (!drm_is_afrc(modifier) || !panfrost_format_supports_afrc(format))
|
||||
return PAN_AFRC_RATE_NONE;
|
||||
|
||||
bool scan = panfrost_afrc_is_scan(modifier);
|
||||
unsigned block_comps = panfrost_afrc_clump_get_nr_components(format, scan);
|
||||
uint32_t block_sz = panfrost_afrc_block_size_from_modifier(modifier) * 8;
|
||||
|
||||
return block_sz / block_comps;
|
||||
}
|
||||
437
src/panfrost/lib/pan_afrc.h
Normal file
437
src/panfrost/lib/pan_afrc.h
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Collabora, Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Authors:
|
||||
* Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
|
||||
*/
|
||||
|
||||
#ifndef __PAN_AFRC_H
|
||||
#define __PAN_AFRC_H
|
||||
|
||||
#include "pan_format.h"
|
||||
#include "pan_texture.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* 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).
|
||||
*/
|
||||
|
||||
#define AFRC_CLUMPS_PER_TILE 64
|
||||
|
||||
enum pan_afrc_rate {
|
||||
PAN_AFRC_RATE_NONE,
|
||||
PAN_AFRC_RATE_1BPC,
|
||||
PAN_AFRC_RATE_2BPC,
|
||||
PAN_AFRC_RATE_3BPC,
|
||||
PAN_AFRC_RATE_4BPC,
|
||||
PAN_AFRC_RATE_5BPC,
|
||||
PAN_AFRC_RATE_6BPC,
|
||||
PAN_AFRC_RATE_7BPC,
|
||||
PAN_AFRC_RATE_8BPC,
|
||||
PAN_AFRC_RATE_9BPC,
|
||||
PAN_AFRC_RATE_10BPC,
|
||||
PAN_AFRC_RATE_11BPC,
|
||||
PAN_AFRC_RATE_12BPC,
|
||||
PAN_AFRC_RATE_DEFAULT = 0xF
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/*
|
||||
* Given an AFRC modifier, return whether the layout is optimized for scan
|
||||
* order (vs rotation order).
|
||||
*/
|
||||
static inline bool
|
||||
pan_afrc_is_scan(uint64_t modifier)
|
||||
{
|
||||
return modifier & AFRC_FORMAT_MOD_LAYOUT_SCAN;
|
||||
}
|
||||
|
||||
static inline struct pan_afrc_format_info
|
||||
pan_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;
|
||||
}
|
||||
|
||||
struct pan_afrc_block_size {
|
||||
unsigned size; /* Block size in bytes */
|
||||
unsigned alignment; /* Buffer alignment */
|
||||
uint64_t modifier_flag; /* Part of the modifier for CU size */
|
||||
};
|
||||
|
||||
#define BLOCK_SIZE(block_size, buffer_alignment) \
|
||||
{ \
|
||||
.size = block_size, \
|
||||
.alignment = buffer_alignment, \
|
||||
.modifier_flag = AFRC_FORMAT_MOD_CU_SIZE_##block_size, \
|
||||
}
|
||||
|
||||
#define AFRC_BLOCK_SIZES(__name) \
|
||||
static const struct pan_afrc_block_size __name[] = { \
|
||||
BLOCK_SIZE(16, 1024), \
|
||||
BLOCK_SIZE(24, 512), \
|
||||
BLOCK_SIZE(32, 2048), \
|
||||
}
|
||||
|
||||
static inline struct pan_block_size
|
||||
pan_afrc_clump_size(enum pipe_format format, bool scan)
|
||||
{
|
||||
struct pan_afrc_format_info finfo = pan_afrc_get_format_info(format);
|
||||
|
||||
switch (finfo.num_comps) {
|
||||
case 1:
|
||||
return scan ? (struct pan_block_size){16, 4}
|
||||
: (struct pan_block_size){8, 8};
|
||||
case 2:
|
||||
return (struct pan_block_size){8, 4};
|
||||
case 3:
|
||||
case 4:
|
||||
return (struct pan_block_size){4, 4};
|
||||
default:
|
||||
assert(0);
|
||||
return (struct pan_block_size){0, 0};
|
||||
}
|
||||
}
|
||||
|
||||
/* Total number of components in a AFRC coding unit */
|
||||
static inline unsigned
|
||||
pan_afrc_clump_get_nr_components(enum pipe_format format, bool scan)
|
||||
{
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
struct pan_block_size clump_sz = pan_afrc_clump_size(format, scan);
|
||||
return clump_sz.width * clump_sz.height * desc->nr_channels;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pan_format_supports_afrc(enum pipe_format format)
|
||||
{
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
int c = util_format_get_first_non_void_channel(desc->format);
|
||||
|
||||
if (c == -1)
|
||||
return false;
|
||||
|
||||
return desc->is_array && desc->channel[c].size == 8;
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
pan_afrc_query_rates(enum pipe_format format, unsigned max, uint32_t *rates)
|
||||
{
|
||||
if (!pan_format_supports_afrc(format))
|
||||
return 0;
|
||||
|
||||
unsigned clump_comps = pan_afrc_clump_get_nr_components(format, false);
|
||||
unsigned nr_rates = 0;
|
||||
|
||||
/**
|
||||
* From EGL_EXT_surface_compression:
|
||||
*
|
||||
* "For pixel formats with different number of bits per component, the
|
||||
* specified fixed-rate compression rate applies to the component with
|
||||
* the highest number of bits."
|
||||
*
|
||||
* We only support formats where all components have the same size for now.
|
||||
* Let's just use the first component size for calculation.
|
||||
*/
|
||||
unsigned uncompressed_rate =
|
||||
util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0);
|
||||
|
||||
AFRC_BLOCK_SIZES(block_sizes);
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(block_sizes); ++i) {
|
||||
unsigned clump_sz = block_sizes[i].size * 8;
|
||||
unsigned rate = clump_sz / clump_comps;
|
||||
|
||||
if (rate >= uncompressed_rate)
|
||||
continue;
|
||||
|
||||
if (nr_rates < max)
|
||||
rates[nr_rates] = rate;
|
||||
nr_rates++;
|
||||
|
||||
if (max > 0 && nr_rates == max)
|
||||
break;
|
||||
}
|
||||
|
||||
return nr_rates;
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
pan_afrc_get_modifiers(enum pipe_format format, uint32_t rate, unsigned max,
|
||||
uint64_t *modifiers)
|
||||
{
|
||||
if (!pan_format_supports_afrc(format))
|
||||
return 0;
|
||||
|
||||
/* For now, the number of components in a clump is always the same no
|
||||
* matter the layout for all supported formats */
|
||||
unsigned clump_comps = pan_afrc_clump_get_nr_components(format, false);
|
||||
unsigned count = 0;
|
||||
|
||||
/* FIXME Choose a more sensitive default compression rate? */
|
||||
if (rate == PAN_AFRC_RATE_DEFAULT) {
|
||||
if (max > 0)
|
||||
modifiers[0] = DRM_FORMAT_MOD_ARM_AFRC(AFRC_FORMAT_MOD_CU_SIZE_24);
|
||||
|
||||
if (max > 1)
|
||||
modifiers[1] = DRM_FORMAT_MOD_ARM_AFRC(AFRC_FORMAT_MOD_CU_SIZE_24 |
|
||||
AFRC_FORMAT_MOD_LAYOUT_SCAN);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
AFRC_BLOCK_SIZES(block_sizes);
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(block_sizes); ++i) {
|
||||
unsigned clump_sz = block_sizes[i].size * 8;
|
||||
if (rate == clump_sz / clump_comps) {
|
||||
for (unsigned scan = 0; scan < 2; ++scan) {
|
||||
if (count < max) {
|
||||
modifiers[count] = DRM_FORMAT_MOD_ARM_AFRC(
|
||||
block_sizes[i].modifier_flag |
|
||||
(scan ? AFRC_FORMAT_MOD_LAYOUT_SCAN : 0));
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
pan_afrc_block_size_from_modifier(uint64_t modifier)
|
||||
{
|
||||
switch (modifier & AFRC_FORMAT_MOD_CU_SIZE_MASK) {
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_16:
|
||||
return 16;
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_24:
|
||||
return 24;
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_32:
|
||||
return 32;
|
||||
default:
|
||||
unreachable("invalid coding unit size flag in modifier");
|
||||
};
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
pan_afrc_get_rate(enum pipe_format format, uint64_t modifier)
|
||||
{
|
||||
if (!drm_is_afrc(modifier) || !pan_format_supports_afrc(format))
|
||||
return PAN_AFRC_RATE_NONE;
|
||||
|
||||
bool scan = pan_afrc_is_scan(modifier);
|
||||
unsigned block_comps = pan_afrc_clump_get_nr_components(format, scan);
|
||||
uint32_t block_sz = pan_afrc_block_size_from_modifier(modifier) * 8;
|
||||
|
||||
return block_sz / block_comps;
|
||||
}
|
||||
|
||||
static inline struct pan_block_size
|
||||
pan_afrc_layout_size(uint64_t modifier)
|
||||
{
|
||||
if (pan_afrc_is_scan(modifier))
|
||||
return (struct pan_block_size){16, 4};
|
||||
else
|
||||
return (struct pan_block_size){8, 8};
|
||||
}
|
||||
|
||||
static inline struct pan_block_size
|
||||
pan_afrc_tile_size(enum pipe_format format, uint64_t modifier)
|
||||
{
|
||||
bool scan = pan_afrc_is_scan(modifier);
|
||||
struct pan_block_size clump_sz = pan_afrc_clump_size(format, scan);
|
||||
struct pan_block_size layout_sz = pan_afrc_layout_size(modifier);
|
||||
|
||||
return (struct pan_block_size){clump_sz.width * layout_sz.width,
|
||||
clump_sz.height * layout_sz.height};
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
pan_afrc_buffer_alignment_from_modifier(uint64_t modifier)
|
||||
{
|
||||
switch (modifier & AFRC_FORMAT_MOD_CU_SIZE_MASK) {
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_16:
|
||||
return 1024;
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_24:
|
||||
return 512;
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_32:
|
||||
return 2048;
|
||||
default:
|
||||
unreachable("invalid coding unit size flag in modifier");
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the number of bytes between rows of paging tiles in an AFRC image
|
||||
*/
|
||||
static inline uint32_t
|
||||
pan_afrc_row_stride(enum pipe_format format, uint64_t modifier, uint32_t width)
|
||||
{
|
||||
struct pan_block_size tile_size = pan_afrc_tile_size(format, modifier);
|
||||
unsigned block_size = pan_afrc_block_size_from_modifier(modifier);
|
||||
|
||||
return (width / tile_size.width) * block_size * AFRC_CLUMPS_PER_TILE;
|
||||
}
|
||||
|
||||
#if PAN_ARCH >= 10
|
||||
static inline enum mali_afrc_format
|
||||
pan_afrc_format(struct pan_afrc_format_info info, uint64_t modifier,
|
||||
unsigned plane)
|
||||
{
|
||||
bool scan = pan_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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline enum mali_afrc_block_size
|
||||
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;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#include "genxml/gen_macros.h"
|
||||
|
||||
#include "pan_afbc.h"
|
||||
#include "pan_afrc.h"
|
||||
#include "pan_desc.h"
|
||||
#include "pan_encoder.h"
|
||||
#include "pan_props.h"
|
||||
|
|
@ -650,13 +651,11 @@ pan_prepare_rt(const struct pan_fb_info *fb, unsigned layer_idx,
|
|||
#if PAN_ARCH >= 10
|
||||
} else if (drm_is_afrc(image->layout.modifier)) {
|
||||
struct pan_afrc_format_info finfo =
|
||||
panfrost_afrc_get_format_info(image->layout.format);
|
||||
pan_afrc_get_format_info(image->layout.format);
|
||||
|
||||
cfg->writeback_mode = MALI_WRITEBACK_MODE_AFRC_RGB;
|
||||
cfg->afrc.block_size =
|
||||
GENX(pan_afrc_block_size)(image->layout.modifier, 0);
|
||||
cfg->afrc.format =
|
||||
GENX(pan_afrc_format)(finfo, image->layout.modifier, 0);
|
||||
cfg->afrc.block_size = pan_afrc_block_size(image->layout.modifier, 0);
|
||||
cfg->afrc.format = pan_afrc_format(finfo, image->layout.modifier, 0);
|
||||
|
||||
cfg->rgb.base = surf.data;
|
||||
cfg->rgb.row_stride = row_stride;
|
||||
|
|
|
|||
|
|
@ -27,101 +27,10 @@
|
|||
#include "util/macros.h"
|
||||
#include "util/u_math.h"
|
||||
#include "pan_afbc.h"
|
||||
#include "pan_afrc.h"
|
||||
#include "pan_props.h"
|
||||
#include "pan_texture.h"
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
struct pan_block_size
|
||||
panfrost_afrc_clump_size(enum pipe_format format, bool scan)
|
||||
{
|
||||
struct pan_afrc_format_info finfo = panfrost_afrc_get_format_info(format);
|
||||
|
||||
switch (finfo.num_comps) {
|
||||
case 1:
|
||||
return scan ? (struct pan_block_size){16, 4}
|
||||
: (struct pan_block_size){8, 8};
|
||||
case 2:
|
||||
return (struct pan_block_size){8, 4};
|
||||
case 3:
|
||||
case 4:
|
||||
return (struct pan_block_size){4, 4};
|
||||
default:
|
||||
assert(0);
|
||||
return (struct pan_block_size){0, 0};
|
||||
}
|
||||
}
|
||||
|
||||
static struct pan_block_size
|
||||
panfrost_afrc_layout_size(uint64_t modifier)
|
||||
{
|
||||
if (panfrost_afrc_is_scan(modifier))
|
||||
return (struct pan_block_size){16, 4};
|
||||
else
|
||||
return (struct pan_block_size){8, 8};
|
||||
}
|
||||
|
||||
struct pan_block_size
|
||||
panfrost_afrc_tile_size(enum pipe_format format, uint64_t modifier)
|
||||
{
|
||||
bool scan = panfrost_afrc_is_scan(modifier);
|
||||
struct pan_block_size clump_sz = panfrost_afrc_clump_size(format, scan);
|
||||
struct pan_block_size layout_sz = panfrost_afrc_layout_size(modifier);
|
||||
|
||||
return (struct pan_block_size){clump_sz.width * layout_sz.width,
|
||||
clump_sz.height * layout_sz.height};
|
||||
}
|
||||
|
||||
unsigned
|
||||
panfrost_afrc_block_size_from_modifier(uint64_t modifier)
|
||||
{
|
||||
switch (modifier & AFRC_FORMAT_MOD_CU_SIZE_MASK) {
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_16:
|
||||
return 16;
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_24:
|
||||
return 24;
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_32:
|
||||
return 32;
|
||||
default:
|
||||
unreachable("invalid coding unit size flag in modifier");
|
||||
};
|
||||
}
|
||||
|
||||
static unsigned
|
||||
panfrost_afrc_buffer_alignment_from_modifier(uint64_t modifier)
|
||||
{
|
||||
switch (modifier & AFRC_FORMAT_MOD_CU_SIZE_MASK) {
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_16:
|
||||
return 1024;
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_24:
|
||||
return 512;
|
||||
case AFRC_FORMAT_MOD_CU_SIZE_32:
|
||||
return 2048;
|
||||
default:
|
||||
unreachable("invalid coding unit size flag in modifier");
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the number of bytes between rows of paging tiles in an AFRC image
|
||||
*/
|
||||
uint32_t
|
||||
pan_afrc_row_stride(enum pipe_format format, uint64_t modifier, uint32_t width)
|
||||
{
|
||||
struct pan_block_size tile_size = panfrost_afrc_tile_size(format, modifier);
|
||||
unsigned block_size = panfrost_afrc_block_size_from_modifier(modifier);
|
||||
|
||||
return (width / tile_size.width) * block_size * AFRC_CLUMPS_PER_TILE;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -149,7 +58,7 @@ panfrost_block_size(uint64_t modifier, enum pipe_format format)
|
|||
else if (drm_is_afbc(modifier))
|
||||
return pan_afbc_superblock_size(modifier);
|
||||
else if (drm_is_afrc(modifier))
|
||||
return panfrost_afrc_tile_size(format, modifier);
|
||||
return pan_afrc_tile_size(format, modifier);
|
||||
else
|
||||
return (struct pan_block_size){1, 1};
|
||||
}
|
||||
|
|
@ -183,7 +92,7 @@ format_minimum_alignment(unsigned arch, enum pipe_format format, uint64_t mod)
|
|||
return 16;
|
||||
|
||||
if (drm_is_afrc(mod))
|
||||
return panfrost_afrc_buffer_alignment_from_modifier(mod);
|
||||
return pan_afrc_buffer_alignment_from_modifier(mod);
|
||||
|
||||
if (arch < 7)
|
||||
return 64;
|
||||
|
|
@ -267,7 +176,7 @@ panfrost_get_legacy_stride(const struct pan_image_layout *layout,
|
|||
return width * util_format_get_blocksize(layout->format);
|
||||
} else if (drm_is_afrc(layout->modifier)) {
|
||||
struct pan_block_size tile_size =
|
||||
panfrost_afrc_tile_size(layout->format, layout->modifier);
|
||||
pan_afrc_tile_size(layout->format, layout->modifier);
|
||||
|
||||
return row_stride / tile_size.height;
|
||||
} else {
|
||||
|
|
@ -288,7 +197,7 @@ panfrost_from_legacy_stride(unsigned legacy_stride, enum pipe_format format,
|
|||
return pan_afbc_row_stride(modifier, width);
|
||||
} else if (drm_is_afrc(modifier)) {
|
||||
struct pan_block_size tile_size =
|
||||
panfrost_afrc_tile_size(format, modifier);
|
||||
pan_afrc_tile_size(format, modifier);
|
||||
|
||||
return legacy_stride * tile_size.height;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
|
||||
#include "pan_afbc.h"
|
||||
#include "pan_afrc.h"
|
||||
#include "pan_texture.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/u_math.h"
|
||||
|
|
@ -526,13 +527,13 @@ panfrost_emit_plane(const struct pan_image_view *iview,
|
|||
} else if (afrc) {
|
||||
#if PAN_ARCH >= 10
|
||||
struct pan_afrc_format_info finfo =
|
||||
panfrost_afrc_get_format_info(iview->format);
|
||||
pan_afrc_get_format_info(iview->format);
|
||||
|
||||
cfg.plane_type = MALI_PLANE_TYPE_AFRC;
|
||||
cfg.afrc.block_size =
|
||||
GENX(pan_afrc_block_size)(layout->modifier, plane_index);
|
||||
pan_afrc_block_size(layout->modifier, plane_index);
|
||||
cfg.afrc.format =
|
||||
GENX(pan_afrc_format)(finfo, layout->modifier, plane_index);
|
||||
pan_afrc_format(finfo, layout->modifier, plane_index);
|
||||
#endif
|
||||
} else {
|
||||
cfg.plane_type =
|
||||
|
|
@ -906,96 +907,3 @@ GENX(panfrost_new_storage_texture)(const struct pan_image_view *iview,
|
|||
}
|
||||
}
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -267,67 +267,6 @@ struct pan_block_size {
|
|||
|
||||
uint32_t pan_slice_align(uint64_t modifier);
|
||||
|
||||
/* AFRC */
|
||||
|
||||
#define AFRC_CLUMPS_PER_TILE 64
|
||||
|
||||
enum pan_afrc_rate {
|
||||
PAN_AFRC_RATE_NONE,
|
||||
PAN_AFRC_RATE_1BPC,
|
||||
PAN_AFRC_RATE_2BPC,
|
||||
PAN_AFRC_RATE_3BPC,
|
||||
PAN_AFRC_RATE_4BPC,
|
||||
PAN_AFRC_RATE_5BPC,
|
||||
PAN_AFRC_RATE_6BPC,
|
||||
PAN_AFRC_RATE_7BPC,
|
||||
PAN_AFRC_RATE_8BPC,
|
||||
PAN_AFRC_RATE_9BPC,
|
||||
PAN_AFRC_RATE_10BPC,
|
||||
PAN_AFRC_RATE_11BPC,
|
||||
PAN_AFRC_RATE_12BPC,
|
||||
PAN_AFRC_RATE_DEFAULT = 0xF
|
||||
};
|
||||
|
||||
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_format_supports_afrc(enum pipe_format format);
|
||||
|
||||
bool panfrost_afrc_is_scan(uint64_t modifier);
|
||||
|
||||
struct pan_block_size panfrost_afrc_clump_size(enum pipe_format format,
|
||||
bool scan);
|
||||
|
||||
struct pan_block_size panfrost_afrc_tile_size(enum pipe_format format,
|
||||
uint64_t modifier);
|
||||
|
||||
unsigned panfrost_afrc_block_size_from_modifier(uint64_t modifier);
|
||||
|
||||
unsigned pan_afrc_row_stride(enum pipe_format format, uint64_t modifier,
|
||||
uint32_t width);
|
||||
|
||||
unsigned panfrost_afrc_query_rates(enum pipe_format format, unsigned max,
|
||||
uint32_t *rates);
|
||||
|
||||
unsigned panfrost_afrc_get_modifiers(enum pipe_format format, uint32_t rate,
|
||||
unsigned max, uint64_t *modifiers);
|
||||
|
||||
uint32_t panfrost_afrc_get_rate(enum pipe_format format, uint64_t modifier);
|
||||
|
||||
struct pan_block_size panfrost_block_size(uint64_t modifier,
|
||||
enum pipe_format format);
|
||||
|
||||
|
|
@ -394,14 +333,6 @@ void pan_iview_get_surface(const struct pan_image_view *iview, unsigned level,
|
|||
unsigned layer, unsigned sample,
|
||||
struct pan_surface *surf);
|
||||
|
||||
#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
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue