v3d: Enables DRM_FORMAT_MOD_BROADCOM_SAND128 support

It enables SAND modifier with columns 128-bytes-wide support for
NV12 format.

When a DRM_FORMAT_MOD_BROADCOM_SAND128 is enabled an imported NV12
texture format has a different layout. Luma and Chroma planes layout
is interleaved for every 128-bytes-wide columns.

Although TFU was supposed to convert a NV12 with SAND_COL128 modifier
from YUV to sRGB color space, it expects a particular swizzle that is not
the one provided by the video decoder available at the Raspberry Pi 4.

This patch follows a similar approach to VC4 YUV blit, using a custom
blit shader that transforms a NV12 texture with SAND_COL128 modifier
with the two interleaved planes to two not-interleaved textures with
UIF format, as it was a regular NV12 format texture.

To reduce the number of texture-fetch operations during the blit, we
are reading and writing the textures in pixel groups of 32-bits. This
implies some swizzling of the pixels to meet the particularities
of the different micro-tile layouts for 8bpp, 16bpp and 32bpp.

With this approach, we are not adding a new format that could be named
"NV12_SAND128". We are just enabling a format modifier.

v2: Rework checks for supported modifiers (Alejandro Piñeiro)
    Destroy custom shaders on context destroy (Alejandro Piñeiro)
    Add more comments (Alejandro Piñeiro)
    SAND128 in query_dmabuf_modifiers should report external_only true.

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10051>
This commit is contained in:
Jose Maria Casanova Crespo
2021-02-25 13:09:23 +01:00
committed by Marge Bot
parent 2470bcb946
commit 95c4f0f910
6 changed files with 330 additions and 6 deletions

View File

@@ -637,6 +637,7 @@ v3d_screen_get_compiler_options(struct pipe_screen *pscreen,
static const uint64_t v3d_available_modifiers[] = {
DRM_FORMAT_MOD_BROADCOM_UIF,
DRM_FORMAT_MOD_LINEAR,
DRM_FORMAT_MOD_BROADCOM_SAND128,
};
static void
@@ -658,7 +659,9 @@ v3d_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
for (i = 0; i < *count; i++) {
modifiers[i] = v3d_available_modifiers[i];
if (external_only)
external_only[i] = false;
external_only[i] =
v3d_available_modifiers[i] ==
DRM_FORMAT_MOD_BROADCOM_SAND128;
}
}
@@ -669,8 +672,22 @@ v3d_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
bool *external_only)
{
int i;
bool is_sand_col128 = (format == PIPE_FORMAT_NV12) &&
(fourcc_mod_broadcom_mod(modifier) == DRM_FORMAT_MOD_BROADCOM_SAND128);
for (i = 0; i < ARRAY_SIZE(v3d_available_modifiers); i++) {
if (is_sand_col128) {
if (external_only)
*external_only = true;
return true;
}
/* We don't want to generally allow DRM_FORMAT_MOD_BROADCOM_SAND128
* modifier, that is the last v3d_available_modifiers. We only accept
* it in the case of having a PIPE_FORMAT_NV12.
*/
assert(v3d_available_modifiers[ARRAY_SIZE(v3d_available_modifiers) - 1] ==
DRM_FORMAT_MOD_BROADCOM_SAND128);
for (i = 0; i < ARRAY_SIZE(v3d_available_modifiers) - 1; i++) {
if (v3d_available_modifiers[i] == modifier) {
if (external_only)
*external_only = false;