[PATCH] drm: drm_fourcc: add 10/12bit software decoder YCbCr formats

Robert Mader robert.mader at collabora.com
Thu Apr 24 12:53:18 UTC 2025


Chris, Javier, Laurent - sorry for the noise, but given you reviewed 
changes in the respective files before, maybe you can help me moving 
this forward? I'd be very happy for any feedback to get this landed, 
thanks! :)

On 07.04.25 21:13, Robert Mader wrote:
> This adds FOURCCs for 10/12bit YCbCr formats used by software decoders
> like ffmpeg, dav1d and libvpx. The intended use-case is buffer sharing
> between SW-decoders and GPUs by allocating buffers with udmabuf or
> dma-heaps, avoiding unnecessary copies or format conversions.
>
> Unlike formats typically used by hardware decoders these formats
> use a LSB alignment. In order to allow fast implementations in GL
> and Vulkan the padding must contain only zeros, so the float
> representation can calculated by simple multiplicating with 2^6=64
> or 2^4=16.
>
> WIP MRs for Mesa, Vulkan and Gstreamer can be found at:
>   - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34303
>   - https://github.com/rmader/Vulkan-Docs/commits/ycbcr-16bit-lsb-formats/
>   - https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8540
>
> The values where inspired by the corresponding VA_FOURCC_I010, however
> suggestions are very welcome.
>
> Signed-off-by: Robert Mader <robert.mader at collabora.com>
> ---
>   drivers/gpu/drm/drm_fourcc.c  | 18 ++++++++++++++++++
>   include/uapi/drm/drm_fourcc.h | 20 ++++++++++++++++++++
>   2 files changed, 38 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index 3a94ca211f9c..917f77703645 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -346,6 +346,24 @@ const struct drm_format_info *__drm_format_info(u32 format)
>   		{ .format = DRM_FORMAT_P030,            .depth = 0,  .num_planes = 2,
>   		  .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },
>   		  .hsub = 2, .vsub = 2, .is_yuv = true},
> +		{ .format = DRM_FORMAT_I010,            .depth = 0,  .num_planes = 3,
> +		  .char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
> +		  .hsub = 2, .vsub = 2, .is_yuv = true},
> +		{ .format = DRM_FORMAT_I210,            .depth = 0,  .num_planes = 3,
> +		  .char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
> +		  .hsub = 2, .vsub = 1, .is_yuv = true},
> +		{ .format = DRM_FORMAT_I410,            .depth = 0,  .num_planes = 3,
> +		  .char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
> +		  .hsub = 1, .vsub = 1, .is_yuv = true},
> +		{ .format = DRM_FORMAT_I012,            .depth = 0,  .num_planes = 3,
> +		  .char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
> +		  .hsub = 2, .vsub = 2, .is_yuv = true},
> +		{ .format = DRM_FORMAT_I212,            .depth = 0,  .num_planes = 3,
> +		  .char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
> +		  .hsub = 2, .vsub = 1, .is_yuv = true},
> +		{ .format = DRM_FORMAT_I412,            .depth = 0,  .num_planes = 3,
> +		  .char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
> +		  .hsub = 1, .vsub = 1, .is_yuv = true},
>   	};
>   
>   	unsigned int i;
> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> index e41a3cec6a9e..f22c80031595 100644
> --- a/include/uapi/drm/drm_fourcc.h
> +++ b/include/uapi/drm/drm_fourcc.h
> @@ -397,6 +397,26 @@ extern "C" {
>   #define DRM_FORMAT_YUV444	fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
>   #define DRM_FORMAT_YVU444	fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
>   
> +/*
> + * 3 plane YCbCr LSB aligned
> + * index 0 = Y plane, [15:0] x:Y [6:10] little endian
> + * index 1 = Cr plane, [15:0] x:Cr [6:10] little endian
> + * index 2 = Cb plane, [15:0] x:Cb [6:10] little endian
> + */
> +#define DRM_FORMAT_I010	fourcc_code('I', '0', '1', '0') /* 2x2 subsampled Cb (1) and Cr (2) planes 10 bits per channel */
> +#define DRM_FORMAT_I210	fourcc_code('I', '2', '1', '0') /* 2x1 subsampled Cb (1) and Cr (2) planes 10 bits per channel */
> +#define DRM_FORMAT_I410	fourcc_code('I', '4', '1', '0') /* non-subsampled Cb (1) and Cr (2) planes 10 bits per channel */
> +
> +/*
> + * 3 plane YCbCr LSB aligned
> + * index 0 = Y plane, [15:0] x:Y [4:12] little endian
> + * index 1 = Cr plane, [15:0] x:Cr [4:12] little endian
> + * index 2 = Cb plane, [15:0] x:Cb [4:12] little endian
> + */
> +#define DRM_FORMAT_I012	fourcc_code('I', '0', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes 12 bits per channel */
> +#define DRM_FORMAT_I212	fourcc_code('I', '2', '1', '2') /* 2x1 subsampled Cb (1) and Cr (2) planes 12 bits per channel */
> +#define DRM_FORMAT_I412	fourcc_code('I', '4', '1', '2') /* non-subsampled Cb (1) and Cr (2) planes 12 bits per channel */
> +
>   
>   /*
>    * Format Modifiers:


More information about the dri-devel mailing list