From: Louis Chauvet <louis.chauvet@bootlin.com>
To: Arthur Grillo <arthurgrillo@riseup.net>
Cc: "Daniel Vetter" <daniel@ffwll.ch>,
"David Airlie" <airlied@gmail.com>,
"Haneen Mohammed" <hamohammed.sa@gmail.com>,
"Harry Wentland" <harry.wentland@amd.com>,
"Jonathan Corbet" <corbet@lwn.net>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Maíra Canal" <mairacanal@riseup.net>,
"Melissa Wen" <melissa.srw@gmail.com>,
"Rodrigo Siqueira" <rodrigosiqueiramelo@gmail.com>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
linux-doc@vger.kernel.org
Subject: Re: [PATCH v2 5/7] drm/vkms: Add YUV support
Date: Thu, 1 Feb 2024 18:44:29 +0100 [thread overview]
Message-ID: <ZbvYfaxBoGI_LzYS@localhost.localdomain> (raw)
In-Reply-To: <20240110-vkms-yuv-v2-5-952fcaa5a193@riseup.net>
Le 10/01/24 - 14:44, Arthur Grillo a écrit :
> Add support to the YUV formats bellow:
>
> - NV12
> - NV16
> - NV24
> - NV21
> - NV61
> - NV42
> - YUV420
> - YUV422
> - YUV444
> - YVU420
> - YVU422
> - YVU444
>
> The conversion matrices of each encoding and range were obtained by
> rounding the values of the original conversion matrices multiplied by
> 2^8. This is done to avoid the use of fixed point operations.
>
> Signed-off-by: Arthur Grillo <arthurgrillo@riseup.net>
> ---
> drivers/gpu/drm/vkms/vkms_formats.c | 147 ++++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/vkms/vkms_formats.h | 4 +
> drivers/gpu/drm/vkms/vkms_plane.c | 14 +++-
> 3 files changed, 164 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c
> index 098ed16f2104..7c1a0ca322d9 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.c
> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> @@ -119,6 +119,137 @@ static void RGB565_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 *out_pixel
> out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
> }
>
> +static void ycbcr2rgb(const s16 m[3][3], u8 y, u8 cb, u8 cr, u8 y_offset, u8 *r, u8 *g, u8 *b)
> +{
> + s32 y_16, cb_16, cr_16;
> + s32 r_16, g_16, b_16;
> +
> + y_16 = y - y_offset;
> + cb_16 = cb - 128;
> + cr_16 = cr - 128;
> +
> + r_16 = m[0][0] * y_16 + m[0][1] * cb_16 + m[0][2] * cr_16;
> + g_16 = m[1][0] * y_16 + m[1][1] * cb_16 + m[1][2] * cr_16;
> + b_16 = m[2][0] * y_16 + m[2][1] * cb_16 + m[2][2] * cr_16;
> +
> + *r = clamp(r_16, 0, 0xffff) >> 8;
> + *g = clamp(g_16, 0, 0xffff) >> 8;
> + *b = clamp(b_16, 0, 0xffff) >> 8;
> +}
> +
> +static void yuv_u8_to_argb_u16(struct pixel_argb_u16 *argb_u16, const struct pixel_yuv_u8 *yuv_u8,
> + enum drm_color_encoding encoding, enum drm_color_range range)
> +{
> + static const s16 bt601_full[3][3] = {
> + {256, 0, 359},
> + {256, -88, -183},
> + {256, 454, 0},
> + };
> + static const s16 bt601[3][3] = {
> + {298, 0, 409},
> + {298, -100, -208},
> + {298, 516, 0},
> + };
> + static const s16 rec709_full[3][3] = {
> + {256, 0, 408},
> + {256, -48, -120},
> + {256, 476, 0 },
> + };
> + static const s16 rec709[3][3] = {
> + {298, 0, 459},
> + {298, -55, -136},
> + {298, 541, 0},
> + };
> + static const s16 bt2020_full[3][3] = {
> + {256, 0, 377},
> + {256, -42, -146},
> + {256, 482, 0},
> + };
> + static const s16 bt2020[3][3] = {
> + {298, 0, 430},
> + {298, -48, -167},
> + {298, 548, 0},
> + };
> +
> + u8 r = 0;
> + u8 g = 0;
> + u8 b = 0;
> + bool full = range == DRM_COLOR_YCBCR_FULL_RANGE;
> + unsigned int y_offset = full ? 0 : 16;
> +
> + switch (encoding) {
> + case DRM_COLOR_YCBCR_BT601:
> + ycbcr2rgb(full ? bt601_full : bt601,
> + yuv_u8->y, yuv_u8->u, yuv_u8->v, y_offset, &r, &g, &b);
> + break;
> + case DRM_COLOR_YCBCR_BT709:
> + ycbcr2rgb(full ? rec709_full : rec709,
> + yuv_u8->y, yuv_u8->u, yuv_u8->v, y_offset, &r, &g, &b);
> + break;
> + case DRM_COLOR_YCBCR_BT2020:
> + ycbcr2rgb(full ? bt2020_full : bt2020,
> + yuv_u8->y, yuv_u8->u, yuv_u8->v, y_offset, &r, &g, &b);
> + break;
> + default:
> + pr_warn_once("Not supported color encoding\n");
> + break;
> + }
> +
> + argb_u16->r = r * 257;
> + argb_u16->g = g * 257;
> + argb_u16->b = b * 257;
> +}
> +
> +static void semi_planar_yuv_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 *out_pixel,
> + enum drm_color_encoding encoding,
> + enum drm_color_range range)
> +{
> + struct pixel_yuv_u8 yuv_u8;
> +
> + yuv_u8.y = src_pixels[0][0];
> + yuv_u8.u = src_pixels[1][0];
> + yuv_u8.v = src_pixels[1][1];
> +
> + yuv_u8_to_argb_u16(out_pixel, &yuv_u8, encoding, range);
> +}
> +
> +static void semi_planar_yvu_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 *out_pixel,
> + enum drm_color_encoding encoding,
> + enum drm_color_range range)
> +{
> + struct pixel_yuv_u8 yuv_u8;
> +
> + yuv_u8.y = src_pixels[0][0];
> + yuv_u8.v = src_pixels[1][0];
> + yuv_u8.u = src_pixels[1][1];
> +
> + yuv_u8_to_argb_u16(out_pixel, &yuv_u8, encoding, range);
> +}
> +
> +static void planar_yuv_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 *out_pixel,
> + enum drm_color_encoding encoding, enum drm_color_range range)
> +{
> + struct pixel_yuv_u8 yuv_u8;
> +
> + yuv_u8.y = src_pixels[0][0];
> + yuv_u8.u = src_pixels[1][0];
> + yuv_u8.v = src_pixels[2][0];
> +
> + yuv_u8_to_argb_u16(out_pixel, &yuv_u8, encoding, range);
> +}
> +
> +static void planar_yvu_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 *out_pixel,
> + enum drm_color_encoding encoding, enum drm_color_range range)
> +{
> + struct pixel_yuv_u8 yuv_u8;
> +
> + yuv_u8.y = src_pixels[0][0];
> + yuv_u8.v = src_pixels[1][0];
> + yuv_u8.u = src_pixels[2][0];
> +
> + yuv_u8_to_argb_u16(out_pixel, &yuv_u8, encoding, range);
> +}
> +
> /**
> * vkms_compose_row - compose a single row of a plane
> * @stage_buffer: output line with the composed pixels
> @@ -267,6 +398,22 @@ void *get_pixel_conversion_function(u32 format)
> return &XRGB16161616_to_argb_u16;
> case DRM_FORMAT_RGB565:
> return &RGB565_to_argb_u16;
> + case DRM_FORMAT_NV12:
> + case DRM_FORMAT_NV16:
> + case DRM_FORMAT_NV24:
> + return &semi_planar_yuv_to_argb_u16;
> + case DRM_FORMAT_NV21:
> + case DRM_FORMAT_NV61:
> + case DRM_FORMAT_NV42:
> + return &semi_planar_yvu_to_argb_u16;
> + case DRM_FORMAT_YUV420:
> + case DRM_FORMAT_YUV422:
> + case DRM_FORMAT_YUV444:
> + return &planar_yuv_to_argb_u16;
> + case DRM_FORMAT_YVU420:
> + case DRM_FORMAT_YVU422:
> + case DRM_FORMAT_YVU444:
> + return &planar_yvu_to_argb_u16;
> default:
> return NULL;
> }
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.h b/drivers/gpu/drm/vkms/vkms_formats.h
> index cf59c2ed8e9a..a8b2f92bdcb5 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.h
> +++ b/drivers/gpu/drm/vkms/vkms_formats.h
> @@ -9,4 +9,8 @@ void *get_pixel_conversion_function(u32 format);
>
> void *get_pixel_write_function(u32 format);
>
> +struct pixel_yuv_u8 {
> + u8 y, u, v;
> +};
> +
> #endif /* _VKMS_FORMATS_H_ */
> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> index e87c80575b7d..932736fc3ee9 100644
> --- a/drivers/gpu/drm/vkms/vkms_plane.c
> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> @@ -17,7 +17,19 @@ static const u32 vkms_formats[] = {
> DRM_FORMAT_XRGB8888,
> DRM_FORMAT_XRGB16161616,
> DRM_FORMAT_ARGB16161616,
> - DRM_FORMAT_RGB565
> + DRM_FORMAT_RGB565,
> + DRM_FORMAT_NV12,
> + DRM_FORMAT_NV16,
> + DRM_FORMAT_NV24,
> + DRM_FORMAT_NV21,
> + DRM_FORMAT_NV61,
> + DRM_FORMAT_NV42,
> + DRM_FORMAT_YUV420,
> + DRM_FORMAT_YUV422,
> + DRM_FORMAT_YUV444,
> + DRM_FORMAT_YVU420,
> + DRM_FORMAT_YVU422,
> + DRM_FORMAT_YVU444
> };
>
> static struct drm_plane_state *
>
> --
> 2.43.0
>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
next prev parent reply other threads:[~2024-02-01 17:44 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-10 17:44 [PATCH v2 0/7] Add YUV formats to VKMS Arthur Grillo
2024-01-10 17:44 ` Arthur Grillo
2024-01-10 17:44 ` [PATCH v2 1/7] drm/vkms: Use drm_frame directly Arthur Grillo
2024-01-10 17:44 ` Arthur Grillo
2024-02-01 17:43 ` Louis Chauvet
2024-01-10 17:44 ` [PATCH v2 2/7] drm/vkms: Add support for multy-planar framebuffers Arthur Grillo
2024-01-10 17:44 ` Arthur Grillo
2024-02-01 17:38 ` Louis Chauvet
2024-02-02 18:49 ` Arthur Grillo
2024-01-10 17:44 ` [PATCH v2 3/7] drm/vkms: Add range and encoding properties to pixel_read function Arthur Grillo
2024-01-10 17:44 ` Arthur Grillo
2024-02-01 17:44 ` Louis Chauvet
2024-01-10 17:44 ` [PATCH v2 4/7] drm/vkms: Add chroma subsampling Arthur Grillo
2024-01-10 17:44 ` Arthur Grillo
2024-02-01 17:39 ` Louis Chauvet
2024-01-10 17:44 ` [PATCH v2 5/7] drm/vkms: Add YUV support Arthur Grillo
2024-01-10 17:44 ` Arthur Grillo
2024-02-01 17:44 ` Louis Chauvet [this message]
2024-01-10 17:44 ` [PATCH v2 6/7] drm/vkms: Drop YUV formats TODO Arthur Grillo
2024-01-10 17:44 ` Arthur Grillo
2024-02-01 17:46 ` Louis Chauvet
2024-01-10 17:44 ` [PATCH v2 7/7] drm/vkms: Create KUnit tests for YUV conversions Arthur Grillo
2024-01-10 17:44 ` Arthur Grillo
2024-02-01 17:40 ` Louis Chauvet
2024-01-15 15:06 ` [PATCH v2 0/7] Add YUV formats to VKMS Sebastian Wick
2024-01-15 15:06 ` Sebastian Wick
2024-02-28 23:42 ` Arthur Grillo
2024-02-29 17:52 ` Sebastian Wick
2024-02-29 18:27 ` Arthur Grillo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZbvYfaxBoGI_LzYS@localhost.localdomain \
--to=louis.chauvet@bootlin.com \
--cc=airlied@gmail.com \
--cc=arthurgrillo@riseup.net \
--cc=corbet@lwn.net \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=hamohammed.sa@gmail.com \
--cc=harry.wentland@amd.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mairacanal@riseup.net \
--cc=melissa.srw@gmail.com \
--cc=mripard@kernel.org \
--cc=rodrigosiqueiramelo@gmail.com \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.