panfrost: Don't use texture format swizzles on v7
They're too restricted for AFBC. Fix up instead. There are two problems at play: 1. We can't just map the format swizzle to the pixel format ordering on v7, because the "reordered" values aren't allowed with compression. 2. We can't just compose the format swizzle with the API swizzle, because the composed swizzle is applied to the border colour, so we need to be able to apply an inverted swizzle to the border colour. That only works for bijective format swizzles. Fortunately, there's a neat solution: decompose the format's swizzle into two swizzles, the first mapping to a reordering that IS allowed for compression, and the second a bijection. Then we use the allowed reordering when texturing, apply the bijective swizzle to the API swizzle, and apply the inverse of the bijective swizzle to the border colour. When we're sampling a border colour, what's now happening mathematically is: (API swizzle o bijective swizzle)((bijective swizzle^-1)(border colour)) = (API swizzle o (bijective swizzle o bijective swizzle^-1))(border colour) = API swizzle(border colour) which is exactly what we wanted. Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20311>
This commit is contained in:

committed by
Marge Bot

parent
f159ff530e
commit
476be5cb27
@@ -212,6 +212,25 @@ panfrost_create_sampler_state(
|
||||
struct panfrost_sampler_state *so = CALLOC_STRUCT(panfrost_sampler_state);
|
||||
so->base = *cso;
|
||||
|
||||
#if PAN_ARCH == 7
|
||||
/* On v7, pan_texture.c composes the API swizzle with a bijective
|
||||
* swizzle derived from the format, to allow more formats than the
|
||||
* hardware otherwise supports. When packing border colours, we need to
|
||||
* undo this bijection, by swizzling with its inverse.
|
||||
*/
|
||||
unsigned mali_format = panfrost_pipe_format_v7[cso->border_color_format].hw;
|
||||
enum mali_rgb_component_order order = mali_format & BITFIELD_MASK(12);
|
||||
|
||||
unsigned char inverted_swizzle[4];
|
||||
panfrost_invert_swizzle(GENX(pan_decompose_swizzle)(order).post,
|
||||
inverted_swizzle);
|
||||
|
||||
util_format_apply_color_swizzle(&so->base.border_color,
|
||||
&cso->border_color,
|
||||
inverted_swizzle,
|
||||
false /* is_integer (irrelevant) */);
|
||||
#endif
|
||||
|
||||
bool using_nearest = cso->min_img_filter == PIPE_TEX_MIPFILTER_NEAREST;
|
||||
|
||||
pan_pack(&so->hw, SAMPLER, cfg) {
|
||||
@@ -231,10 +250,10 @@ panfrost_create_sampler_state(
|
||||
cfg.compare_function = panfrost_sampler_compare_func(cso);
|
||||
cfg.seamless_cube_map = cso->seamless_cube_map;
|
||||
|
||||
cfg.border_color_r = cso->border_color.ui[0];
|
||||
cfg.border_color_g = cso->border_color.ui[1];
|
||||
cfg.border_color_b = cso->border_color.ui[2];
|
||||
cfg.border_color_a = cso->border_color.ui[3];
|
||||
cfg.border_color_r = so->base.border_color.ui[0];
|
||||
cfg.border_color_g = so->base.border_color.ui[1];
|
||||
cfg.border_color_b = so->base.border_color.ui[2];
|
||||
cfg.border_color_a = so->base.border_color.ui[3];
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
if (cso->max_anisotropy > 1) {
|
||||
|
@@ -202,6 +202,16 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
||||
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
|
||||
return 16;
|
||||
|
||||
/* v7 (only) restricts component orders with AFBC. To workaround, we
|
||||
* compose format swizzles with texture swizzles. pan_texture.c motsly
|
||||
* handles this but we need to fix up the border colour.
|
||||
*/
|
||||
case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
|
||||
if (dev->arch == 7)
|
||||
return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_FREEDRENO;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT:
|
||||
return 65536;
|
||||
|
||||
|
@@ -139,11 +139,7 @@ panfrost_afbc_format(unsigned arch, enum pipe_format format)
|
||||
*/
|
||||
format = util_format_linear(format);
|
||||
|
||||
/* Don't allow swizzled formats on v7 */
|
||||
if (arch == 7 && format != unswizzled_format(format))
|
||||
return PAN_AFBC_MODE_INVALID;
|
||||
|
||||
/* Otherwise swizzling doesn't affect AFBC */
|
||||
/* We handle swizzling orthogonally to AFBC */
|
||||
format = unswizzled_format(format);
|
||||
|
||||
switch (format) {
|
||||
|
@@ -593,3 +593,55 @@ const struct panfrost_format GENX(panfrost_pipe_format)[PIPE_FORMAT_COUNT] = {
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#if PAN_ARCH == 7
|
||||
/*
|
||||
* Decompose a component ordering swizzle into a component ordering (applied
|
||||
* first) and a swizzle (applied second). The output ordering "pre" is allowed
|
||||
* with compression and the swizzle "post" is a bijection.
|
||||
*
|
||||
* These properties allow any component ordering to be used with compression, by
|
||||
* using the output "pre" ordering, composing the API swizzle with the "post"
|
||||
* ordering, and applying the inverse of the "post" ordering to the border
|
||||
* colour to undo what we compose into the API swizzle.
|
||||
*
|
||||
* Note that "post" is a swizzle, not a component ordering, which means it is
|
||||
* inverted from the ordering. E.g. ARGB ordering uses a GBAR (YZWX) swizzle.
|
||||
*/
|
||||
struct pan_decomposed_swizzle
|
||||
GENX(pan_decompose_swizzle)(enum mali_rgb_component_order order)
|
||||
{
|
||||
#define CASE(case_, pre_, R_, G_, B_, A_) \
|
||||
case MALI_RGB_COMPONENT_ORDER_##case_: \
|
||||
return (struct pan_decomposed_swizzle) { \
|
||||
MALI_RGB_COMPONENT_ORDER_##pre_, { \
|
||||
PIPE_SWIZZLE_##R_, PIPE_SWIZZLE_##G_, \
|
||||
PIPE_SWIZZLE_##B_, PIPE_SWIZZLE_##A_ \
|
||||
} \
|
||||
};
|
||||
|
||||
switch (order) {
|
||||
CASE(RGBA, RGBA, X, Y, Z, W);
|
||||
CASE(GRBA, RGBA, Y, X, Z, W);
|
||||
CASE(BGRA, RGBA, Z, Y, X, W);
|
||||
CASE(ARGB, RGBA, Y, Z, W, X);
|
||||
CASE(AGRB, RGBA, Z, Y, W, X);
|
||||
CASE(ABGR, RGBA, W, Z, Y, X);
|
||||
CASE(RGB1, RGB1, X, Y, Z, W);
|
||||
CASE(GRB1, RGB1, Y, X, Z, W);
|
||||
CASE(BGR1, RGB1, Z, Y, X, W);
|
||||
CASE(1RGB, RGB1, Y, Z, W, X);
|
||||
CASE(1GRB, RGB1, Z, Y, W, X);
|
||||
CASE(1BGR, RGB1, W, Z, Y, X);
|
||||
CASE(RRRR, RRRR, X, Y, Z, W);
|
||||
CASE(RRR1, RRR1, X, Y, Z, W);
|
||||
CASE(RRRA, RRRA, X, Y, Z, W);
|
||||
CASE(000A, 000A, X, Y, Z, W);
|
||||
CASE(0001, 0001, X, Y, Z, W);
|
||||
CASE(0000, 0000, X, Y, Z, W);
|
||||
default: unreachable("Invalid case for texturing");
|
||||
}
|
||||
|
||||
#undef CASE
|
||||
}
|
||||
#endif
|
||||
|
@@ -81,4 +81,17 @@ panfrost_get_default_swizzle(unsigned components)
|
||||
}
|
||||
}
|
||||
|
||||
#if PAN_ARCH == 7
|
||||
struct pan_decomposed_swizzle {
|
||||
/* Component ordering to apply first */
|
||||
enum mali_rgb_component_order pre;
|
||||
|
||||
/* Bijective swizzle applied after */
|
||||
unsigned char post[4];
|
||||
};
|
||||
|
||||
struct pan_decomposed_swizzle
|
||||
GENX(pan_decompose_swizzle)(enum mali_rgb_component_order order);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -535,7 +535,8 @@ GENX(panfrost_new_texture)(const struct panfrost_device *dev,
|
||||
{
|
||||
const struct pan_image_layout *layout = &iview->image->layout;
|
||||
enum pipe_format format = iview->format;
|
||||
unsigned swizzle;
|
||||
uint32_t mali_format = dev->formats[format].hw;
|
||||
unsigned char swizzle[4];
|
||||
|
||||
if (PAN_ARCH >= 7 && util_format_is_depth_or_stencil(format)) {
|
||||
/* v7+ doesn't have an _RRRR component order, combine the
|
||||
@@ -545,14 +546,31 @@ GENX(panfrost_new_texture)(const struct panfrost_device *dev,
|
||||
PIPE_SWIZZLE_X, PIPE_SWIZZLE_X,
|
||||
PIPE_SWIZZLE_X, PIPE_SWIZZLE_X,
|
||||
};
|
||||
unsigned char patched_swizzle[4];
|
||||
|
||||
util_format_compose_swizzles(replicate_x,
|
||||
iview->swizzle,
|
||||
patched_swizzle);
|
||||
swizzle = panfrost_translate_swizzle_4(patched_swizzle);
|
||||
swizzle);
|
||||
} else if (PAN_ARCH == 7) {
|
||||
#if PAN_ARCH == 7
|
||||
/* v7 (only) restricts component orders when AFBC is in use.
|
||||
* Rather than restrict AFBC, we use an allowed component order
|
||||
* with an invertible swizzle composed.
|
||||
*/
|
||||
enum mali_rgb_component_order orig =
|
||||
mali_format & BITFIELD_MASK(12);
|
||||
struct pan_decomposed_swizzle decomposed =
|
||||
GENX(pan_decompose_swizzle)(orig);
|
||||
|
||||
/* Apply the new component order */
|
||||
mali_format = (mali_format & ~orig) | decomposed.pre;
|
||||
|
||||
/* Compose the new swizzle */
|
||||
util_format_compose_swizzles(decomposed.post, iview->swizzle,
|
||||
swizzle);
|
||||
#endif
|
||||
} else {
|
||||
swizzle = panfrost_translate_swizzle_4(iview->swizzle);
|
||||
STATIC_ASSERT(sizeof(swizzle) == sizeof(iview->swizzle));
|
||||
memcpy(swizzle, iview->swizzle, sizeof(swizzle));
|
||||
}
|
||||
|
||||
panfrost_emit_texture_payload(iview, format, payload->cpu);
|
||||
@@ -581,14 +599,14 @@ GENX(panfrost_new_texture)(const struct panfrost_device *dev,
|
||||
|
||||
pan_pack(out, TEXTURE, cfg) {
|
||||
cfg.dimension = iview->dim;
|
||||
cfg.format = dev->formats[format].hw;
|
||||
cfg.format = mali_format;
|
||||
cfg.width = width;
|
||||
cfg.height = u_minify(layout->height, iview->first_level);
|
||||
if (iview->dim == MALI_TEXTURE_DIMENSION_3D)
|
||||
cfg.depth = u_minify(layout->depth, iview->first_level);
|
||||
else
|
||||
cfg.sample_count = layout->nr_samples;
|
||||
cfg.swizzle = swizzle;
|
||||
cfg.swizzle = panfrost_translate_swizzle_4(swizzle);
|
||||
#if PAN_ARCH >= 9
|
||||
cfg.texel_interleave =
|
||||
(layout->modifier != DRM_FORMAT_MOD_LINEAR) ||
|
||||
|
Reference in New Issue
Block a user