Skip to content

Commit b8c19bc

Browse files
rmaderpelwell
authored andcommitted
drm: drm_fourcc: add 10/12/16bit software decoder YCbCr formats
This adds FOURCCs for 3-plane 10/12/16bit YCbCr formats used by software decoders like ffmpeg, dav1d and libvpx. The intended use-case is buffer sharing between decoders and GPUs by allocating buffers with e.g. udmabuf or dma-heaps, avoiding unnecessary copies and format conversions in various scenarios. Unlike formats typically used by hardware decoders the 10/12bit 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 be calculated by multiplying with 2^6=64 or 2^4=16 respectively. MRs or branches for Mesa, Vulkan, Gstreamer, Weston and Mutter 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 - https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/1753 - https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4348 The naming scheme follows the 'P' and 'Q' formats. The 'S' stands for 'software' and was selected in order to make remembering easy. The 'Sx16' formats could as well be 'Qx16'. We stick with 'S' as 16bit software decoders are likely much more common than hardware ones for the foreseeable future. Note that these formats already have Vulkan equivalents: - VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM - VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM - VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM Signed-off-by: Robert Mader <robert.mader@collabora.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Link: https://lore.kernel.org/r/20250509133535.60330-1-robert.mader@collabora.com Signed-off-by: Daniel Stone <daniels@collabora.com>
1 parent a77bf18 commit b8c19bc

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

drivers/gpu/drm/drm_fourcc.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,33 @@ const struct drm_format_info *__drm_format_info(u32 format)
346346
{ .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2,
347347
.char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },
348348
.hsub = 2, .vsub = 2, .is_yuv = true},
349+
{ .format = DRM_FORMAT_S010, .depth = 0, .num_planes = 3,
350+
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
351+
.hsub = 2, .vsub = 2, .is_yuv = true},
352+
{ .format = DRM_FORMAT_S210, .depth = 0, .num_planes = 3,
353+
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
354+
.hsub = 2, .vsub = 1, .is_yuv = true},
355+
{ .format = DRM_FORMAT_S410, .depth = 0, .num_planes = 3,
356+
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
357+
.hsub = 1, .vsub = 1, .is_yuv = true},
358+
{ .format = DRM_FORMAT_S012, .depth = 0, .num_planes = 3,
359+
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
360+
.hsub = 2, .vsub = 2, .is_yuv = true},
361+
{ .format = DRM_FORMAT_S212, .depth = 0, .num_planes = 3,
362+
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
363+
.hsub = 2, .vsub = 1, .is_yuv = true},
364+
{ .format = DRM_FORMAT_S412, .depth = 0, .num_planes = 3,
365+
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
366+
.hsub = 1, .vsub = 1, .is_yuv = true},
367+
{ .format = DRM_FORMAT_S016, .depth = 0, .num_planes = 3,
368+
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
369+
.hsub = 2, .vsub = 2, .is_yuv = true},
370+
{ .format = DRM_FORMAT_S216, .depth = 0, .num_planes = 3,
371+
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
372+
.hsub = 2, .vsub = 1, .is_yuv = true},
373+
{ .format = DRM_FORMAT_S416, .depth = 0, .num_planes = 3,
374+
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
375+
.hsub = 1, .vsub = 1, .is_yuv = true},
349376
};
350377

351378
unsigned int i;

include/uapi/drm/drm_fourcc.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,42 @@ extern "C" {
377377
*/
378378
#define DRM_FORMAT_Q401 fourcc_code('Q', '4', '0', '1')
379379

380+
/*
381+
* 3 plane YCbCr LSB aligned
382+
* In order to use these formats in a similar fashion to MSB aligned ones
383+
* implementation can multiply the values by 2^6=64. For that reason the padding
384+
* must only contain zeros.
385+
* index 0 = Y plane, [15:0] z:Y [6:10] little endian
386+
* index 1 = Cr plane, [15:0] z:Cr [6:10] little endian
387+
* index 2 = Cb plane, [15:0] z:Cb [6:10] little endian
388+
*/
389+
#define DRM_FORMAT_S010 fourcc_code('S', '0', '1', '0') /* 2x2 subsampled Cb (1) and Cr (2) planes 10 bits per channel */
390+
#define DRM_FORMAT_S210 fourcc_code('S', '2', '1', '0') /* 2x1 subsampled Cb (1) and Cr (2) planes 10 bits per channel */
391+
#define DRM_FORMAT_S410 fourcc_code('S', '4', '1', '0') /* non-subsampled Cb (1) and Cr (2) planes 10 bits per channel */
392+
393+
/*
394+
* 3 plane YCbCr LSB aligned
395+
* In order to use these formats in a similar fashion to MSB aligned ones
396+
* implementation can multiply the values by 2^4=16. For that reason the padding
397+
* must only contain zeros.
398+
* index 0 = Y plane, [15:0] z:Y [4:12] little endian
399+
* index 1 = Cr plane, [15:0] z:Cr [4:12] little endian
400+
* index 2 = Cb plane, [15:0] z:Cb [4:12] little endian
401+
*/
402+
#define DRM_FORMAT_S012 fourcc_code('S', '0', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes 12 bits per channel */
403+
#define DRM_FORMAT_S212 fourcc_code('S', '2', '1', '2') /* 2x1 subsampled Cb (1) and Cr (2) planes 12 bits per channel */
404+
#define DRM_FORMAT_S412 fourcc_code('S', '4', '1', '2') /* non-subsampled Cb (1) and Cr (2) planes 12 bits per channel */
405+
406+
/*
407+
* 3 plane YCbCr
408+
* index 0 = Y plane, [15:0] Y little endian
409+
* index 1 = Cr plane, [15:0] Cr little endian
410+
* index 2 = Cb plane, [15:0] Cb little endian
411+
*/
412+
#define DRM_FORMAT_S016 fourcc_code('S', '0', '1', '6') /* 2x2 subsampled Cb (1) and Cr (2) planes 16 bits per channel */
413+
#define DRM_FORMAT_S216 fourcc_code('S', '2', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes 16 bits per channel */
414+
#define DRM_FORMAT_S416 fourcc_code('S', '4', '1', '6') /* non-subsampled Cb (1) and Cr (2) planes 16 bits per channel */
415+
380416
/*
381417
* 3 plane YCbCr
382418
* index 0: Y plane, [7:0] Y

0 commit comments

Comments
 (0)