From 551dafcce89a6afed049432e8fc2cf7906465ec3 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 3 Apr 2024 21:18:44 +0200 Subject: [PATCH] render: add support for more formats --- src/format.rs | 769 +++++++++--------------- src/gfx_apis/gl.rs | 2 + src/gfx_apis/gl/gl/render_buffer.rs | 5 +- src/gfx_apis/gl/gl/texture.rs | 11 +- src/gfx_apis/gl/renderer/framebuffer.rs | 15 +- src/gfx_apis/gl/renderer/texture.rs | 4 +- src/gfx_apis/vulkan.rs | 2 + src/gfx_apis/vulkan/format.rs | 3 + src/gfx_apis/vulkan/image.rs | 5 +- src/gfx_apis/vulkan/renderer.rs | 12 +- src/ifs/wl_buffer.rs | 7 +- src/ifs/wl_shm.rs | 2 +- src/ifs/wl_shm_pool.rs | 2 +- 13 files changed, 348 insertions(+), 491 deletions(-) diff --git a/src/format.rs b/src/format.rs index f8594d25..bae6a760 100644 --- a/src/format.rs +++ b/src/format.rs @@ -2,8 +2,12 @@ use { crate::{ gfx_apis::gl::sys::{GLenum, GLint, GL_BGRA_EXT, GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE}, pipewire::pw_pod::{ - SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx, SpaVideoFormat, SPA_VIDEO_FORMAT_BGRA, - SPA_VIDEO_FORMAT_RGBA, + SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx, SPA_VIDEO_FORMAT_xBGR_210LE, + SPA_VIDEO_FORMAT_xRGB_210LE, SpaVideoFormat, SPA_VIDEO_FORMAT_ABGR_210LE, + SPA_VIDEO_FORMAT_ARGB_210LE, SPA_VIDEO_FORMAT_BGR, SPA_VIDEO_FORMAT_BGR15, + SPA_VIDEO_FORMAT_BGR16, SPA_VIDEO_FORMAT_BGRA, SPA_VIDEO_FORMAT_GRAY8, + SPA_VIDEO_FORMAT_RGB, SPA_VIDEO_FORMAT_RGB16, SPA_VIDEO_FORMAT_RGBA, + SPA_VIDEO_FORMAT_UNKNOWN, }, utils::debug_fn::debug_fn, }, @@ -13,21 +17,39 @@ use { std::fmt::{Debug, Write}, }; -#[derive(Copy, Clone, Debug, Eq)] -pub struct Format { - pub name: &'static str, +#[derive(Copy, Clone, Debug)] +pub struct FormatShmInfo { pub bpp: u32, pub gl_format: GLint, pub gl_internal_format: GLenum, pub gl_type: GLint, +} + +#[derive(Copy, Clone, Debug)] +pub struct Format { + pub name: &'static str, pub vk_format: vk::Format, pub drm: u32, pub wl_id: Option, pub external_only_guess: bool, pub has_alpha: bool, - pub shm_supported: bool, pub pipewire: SpaVideoFormat, pub opaque: Option<&'static Format>, + pub shm_info: Option, +} + +const fn default() -> Format { + Format { + name: "", + vk_format: vk::Format::UNDEFINED, + drm: 0, + wl_id: None, + external_only_guess: false, + has_alpha: false, + pipewire: SPA_VIDEO_FORMAT_UNKNOWN, + opaque: None, + shm_info: None, + } } impl PartialEq for Format { @@ -36,6 +58,8 @@ impl PartialEq for Format { } } +impl Eq for Format {} + static FORMATS_MAP: Lazy> = Lazy::new(|| { let mut map = AHashMap::new(); for format in FORMATS { @@ -91,514 +115,315 @@ pub fn map_wayland_format_id(id: u32) -> u32 { pub static ARGB8888: &Format = &Format { name: "argb8888", - bpp: 4, - gl_format: GL_BGRA_EXT, - gl_internal_format: GL_RGBA8, - gl_type: GL_UNSIGNED_BYTE, + shm_info: Some(FormatShmInfo { + bpp: 4, + gl_format: GL_BGRA_EXT, + gl_internal_format: GL_RGBA8, + gl_type: GL_UNSIGNED_BYTE, + }), vk_format: vk::Format::B8G8R8A8_UNORM, drm: ARGB8888_DRM, wl_id: Some(ARGB8888_ID), external_only_guess: false, has_alpha: true, - shm_supported: true, pipewire: SPA_VIDEO_FORMAT_BGRA, opaque: Some(XRGB8888), }; pub static XRGB8888: &Format = &Format { name: "xrgb8888", - bpp: 4, - gl_format: GL_BGRA_EXT, - gl_internal_format: GL_RGBA8, - gl_type: GL_UNSIGNED_BYTE, + shm_info: Some(FormatShmInfo { + bpp: 4, + gl_format: GL_BGRA_EXT, + gl_internal_format: GL_RGBA8, + gl_type: GL_UNSIGNED_BYTE, + }), vk_format: vk::Format::B8G8R8A8_UNORM, drm: XRGB8888_DRM, wl_id: Some(XRGB8888_ID), external_only_guess: false, has_alpha: false, - shm_supported: true, pipewire: SPA_VIDEO_FORMAT_BGRx, opaque: None, }; static ABGR8888: &Format = &Format { name: "abgr8888", - bpp: 4, - gl_format: GL_RGBA, - gl_internal_format: GL_RGBA8, - gl_type: GL_UNSIGNED_BYTE, + shm_info: Some(FormatShmInfo { + bpp: 4, + gl_format: GL_RGBA, + gl_internal_format: GL_RGBA8, + gl_type: GL_UNSIGNED_BYTE, + }), vk_format: vk::Format::R8G8B8A8_UNORM, drm: fourcc_code('A', 'B', '2', '4'), wl_id: None, external_only_guess: false, has_alpha: true, - shm_supported: true, pipewire: SPA_VIDEO_FORMAT_RGBA, opaque: Some(XBGR8888), }; static XBGR8888: &Format = &Format { name: "xbgr8888", - bpp: 4, - gl_format: GL_RGBA, - gl_internal_format: GL_RGBA8, - gl_type: GL_UNSIGNED_BYTE, + shm_info: Some(FormatShmInfo { + bpp: 4, + gl_format: GL_RGBA, + gl_internal_format: GL_RGBA8, + gl_type: GL_UNSIGNED_BYTE, + }), vk_format: vk::Format::R8G8B8A8_UNORM, drm: fourcc_code('X', 'B', '2', '4'), wl_id: None, external_only_guess: false, has_alpha: false, - shm_supported: true, pipewire: SPA_VIDEO_FORMAT_RGBx, opaque: None, }; +static R8: &Format = &Format { + name: "r8", + vk_format: vk::Format::R8_UNORM, + drm: fourcc_code('R', '8', ' ', ' '), + pipewire: SPA_VIDEO_FORMAT_GRAY8, + ..default() +}; + +static GR88: &Format = &Format { + name: "gr88", + vk_format: vk::Format::R8G8_UNORM, + drm: fourcc_code('G', 'R', '8', '8'), + ..default() +}; + +static RGB888: &Format = &Format { + name: "rgb888", + vk_format: vk::Format::B8G8R8_UNORM, + drm: fourcc_code('R', 'G', '2', '4'), + pipewire: SPA_VIDEO_FORMAT_BGR, + ..default() +}; + +static BGR888: &Format = &Format { + name: "bgr888", + vk_format: vk::Format::R8G8B8_UNORM, + drm: fourcc_code('B', 'G', '2', '4'), + pipewire: SPA_VIDEO_FORMAT_RGB, + ..default() +}; + +static RGBA4444: &Format = &Format { + name: "rgba4444", + vk_format: vk::Format::R4G4B4A4_UNORM_PACK16, + drm: fourcc_code('R', 'A', '1', '2'), + has_alpha: true, + opaque: Some(RGBX4444), + ..default() +}; + +static RGBX4444: &Format = &Format { + name: "rgbx4444", + vk_format: vk::Format::R4G4B4A4_UNORM_PACK16, + drm: fourcc_code('R', 'X', '1', '2'), + ..default() +}; + +static BGRA4444: &Format = &Format { + name: "bgra4444", + vk_format: vk::Format::B4G4R4A4_UNORM_PACK16, + drm: fourcc_code('B', 'A', '1', '2'), + has_alpha: true, + opaque: Some(BGRX4444), + ..default() +}; + +static BGRX4444: &Format = &Format { + name: "bgrx4444", + vk_format: vk::Format::B4G4R4A4_UNORM_PACK16, + drm: fourcc_code('B', 'X', '1', '2'), + ..default() +}; + +static RGB565: &Format = &Format { + name: "rgb565", + vk_format: vk::Format::R5G6B5_UNORM_PACK16, + drm: fourcc_code('R', 'G', '1', '6'), + pipewire: SPA_VIDEO_FORMAT_BGR16, + ..default() +}; + +static BGR565: &Format = &Format { + name: "bgr565", + vk_format: vk::Format::B5G6R5_UNORM_PACK16, + drm: fourcc_code('B', 'G', '1', '6'), + pipewire: SPA_VIDEO_FORMAT_RGB16, + ..default() +}; + +static RGBA5551: &Format = &Format { + name: "rgba5551", + vk_format: vk::Format::R5G5B5A1_UNORM_PACK16, + drm: fourcc_code('R', 'A', '1', '5'), + has_alpha: true, + opaque: Some(RGBX5551), + ..default() +}; + +static RGBX5551: &Format = &Format { + name: "rgbx5551", + vk_format: vk::Format::R5G5B5A1_UNORM_PACK16, + drm: fourcc_code('R', 'X', '1', '5'), + ..default() +}; + +static BGRA5551: &Format = &Format { + name: "bgra5551", + vk_format: vk::Format::B5G5R5A1_UNORM_PACK16, + drm: fourcc_code('B', 'A', '1', '5'), + has_alpha: true, + opaque: Some(BGRX5551), + ..default() +}; + +static BGRX5551: &Format = &Format { + name: "bgrx5551", + vk_format: vk::Format::B5G5R5A1_UNORM_PACK16, + drm: fourcc_code('B', 'X', '1', '5'), + ..default() +}; + +static ARGB1555: &Format = &Format { + name: "argb1555", + vk_format: vk::Format::A1R5G5B5_UNORM_PACK16, + drm: fourcc_code('A', 'R', '1', '5'), + has_alpha: true, + opaque: Some(XRGB1555), + ..default() +}; + +static XRGB1555: &Format = &Format { + name: "xrgb1555", + vk_format: vk::Format::A1R5G5B5_UNORM_PACK16, + drm: fourcc_code('X', 'R', '1', '5'), + pipewire: SPA_VIDEO_FORMAT_BGR15, + ..default() +}; + +static ARGB2101010: &Format = &Format { + name: "argb2101010", + vk_format: vk::Format::A2R10G10B10_UNORM_PACK32, + drm: fourcc_code('A', 'R', '3', '0'), + has_alpha: true, + opaque: Some(XRGB2101010), + pipewire: SPA_VIDEO_FORMAT_ARGB_210LE, + ..default() +}; + +static XRGB2101010: &Format = &Format { + name: "xrgb2101010", + vk_format: vk::Format::A2R10G10B10_UNORM_PACK32, + drm: fourcc_code('X', 'R', '3', '0'), + pipewire: SPA_VIDEO_FORMAT_xRGB_210LE, + ..default() +}; + +static ABGR2101010: &Format = &Format { + name: "abgr2101010", + vk_format: vk::Format::A2B10G10R10_UNORM_PACK32, + drm: fourcc_code('A', 'B', '3', '0'), + has_alpha: true, + opaque: Some(XBGR2101010), + pipewire: SPA_VIDEO_FORMAT_ABGR_210LE, + ..default() +}; + +static XBGR2101010: &Format = &Format { + name: "xbgr2101010", + vk_format: vk::Format::A2B10G10R10_UNORM_PACK32, + drm: fourcc_code('X', 'B', '3', '0'), + pipewire: SPA_VIDEO_FORMAT_xBGR_210LE, + ..default() +}; + +static ABGR16161616: &Format = &Format { + name: "abgr16161616", + vk_format: vk::Format::R16G16B16A16_UNORM, + drm: fourcc_code('A', 'B', '4', '8'), + has_alpha: true, + opaque: Some(XBGR16161616), + ..default() +}; + +static XBGR16161616: &Format = &Format { + name: "xbgr16161616", + vk_format: vk::Format::R16G16B16A16_UNORM, + drm: fourcc_code('X', 'B', '4', '8'), + ..default() +}; + +static ABGR16161616F: &Format = &Format { + name: "abgr16161616f", + vk_format: vk::Format::R16G16B16A16_SFLOAT, + drm: fourcc_code('A', 'B', '4', 'H'), + has_alpha: true, + opaque: Some(XBGR16161616F), + ..default() +}; + +static XBGR16161616F: &Format = &Format { + name: "xbgr16161616f", + vk_format: vk::Format::R16G16B16A16_SFLOAT, + drm: fourcc_code('X', 'B', '4', 'H'), + ..default() +}; + pub static FORMATS: &[Format] = &[ - *ARGB8888, *XRGB8888, *ABGR8888, + *ARGB8888, + *XRGB8888, + *ABGR8888, *XBGR8888, - // *NV12, - // Format { - // name: "nv12", - // bpp: 1, // wrong but only used for shm - // gl_format: 0, // wrong but only used for shm - // gl_type: GL_UNSIGNED_BYTE, // wrong but only used for shm - // drm: fourcc_code('N', 'V', '1', '2'), - // wl_id: None, - // external_only_guess: true, - // has_alpha: false, - // shm_supported: false, - // pipewire: SPA_VIDEO_FORMAT_NV12, - // }, - // Format { - // id: fourcc_code('C', '8', ' ', ' '), - // name: "c8", - // }, - // Format { - // id: fourcc_code('R', '8', ' ', ' '), - // name: "r8", - // }, - // Format { - // id: fourcc_code('R', '1', '6', ' '), - // name: "r16", - // }, - // Format { - // id: fourcc_code('R', 'G', '8', '8'), - // name: "rg88", - // }, - // Format { - // id: fourcc_code('G', 'R', '8', '8'), - // name: "gr88", - // }, - // Format { - // id: fourcc_code('R', 'G', '3', '2'), - // name: "rg1616", - // }, - // Format { - // id: fourcc_code('G', 'R', '3', '2'), - // name: "gr1616", - // }, - // Format { - // id: fourcc_code('R', 'G', 'B', '8'), - // name: "rgb332", - // }, - // Format { - // id: fourcc_code('B', 'G', 'R', '8'), - // name: "bgr233", - // }, - // Format { - // id: fourcc_code('X', 'R', '1', '2'), - // name: "xrgb4444", - // }, - // Format { - // id: fourcc_code('X', 'B', '1', '2'), - // name: "xbgr4444", - // }, - // Format { - // id: fourcc_code('R', 'X', '1', '2'), - // name: "rgbx4444", - // }, - // Format { - // id: fourcc_code('B', 'X', '1', '2'), - // name: "bgrx4444", - // }, - // Format { - // id: fourcc_code('A', 'R', '1', '2'), - // name: "argb4444", - // }, - // Format { - // id: fourcc_code('A', 'B', '1', '2'), - // name: "abgr4444", - // }, - // Format { - // id: fourcc_code('R', 'A', '1', '2'), - // name: "rgba4444", - // }, - // Format { - // id: fourcc_code('B', 'A', '1', '2'), - // name: "bgra4444", - // }, - // Format { - // id: fourcc_code('X', 'R', '1', '5'), - // name: "xrgb1555", - // }, - // Format { - // id: fourcc_code('X', 'B', '1', '5'), - // name: "xbgr1555", - // }, - // Format { - // id: fourcc_code('R', 'X', '1', '5'), - // name: "rgbx5551", - // }, - // Format { - // id: fourcc_code('B', 'X', '1', '5'), - // name: "bgrx5551", - // }, - // Format { - // id: fourcc_code('A', 'R', '1', '5'), - // name: "argb1555", - // }, - // Format { - // id: fourcc_code('A', 'B', '1', '5'), - // name: "abgr1555", - // }, - // Format { - // id: fourcc_code('R', 'A', '1', '5'), - // name: "rgba5551", - // }, - // Format { - // id: fourcc_code('B', 'A', '1', '5'), - // name: "bgra5551", - // }, - // Format { - // id: fourcc_code('R', 'G', '1', '6'), - // name: "rgb565", - // }, - // Format { - // id: fourcc_code('B', 'G', '1', '6'), - // name: "bgr565", - // }, - // Format { - // id: fourcc_code('R', 'G', '2', '4'), - // name: "rgb888", - // }, - // Format { - // id: fourcc_code('B', 'G', '2', '4'), - // name: "bgr888", - // }, - // Format { - // id: fourcc_code('X', 'R', '2', '4'), - // name: "xrgb8888", - // }, - // Format { - // id: fourcc_code('X', 'B', '2', '4'), - // name: "xbgr8888", - // }, - // Format { - // id: fourcc_code('R', 'X', '2', '4'), - // name: "rgbx8888", - // }, - // Format { - // id: fourcc_code('B', 'X', '2', '4'), - // name: "bgrx8888", - // }, - // Format { - // id: fourcc_code('A', 'R', '2', '4'), - // name: "argb8888", - // }, - // Format { - // id: fourcc_code('A', 'B', '2', '4'), - // name: "abgr8888", - // }, - // Format { - // id: fourcc_code('R', 'A', '2', '4'), - // name: "rgba8888", - // }, - // Format { - // id: fourcc_code('B', 'A', '2', '4'), - // name: "bgra8888", - // }, - // Format { - // id: fourcc_code('X', 'R', '3', '0'), - // name: "xrgb2101010", - // }, - // Format { - // id: fourcc_code('X', 'B', '3', '0'), - // name: "xbgr2101010", - // }, - // Format { - // id: fourcc_code('R', 'X', '3', '0'), - // name: "rgbx1010102", - // }, - // Format { - // id: fourcc_code('B', 'X', '3', '0'), - // name: "bgrx1010102", - // }, - // Format { - // id: fourcc_code('A', 'R', '3', '0'), - // name: "argb2101010", - // }, - // Format { - // id: fourcc_code('A', 'B', '3', '0'), - // name: "abgr2101010", - // }, - // Format { - // id: fourcc_code('R', 'A', '3', '0'), - // name: "rgba1010102", - // }, - // Format { - // id: fourcc_code('B', 'A', '3', '0'), - // name: "bgra1010102", - // }, - // Format { - // id: fourcc_code('X', 'R', '4', '8'), - // name: "xrgb16161616", - // }, - // Format { - // id: fourcc_code('X', 'B', '4', '8'), - // name: "xbgr16161616", - // }, - // Format { - // id: fourcc_code('A', 'R', '4', '8'), - // name: "argb16161616", - // }, - // Format { - // id: fourcc_code('A', 'B', '4', '8'), - // name: "abgr16161616", - // }, - // Format { - // id: fourcc_code('X', 'R', '4', 'H'), - // name: "xrgb16161616f", - // }, - // Format { - // id: fourcc_code('X', 'B', '4', 'H'), - // name: "xbgr16161616f", - // }, - // Format { - // id: fourcc_code('A', 'R', '4', 'H'), - // name: "argb16161616f", - // }, - // Format { - // id: fourcc_code('A', 'B', '4', 'H'), - // name: "abgr16161616f", - // }, - // Format { - // id: fourcc_code('A', 'B', '1', '0'), - // name: "axbxgxrx106106106106", - // }, - // Format { - // id: fourcc_code('Y', 'U', 'Y', 'V'), - // name: "yuyv", - // }, - // Format { - // id: fourcc_code('Y', 'V', 'Y', 'U'), - // name: "yvyu", - // }, - // Format { - // id: fourcc_code('U', 'Y', 'V', 'Y'), - // name: "uyvy", - // }, - // Format { - // id: fourcc_code('V', 'Y', 'U', 'Y'), - // name: "vyuy", - // }, - // Format { - // id: fourcc_code('A', 'Y', 'U', 'V'), - // name: "ayuv", - // }, - // Format { - // id: fourcc_code('X', 'Y', 'U', 'V'), - // name: "xyuv8888", - // }, - // Format { - // id: fourcc_code('V', 'U', '2', '4'), - // name: "vuy888", - // }, - // Format { - // id: fourcc_code('V', 'U', '3', '0'), - // name: "vuy101010", - // }, - // Format { - // id: fourcc_code('Y', '2', '1', '0'), - // name: "y210", - // }, - // Format { - // id: fourcc_code('Y', '2', '1', '2'), - // name: "y212", - // }, - // Format { - // id: fourcc_code('Y', '2', '1', '6'), - // name: "y216", - // }, - // Format { - // id: fourcc_code('Y', '4', '1', '0'), - // name: "y410", - // }, - // Format { - // id: fourcc_code('Y', '4', '1', '2'), - // name: "y412", - // }, - // Format { - // id: fourcc_code('Y', '4', '1', '6'), - // name: "y416", - // }, - // Format { - // id: fourcc_code('X', 'V', '3', '0'), - // name: "xvyu2101010", - // }, - // Format { - // id: fourcc_code('X', 'V', '3', '6'), - // name: "xvyu12_16161616", - // }, - // Format { - // id: fourcc_code('X', 'V', '4', '8'), - // name: "xvyu16161616", - // }, - // Format { - // id: fourcc_code('Y', '0', 'L', '0'), - // name: "y0l0", - // }, - // Format { - // id: fourcc_code('X', '0', 'L', '0'), - // name: "x0l0", - // }, - // Format { - // id: fourcc_code('Y', '0', 'L', '2'), - // name: "y0l2", - // }, - // Format { - // id: fourcc_code('X', '0', 'L', '2'), - // name: "x0l2", - // }, - // Format { - // id: fourcc_code('Y', 'U', '0', '8'), - // name: "yuv420_8bit", - // }, - // Format { - // id: fourcc_code('Y', 'U', '1', '0'), - // name: "yuv420_10bit", - // }, - // Format { - // id: fourcc_code('X', 'R', 'A', '8'), - // name: "xrgb8888_a8", - // }, - // Format { - // id: fourcc_code('X', 'B', 'A', '8'), - // name: "xbgr8888_a8", - // }, - // Format { - // id: fourcc_code('R', 'X', 'A', '8'), - // name: "rgbx8888_a8", - // }, - // Format { - // id: fourcc_code('B', 'X', 'A', '8'), - // name: "bgrx8888_a8", - // }, - // Format { - // id: fourcc_code('R', '8', 'A', '8'), - // name: "rgb888_a8", - // }, - // Format { - // id: fourcc_code('B', '8', 'A', '8'), - // name: "bgr888_a8", - // }, - // Format { - // id: fourcc_code('R', '5', 'A', '8'), - // name: "rgb565_a8", - // }, - // Format { - // id: fourcc_code('B', '5', 'A', '8'), - // name: "bgr565_a8", - // }, - // Format { - // id: fourcc_code('N', 'V', '1', '2'), - // name: "nv12", - // }, - // Format { - // id: fourcc_code('N', 'V', '2', '1'), - // name: "nv21", - // }, - // Format { - // id: fourcc_code('N', 'V', '1', '6'), - // name: "nv16", - // }, - // Format { - // id: fourcc_code('N', 'V', '6', '1'), - // name: "nv61", - // }, - // Format { - // id: fourcc_code('N', 'V', '2', '4'), - // name: "nv24", - // }, - // Format { - // id: fourcc_code('N', 'V', '4', '2'), - // name: "nv42", - // }, - // Format { - // id: fourcc_code('N', 'V', '1', '5'), - // name: "nv15", - // }, - // Format { - // id: fourcc_code('P', '2', '1', '0'), - // name: "p210", - // }, - // Format { - // id: fourcc_code('P', '0', '1', '0'), - // name: "p010", - // }, - // Format { - // id: fourcc_code('P', '0', '1', '2'), - // name: "p012", - // }, - // Format { - // id: fourcc_code('P', '0', '1', '6'), - // name: "p016", - // }, - // Format { - // id: fourcc_code('Q', '4', '1', '0'), - // name: "q410", - // }, - // Format { - // id: fourcc_code('Q', '4', '0', '1'), - // name: "q401", - // }, - // Format { - // id: fourcc_code('Y', 'U', 'V', '9'), - // name: "yuv410", - // }, - // Format { - // id: fourcc_code('Y', 'V', 'U', '9'), - // name: "yvu410", - // }, - // Format { - // id: fourcc_code('Y', 'U', '1', '1'), - // name: "yuv411", - // }, - // Format { - // id: fourcc_code('Y', 'V', '1', '1'), - // name: "yvu411", - // }, - // Format { - // id: fourcc_code('Y', 'U', '1', '2'), - // name: "yuv420", - // }, - // Format { - // id: fourcc_code('Y', 'V', '1', '2'), - // name: "yvu420", - // }, - // Format { - // id: fourcc_code('Y', 'U', '1', '6'), - // name: "yuv422", - // }, - // Format { - // id: fourcc_code('Y', 'V', '1', '6'), - // name: "yvu422", - // }, - // Format { - // id: fourcc_code('Y', 'U', '2', '4'), - // name: "yuv444", - // }, - // Format { - // id: fourcc_code('Y', 'V', '2', '4'), - // name: "yvu444", - // }, + *R8, + *GR88, + *RGB888, + *BGR888, + #[cfg(target_endian = "little")] + *RGBA4444, + #[cfg(target_endian = "little")] + *RGBX4444, + #[cfg(target_endian = "little")] + *BGRA4444, + #[cfg(target_endian = "little")] + *BGRX4444, + #[cfg(target_endian = "little")] + *RGB565, + #[cfg(target_endian = "little")] + *BGR565, + #[cfg(target_endian = "little")] + *RGBA5551, + #[cfg(target_endian = "little")] + *RGBX5551, + #[cfg(target_endian = "little")] + *BGRA5551, + #[cfg(target_endian = "little")] + *BGRX5551, + #[cfg(target_endian = "little")] + *ARGB1555, + #[cfg(target_endian = "little")] + *XRGB1555, + #[cfg(target_endian = "little")] + *ARGB2101010, + #[cfg(target_endian = "little")] + *XRGB2101010, + #[cfg(target_endian = "little")] + *ABGR2101010, + #[cfg(target_endian = "little")] + *XBGR2101010, + #[cfg(target_endian = "little")] + *ABGR16161616, + #[cfg(target_endian = "little")] + *XBGR16161616, + #[cfg(target_endian = "little")] + *ABGR16161616F, + #[cfg(target_endian = "little")] + *XBGR16161616F, ]; diff --git a/src/gfx_apis/gl.rs b/src/gfx_apis/gl.rs index b2395573..e18af215 100644 --- a/src/gfx_apis/gl.rs +++ b/src/gfx_apis/gl.rs @@ -190,6 +190,8 @@ enum RenderError { ExportSyncFile, #[error("Could not insert wait for EGLSyncKHR")] WaitSync, + #[error("Buffer format {0} is not supported for shm buffers in OpenGL context")] + UnsupportedShmFormat(&'static str), } #[derive(Default)] diff --git a/src/gfx_apis/gl/gl/render_buffer.rs b/src/gfx_apis/gl/gl/render_buffer.rs index db15c6f9..545a746b 100644 --- a/src/gfx_apis/gl/gl/render_buffer.rs +++ b/src/gfx_apis/gl/gl/render_buffer.rs @@ -32,11 +32,14 @@ impl GlRenderBuffer { height: i32, format: &'static Format, ) -> Result, RenderError> { + let Some(shm_info) = &format.shm_info else { + return Err(RenderError::UnsupportedShmFormat(format.name)); + }; let gles = &ctx.dpy.gles; let mut rbo = 0; (gles.glGenRenderbuffers)(1, &mut rbo); (gles.glBindRenderbuffer)(GL_RENDERBUFFER, rbo); - (gles.glRenderbufferStorage)(GL_RENDERBUFFER, format.gl_internal_format, width, height); + (gles.glRenderbufferStorage)(GL_RENDERBUFFER, shm_info.gl_internal_format, width, height); (gles.glBindRenderbuffer)(GL_RENDERBUFFER, 0); Ok(Rc::new(GlRenderBuffer { _img: None, diff --git a/src/gfx_apis/gl/gl/texture.rs b/src/gfx_apis/gl/gl/texture.rs index fa006579..c1c5e943 100644 --- a/src/gfx_apis/gl/gl/texture.rs +++ b/src/gfx_apis/gl/gl/texture.rs @@ -73,6 +73,9 @@ impl GlTexture { height: i32, stride: i32, ) -> Result { + let Some(shm_info) = &format.shm_info else { + return Err(RenderError::UnsupportedShmFormat(format.name)); + }; if (stride * height) as usize > data.len() { return Err(RenderError::SmallImageBuffer); } @@ -83,16 +86,16 @@ impl GlTexture { (gles.glBindTexture)(GL_TEXTURE_2D, tex); (gles.glTexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); (gles.glTexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - (gles.glPixelStorei)(GL_UNPACK_ROW_LENGTH_EXT, stride / format.bpp as GLint); + (gles.glPixelStorei)(GL_UNPACK_ROW_LENGTH_EXT, stride / shm_info.bpp as GLint); (gles.glTexImage2D)( GL_TEXTURE_2D, 0, - format.gl_format, + shm_info.gl_format, width, height, 0, - format.gl_format as _, - format.gl_type as _, + shm_info.gl_format as _, + shm_info.gl_type as _, data.as_ptr() as _, ); (gles.glPixelStorei)(GL_UNPACK_ROW_LENGTH_EXT, 0); diff --git a/src/gfx_apis/gl/renderer/framebuffer.rs b/src/gfx_apis/gl/renderer/framebuffer.rs index 8a2eea1e..41a104ac 100644 --- a/src/gfx_apis/gl/renderer/framebuffer.rs +++ b/src/gfx_apis/gl/renderer/framebuffer.rs @@ -43,7 +43,10 @@ impl Framebuffer { height: i32, format: &Format, shm: &[Cell], - ) { + ) -> Result<(), RenderError> { + let Some(shm_info) = &format.shm_info else { + return Err(RenderError::UnsupportedShmFormat(format.name)); + }; let gles = self.ctx.ctx.dpy.gles; let y = self.gl.height - y - height; let _ = self.ctx.ctx.with_current(|| { @@ -55,14 +58,15 @@ impl Framebuffer { y, width, height, - format.gl_format as _, - format.gl_type as _, + shm_info.gl_format as _, + shm_info.gl_type as _, shm.len() as _, shm.as_ptr() as _, ); } Ok(()) }); + Ok(()) } pub fn render( @@ -126,8 +130,9 @@ impl GfxFramebuffer for Framebuffer { format: &'static Format, shm: &[Cell], ) -> Result<(), GfxError> { - (*self).copy_to_shm(x, y, width, height, format, shm); - Ok(()) + (*self) + .copy_to_shm(x, y, width, height, format, shm) + .map_err(|e| e.into()) } fn format(&self) -> &'static Format { diff --git a/src/gfx_apis/gl/renderer/texture.rs b/src/gfx_apis/gl/renderer/texture.rs index 7ef887e1..003fe6be 100644 --- a/src/gfx_apis/gl/renderer/texture.rs +++ b/src/gfx_apis/gl/renderer/texture.rs @@ -70,8 +70,8 @@ impl GfxTexture for Texture { shm: &[Cell], ) -> Result<(), GfxError> { self.to_framebuffer()? - .copy_to_shm(x, y, width, height, format, shm); - Ok(()) + .copy_to_shm(x, y, width, height, format, shm) + .map_err(|e| e.into()) } fn dmabuf(&self) -> Option<&DmaBuf> { diff --git a/src/gfx_apis/vulkan.rs b/src/gfx_apis/vulkan.rs index a23a232b..7468fc7b 100644 --- a/src/gfx_apis/vulkan.rs +++ b/src/gfx_apis/vulkan.rs @@ -175,6 +175,8 @@ pub enum VulkanError { }, #[error(transparent)] GfxError(GfxError), + #[error("Buffer format {0} is not supported for shm buffers in Vulkan context")] + UnsupportedShmFormat(&'static str), } impl From for GfxError { diff --git a/src/gfx_apis/vulkan/format.rs b/src/gfx_apis/vulkan/format.rs index cef95cef..79b03c34 100644 --- a/src/gfx_apis/vulkan/format.rs +++ b/src/gfx_apis/vulkan/format.rs @@ -130,6 +130,9 @@ impl VulkanInstance { format: &Format, props: &FormatProperties2, ) -> Result, VulkanError> { + if format.shm_info.is_none() { + return Ok(None); + } if !props .format_properties .optimal_tiling_features diff --git a/src/gfx_apis/vulkan/image.rs b/src/gfx_apis/vulkan/image.rs index ce09554e..0cbe6118 100644 --- a/src/gfx_apis/vulkan/image.rs +++ b/src/gfx_apis/vulkan/image.rs @@ -120,13 +120,16 @@ impl VulkanRenderer { data: &[Cell], for_download: bool, ) -> Result, VulkanError> { + let Some(shm_info) = &format.shm_info else { + return Err(VulkanError::UnsupportedShmFormat(format.name)); + }; if width <= 0 || height <= 0 || stride <= 0 { return Err(VulkanError::NonPositiveImageSize); } let width = width as u32; let height = height as u32; let stride = stride as u32; - if stride % format.bpp != 0 || stride / format.bpp < width { + if stride % shm_info.bpp != 0 || stride / shm_info.bpp < width { return Err(VulkanError::InvalidStride); } let vk_format = self diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index d1dc47d6..18fa6e14 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -294,9 +294,12 @@ impl VulkanRenderer { fn copy_shm_to_image(&self, cmd: CommandBuffer) { let memory = self.memory.borrow_mut(); for (img, staging) in &memory.flush_staging { + let Some(shm_info) = &img.format.shm_info else { + continue; + }; let cpy = BufferImageCopy2::builder() .buffer_image_height(img.height) - .buffer_row_length(img.stride / img.format.bpp) + .buffer_row_length(img.stride / shm_info.bpp) .image_extent(Extent3D { width: img.width, height: img.height, @@ -751,7 +754,10 @@ impl VulkanRenderer { stride: u32, dst: &[Cell], ) -> Result<(), VulkanError> { - if stride < tex.width * tex.format.bpp || stride % tex.format.bpp != 0 { + let Some(shm_info) = &tex.format.shm_info else { + return Err(VulkanError::UnsupportedShmFormat(tex.format.name)); + }; + if stride < tex.width * shm_info.bpp || stride % shm_info.bpp != 0 { return Err(VulkanError::InvalidStride); } let size = stride as u64 * tex.height as u64; @@ -759,7 +765,7 @@ impl VulkanRenderer { return Err(VulkanError::InvalidBufferSize); } let region = BufferImageCopy::builder() - .buffer_row_length(stride / tex.format.bpp) + .buffer_row_length(stride / shm_info.bpp) .buffer_image_height(tex.height) .image_subresource(ImageSubresourceLayers { aspect_mask: ImageAspectFlags::COLOR, diff --git a/src/ifs/wl_buffer.rs b/src/ifs/wl_buffer.rs index 1e5a742f..e28f72f1 100644 --- a/src/ifs/wl_buffer.rs +++ b/src/ifs/wl_buffer.rs @@ -90,13 +90,16 @@ impl WlBuffer { format: &'static Format, mem: &Rc, ) -> Result { + let Some(shm_info) = &format.shm_info else { + return Err(WlBufferError::UnsupportedShmFormat(format.name)); + }; let bytes = stride as u64 * height as u64; let required = bytes + offset as u64; if required > mem.len() as u64 { return Err(WlBufferError::OutOfBounds); } let mem = mem.offset(offset); - let min_row_size = width as u64 * format.bpp as u64; + let min_row_size = width as u64 * shm_info.bpp as u64; if (stride as u64) < min_row_size { return Err(WlBufferError::StrideTooSmall); } @@ -270,6 +273,8 @@ pub enum WlBufferError { MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), + #[error("Buffer format {0} is not supported for shm buffers")] + UnsupportedShmFormat(&'static str), } efrom!(WlBufferError, ClientMemError); efrom!(WlBufferError, MsgParserError); diff --git a/src/ifs/wl_shm.rs b/src/ifs/wl_shm.rs index cc6b11dd..6ce90572 100644 --- a/src/ifs/wl_shm.rs +++ b/src/ifs/wl_shm.rs @@ -46,7 +46,7 @@ impl WlShmGlobal { track!(client, obj); client.add_client_obj(&obj)?; for format in FORMATS { - if format.shm_supported { + if format.shm_info.is_some() { client.event(Format { self_id: id, format: format.wl_id.unwrap_or(format.drm), diff --git a/src/ifs/wl_shm_pool.rs b/src/ifs/wl_shm_pool.rs index e4124c4d..cef57fdf 100644 --- a/src/ifs/wl_shm_pool.rs +++ b/src/ifs/wl_shm_pool.rs @@ -45,7 +45,7 @@ impl WlShmPool { let req: CreateBuffer = self.client.parse(self, parser)?; let drm_format = map_wayland_format_id(req.format); let format = match formats().get(&drm_format) { - Some(f) if f.shm_supported => *f, + Some(f) if f.shm_info.is_some() => *f, _ => return Err(WlShmPoolError::InvalidFormat(req.format)), }; if req.height < 0 || req.width < 0 || req.stride < 0 || req.offset < 0 {