1
0
Fork 0
forked from wry/wry

Merge pull request #148 from mahkoh/jorth/10-bit

render: add support for more formats
This commit is contained in:
mahkoh 2024-04-04 09:33:16 +02:00 committed by GitHub
commit a2c907c8c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 348 additions and 491 deletions

View file

@ -2,8 +2,12 @@ use {
crate::{ crate::{
gfx_apis::gl::sys::{GLenum, GLint, GL_BGRA_EXT, GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE}, gfx_apis::gl::sys::{GLenum, GLint, GL_BGRA_EXT, GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE},
pipewire::pw_pod::{ pipewire::pw_pod::{
SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx, SpaVideoFormat, SPA_VIDEO_FORMAT_BGRA, SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx, SPA_VIDEO_FORMAT_xBGR_210LE,
SPA_VIDEO_FORMAT_RGBA, 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, utils::debug_fn::debug_fn,
}, },
@ -13,21 +17,39 @@ use {
std::fmt::{Debug, Write}, std::fmt::{Debug, Write},
}; };
#[derive(Copy, Clone, Debug, Eq)] #[derive(Copy, Clone, Debug)]
pub struct Format { pub struct FormatShmInfo {
pub name: &'static str,
pub bpp: u32, pub bpp: u32,
pub gl_format: GLint, pub gl_format: GLint,
pub gl_internal_format: GLenum, pub gl_internal_format: GLenum,
pub gl_type: GLint, pub gl_type: GLint,
}
#[derive(Copy, Clone, Debug)]
pub struct Format {
pub name: &'static str,
pub vk_format: vk::Format, pub vk_format: vk::Format,
pub drm: u32, pub drm: u32,
pub wl_id: Option<u32>, pub wl_id: Option<u32>,
pub external_only_guess: bool, pub external_only_guess: bool,
pub has_alpha: bool, pub has_alpha: bool,
pub shm_supported: bool,
pub pipewire: SpaVideoFormat, pub pipewire: SpaVideoFormat,
pub opaque: Option<&'static Format>, pub opaque: Option<&'static Format>,
pub shm_info: Option<FormatShmInfo>,
}
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 { impl PartialEq for Format {
@ -36,6 +58,8 @@ impl PartialEq for Format {
} }
} }
impl Eq for Format {}
static FORMATS_MAP: Lazy<AHashMap<u32, &'static Format>> = Lazy::new(|| { static FORMATS_MAP: Lazy<AHashMap<u32, &'static Format>> = Lazy::new(|| {
let mut map = AHashMap::new(); let mut map = AHashMap::new();
for format in FORMATS { for format in FORMATS {
@ -91,514 +115,315 @@ pub fn map_wayland_format_id(id: u32) -> u32 {
pub static ARGB8888: &Format = &Format { pub static ARGB8888: &Format = &Format {
name: "argb8888", name: "argb8888",
bpp: 4, shm_info: Some(FormatShmInfo {
gl_format: GL_BGRA_EXT, bpp: 4,
gl_internal_format: GL_RGBA8, gl_format: GL_BGRA_EXT,
gl_type: GL_UNSIGNED_BYTE, gl_internal_format: GL_RGBA8,
gl_type: GL_UNSIGNED_BYTE,
}),
vk_format: vk::Format::B8G8R8A8_UNORM, vk_format: vk::Format::B8G8R8A8_UNORM,
drm: ARGB8888_DRM, drm: ARGB8888_DRM,
wl_id: Some(ARGB8888_ID), wl_id: Some(ARGB8888_ID),
external_only_guess: false, external_only_guess: false,
has_alpha: true, has_alpha: true,
shm_supported: true,
pipewire: SPA_VIDEO_FORMAT_BGRA, pipewire: SPA_VIDEO_FORMAT_BGRA,
opaque: Some(XRGB8888), opaque: Some(XRGB8888),
}; };
pub static XRGB8888: &Format = &Format { pub static XRGB8888: &Format = &Format {
name: "xrgb8888", name: "xrgb8888",
bpp: 4, shm_info: Some(FormatShmInfo {
gl_format: GL_BGRA_EXT, bpp: 4,
gl_internal_format: GL_RGBA8, gl_format: GL_BGRA_EXT,
gl_type: GL_UNSIGNED_BYTE, gl_internal_format: GL_RGBA8,
gl_type: GL_UNSIGNED_BYTE,
}),
vk_format: vk::Format::B8G8R8A8_UNORM, vk_format: vk::Format::B8G8R8A8_UNORM,
drm: XRGB8888_DRM, drm: XRGB8888_DRM,
wl_id: Some(XRGB8888_ID), wl_id: Some(XRGB8888_ID),
external_only_guess: false, external_only_guess: false,
has_alpha: false, has_alpha: false,
shm_supported: true,
pipewire: SPA_VIDEO_FORMAT_BGRx, pipewire: SPA_VIDEO_FORMAT_BGRx,
opaque: None, opaque: None,
}; };
static ABGR8888: &Format = &Format { static ABGR8888: &Format = &Format {
name: "abgr8888", name: "abgr8888",
bpp: 4, shm_info: Some(FormatShmInfo {
gl_format: GL_RGBA, bpp: 4,
gl_internal_format: GL_RGBA8, gl_format: GL_RGBA,
gl_type: GL_UNSIGNED_BYTE, gl_internal_format: GL_RGBA8,
gl_type: GL_UNSIGNED_BYTE,
}),
vk_format: vk::Format::R8G8B8A8_UNORM, vk_format: vk::Format::R8G8B8A8_UNORM,
drm: fourcc_code('A', 'B', '2', '4'), drm: fourcc_code('A', 'B', '2', '4'),
wl_id: None, wl_id: None,
external_only_guess: false, external_only_guess: false,
has_alpha: true, has_alpha: true,
shm_supported: true,
pipewire: SPA_VIDEO_FORMAT_RGBA, pipewire: SPA_VIDEO_FORMAT_RGBA,
opaque: Some(XBGR8888), opaque: Some(XBGR8888),
}; };
static XBGR8888: &Format = &Format { static XBGR8888: &Format = &Format {
name: "xbgr8888", name: "xbgr8888",
bpp: 4, shm_info: Some(FormatShmInfo {
gl_format: GL_RGBA, bpp: 4,
gl_internal_format: GL_RGBA8, gl_format: GL_RGBA,
gl_type: GL_UNSIGNED_BYTE, gl_internal_format: GL_RGBA8,
gl_type: GL_UNSIGNED_BYTE,
}),
vk_format: vk::Format::R8G8B8A8_UNORM, vk_format: vk::Format::R8G8B8A8_UNORM,
drm: fourcc_code('X', 'B', '2', '4'), drm: fourcc_code('X', 'B', '2', '4'),
wl_id: None, wl_id: None,
external_only_guess: false, external_only_guess: false,
has_alpha: false, has_alpha: false,
shm_supported: true,
pipewire: SPA_VIDEO_FORMAT_RGBx, pipewire: SPA_VIDEO_FORMAT_RGBx,
opaque: None, 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] = &[ pub static FORMATS: &[Format] = &[
*ARGB8888, *XRGB8888, *ABGR8888, *ARGB8888,
*XRGB8888,
*ABGR8888,
*XBGR8888, *XBGR8888,
// *NV12, *R8,
// Format { *GR88,
// name: "nv12", *RGB888,
// bpp: 1, // wrong but only used for shm *BGR888,
// gl_format: 0, // wrong but only used for shm #[cfg(target_endian = "little")]
// gl_type: GL_UNSIGNED_BYTE, // wrong but only used for shm *RGBA4444,
// drm: fourcc_code('N', 'V', '1', '2'), #[cfg(target_endian = "little")]
// wl_id: None, *RGBX4444,
// external_only_guess: true, #[cfg(target_endian = "little")]
// has_alpha: false, *BGRA4444,
// shm_supported: false, #[cfg(target_endian = "little")]
// pipewire: SPA_VIDEO_FORMAT_NV12, *BGRX4444,
// }, #[cfg(target_endian = "little")]
// Format { *RGB565,
// id: fourcc_code('C', '8', ' ', ' '), #[cfg(target_endian = "little")]
// name: "c8", *BGR565,
// }, #[cfg(target_endian = "little")]
// Format { *RGBA5551,
// id: fourcc_code('R', '8', ' ', ' '), #[cfg(target_endian = "little")]
// name: "r8", *RGBX5551,
// }, #[cfg(target_endian = "little")]
// Format { *BGRA5551,
// id: fourcc_code('R', '1', '6', ' '), #[cfg(target_endian = "little")]
// name: "r16", *BGRX5551,
// }, #[cfg(target_endian = "little")]
// Format { *ARGB1555,
// id: fourcc_code('R', 'G', '8', '8'), #[cfg(target_endian = "little")]
// name: "rg88", *XRGB1555,
// }, #[cfg(target_endian = "little")]
// Format { *ARGB2101010,
// id: fourcc_code('G', 'R', '8', '8'), #[cfg(target_endian = "little")]
// name: "gr88", *XRGB2101010,
// }, #[cfg(target_endian = "little")]
// Format { *ABGR2101010,
// id: fourcc_code('R', 'G', '3', '2'), #[cfg(target_endian = "little")]
// name: "rg1616", *XBGR2101010,
// }, #[cfg(target_endian = "little")]
// Format { *ABGR16161616,
// id: fourcc_code('G', 'R', '3', '2'), #[cfg(target_endian = "little")]
// name: "gr1616", *XBGR16161616,
// }, #[cfg(target_endian = "little")]
// Format { *ABGR16161616F,
// id: fourcc_code('R', 'G', 'B', '8'), #[cfg(target_endian = "little")]
// name: "rgb332", *XBGR16161616F,
// },
// 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",
// },
]; ];

View file

@ -190,6 +190,8 @@ enum RenderError {
ExportSyncFile, ExportSyncFile,
#[error("Could not insert wait for EGLSyncKHR")] #[error("Could not insert wait for EGLSyncKHR")]
WaitSync, WaitSync,
#[error("Buffer format {0} is not supported for shm buffers in OpenGL context")]
UnsupportedShmFormat(&'static str),
} }
#[derive(Default)] #[derive(Default)]

View file

@ -32,11 +32,14 @@ impl GlRenderBuffer {
height: i32, height: i32,
format: &'static Format, format: &'static Format,
) -> Result<Rc<GlRenderBuffer>, RenderError> { ) -> Result<Rc<GlRenderBuffer>, RenderError> {
let Some(shm_info) = &format.shm_info else {
return Err(RenderError::UnsupportedShmFormat(format.name));
};
let gles = &ctx.dpy.gles; let gles = &ctx.dpy.gles;
let mut rbo = 0; let mut rbo = 0;
(gles.glGenRenderbuffers)(1, &mut rbo); (gles.glGenRenderbuffers)(1, &mut rbo);
(gles.glBindRenderbuffer)(GL_RENDERBUFFER, 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); (gles.glBindRenderbuffer)(GL_RENDERBUFFER, 0);
Ok(Rc::new(GlRenderBuffer { Ok(Rc::new(GlRenderBuffer {
_img: None, _img: None,

View file

@ -73,6 +73,9 @@ impl GlTexture {
height: i32, height: i32,
stride: i32, stride: i32,
) -> Result<GlTexture, RenderError> { ) -> Result<GlTexture, RenderError> {
let Some(shm_info) = &format.shm_info else {
return Err(RenderError::UnsupportedShmFormat(format.name));
};
if (stride * height) as usize > data.len() { if (stride * height) as usize > data.len() {
return Err(RenderError::SmallImageBuffer); return Err(RenderError::SmallImageBuffer);
} }
@ -83,16 +86,16 @@ impl GlTexture {
(gles.glBindTexture)(GL_TEXTURE_2D, tex); (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_S, GL_CLAMP_TO_EDGE);
(gles.glTexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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)( (gles.glTexImage2D)(
GL_TEXTURE_2D, GL_TEXTURE_2D,
0, 0,
format.gl_format, shm_info.gl_format,
width, width,
height, height,
0, 0,
format.gl_format as _, shm_info.gl_format as _,
format.gl_type as _, shm_info.gl_type as _,
data.as_ptr() as _, data.as_ptr() as _,
); );
(gles.glPixelStorei)(GL_UNPACK_ROW_LENGTH_EXT, 0); (gles.glPixelStorei)(GL_UNPACK_ROW_LENGTH_EXT, 0);

View file

@ -43,7 +43,10 @@ impl Framebuffer {
height: i32, height: i32,
format: &Format, format: &Format,
shm: &[Cell<u8>], shm: &[Cell<u8>],
) { ) -> Result<(), RenderError> {
let Some(shm_info) = &format.shm_info else {
return Err(RenderError::UnsupportedShmFormat(format.name));
};
let gles = self.ctx.ctx.dpy.gles; let gles = self.ctx.ctx.dpy.gles;
let y = self.gl.height - y - height; let y = self.gl.height - y - height;
let _ = self.ctx.ctx.with_current(|| { let _ = self.ctx.ctx.with_current(|| {
@ -55,14 +58,15 @@ impl Framebuffer {
y, y,
width, width,
height, height,
format.gl_format as _, shm_info.gl_format as _,
format.gl_type as _, shm_info.gl_type as _,
shm.len() as _, shm.len() as _,
shm.as_ptr() as _, shm.as_ptr() as _,
); );
} }
Ok(()) Ok(())
}); });
Ok(())
} }
pub fn render( pub fn render(
@ -126,8 +130,9 @@ impl GfxFramebuffer for Framebuffer {
format: &'static Format, format: &'static Format,
shm: &[Cell<u8>], shm: &[Cell<u8>],
) -> Result<(), GfxError> { ) -> Result<(), GfxError> {
(*self).copy_to_shm(x, y, width, height, format, shm); (*self)
Ok(()) .copy_to_shm(x, y, width, height, format, shm)
.map_err(|e| e.into())
} }
fn format(&self) -> &'static Format { fn format(&self) -> &'static Format {

View file

@ -70,8 +70,8 @@ impl GfxTexture for Texture {
shm: &[Cell<u8>], shm: &[Cell<u8>],
) -> Result<(), GfxError> { ) -> Result<(), GfxError> {
self.to_framebuffer()? self.to_framebuffer()?
.copy_to_shm(x, y, width, height, format, shm); .copy_to_shm(x, y, width, height, format, shm)
Ok(()) .map_err(|e| e.into())
} }
fn dmabuf(&self) -> Option<&DmaBuf> { fn dmabuf(&self) -> Option<&DmaBuf> {

View file

@ -175,6 +175,8 @@ pub enum VulkanError {
}, },
#[error(transparent)] #[error(transparent)]
GfxError(GfxError), GfxError(GfxError),
#[error("Buffer format {0} is not supported for shm buffers in Vulkan context")]
UnsupportedShmFormat(&'static str),
} }
impl From<VulkanError> for GfxError { impl From<VulkanError> for GfxError {

View file

@ -130,6 +130,9 @@ impl VulkanInstance {
format: &Format, format: &Format,
props: &FormatProperties2, props: &FormatProperties2,
) -> Result<Option<VulkanShmFormat>, VulkanError> { ) -> Result<Option<VulkanShmFormat>, VulkanError> {
if format.shm_info.is_none() {
return Ok(None);
}
if !props if !props
.format_properties .format_properties
.optimal_tiling_features .optimal_tiling_features

View file

@ -120,13 +120,16 @@ impl VulkanRenderer {
data: &[Cell<u8>], data: &[Cell<u8>],
for_download: bool, for_download: bool,
) -> Result<Rc<VulkanImage>, VulkanError> { ) -> Result<Rc<VulkanImage>, VulkanError> {
let Some(shm_info) = &format.shm_info else {
return Err(VulkanError::UnsupportedShmFormat(format.name));
};
if width <= 0 || height <= 0 || stride <= 0 { if width <= 0 || height <= 0 || stride <= 0 {
return Err(VulkanError::NonPositiveImageSize); return Err(VulkanError::NonPositiveImageSize);
} }
let width = width as u32; let width = width as u32;
let height = height as u32; let height = height as u32;
let stride = stride 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); return Err(VulkanError::InvalidStride);
} }
let vk_format = self let vk_format = self

View file

@ -294,9 +294,12 @@ impl VulkanRenderer {
fn copy_shm_to_image(&self, cmd: CommandBuffer) { fn copy_shm_to_image(&self, cmd: CommandBuffer) {
let memory = self.memory.borrow_mut(); let memory = self.memory.borrow_mut();
for (img, staging) in &memory.flush_staging { for (img, staging) in &memory.flush_staging {
let Some(shm_info) = &img.format.shm_info else {
continue;
};
let cpy = BufferImageCopy2::builder() let cpy = BufferImageCopy2::builder()
.buffer_image_height(img.height) .buffer_image_height(img.height)
.buffer_row_length(img.stride / img.format.bpp) .buffer_row_length(img.stride / shm_info.bpp)
.image_extent(Extent3D { .image_extent(Extent3D {
width: img.width, width: img.width,
height: img.height, height: img.height,
@ -751,7 +754,10 @@ impl VulkanRenderer {
stride: u32, stride: u32,
dst: &[Cell<u8>], dst: &[Cell<u8>],
) -> Result<(), VulkanError> { ) -> 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); return Err(VulkanError::InvalidStride);
} }
let size = stride as u64 * tex.height as u64; let size = stride as u64 * tex.height as u64;
@ -759,7 +765,7 @@ impl VulkanRenderer {
return Err(VulkanError::InvalidBufferSize); return Err(VulkanError::InvalidBufferSize);
} }
let region = BufferImageCopy::builder() let region = BufferImageCopy::builder()
.buffer_row_length(stride / tex.format.bpp) .buffer_row_length(stride / shm_info.bpp)
.buffer_image_height(tex.height) .buffer_image_height(tex.height)
.image_subresource(ImageSubresourceLayers { .image_subresource(ImageSubresourceLayers {
aspect_mask: ImageAspectFlags::COLOR, aspect_mask: ImageAspectFlags::COLOR,

View file

@ -90,13 +90,16 @@ impl WlBuffer {
format: &'static Format, format: &'static Format,
mem: &Rc<ClientMem>, mem: &Rc<ClientMem>,
) -> Result<Self, WlBufferError> { ) -> Result<Self, WlBufferError> {
let Some(shm_info) = &format.shm_info else {
return Err(WlBufferError::UnsupportedShmFormat(format.name));
};
let bytes = stride as u64 * height as u64; let bytes = stride as u64 * height as u64;
let required = bytes + offset as u64; let required = bytes + offset as u64;
if required > mem.len() as u64 { if required > mem.len() as u64 {
return Err(WlBufferError::OutOfBounds); return Err(WlBufferError::OutOfBounds);
} }
let mem = mem.offset(offset); 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 { if (stride as u64) < min_row_size {
return Err(WlBufferError::StrideTooSmall); return Err(WlBufferError::StrideTooSmall);
} }
@ -270,6 +273,8 @@ pub enum WlBufferError {
MsgParserError(#[source] Box<MsgParserError>), MsgParserError(#[source] Box<MsgParserError>),
#[error(transparent)] #[error(transparent)]
ClientError(Box<ClientError>), ClientError(Box<ClientError>),
#[error("Buffer format {0} is not supported for shm buffers")]
UnsupportedShmFormat(&'static str),
} }
efrom!(WlBufferError, ClientMemError); efrom!(WlBufferError, ClientMemError);
efrom!(WlBufferError, MsgParserError); efrom!(WlBufferError, MsgParserError);

View file

@ -46,7 +46,7 @@ impl WlShmGlobal {
track!(client, obj); track!(client, obj);
client.add_client_obj(&obj)?; client.add_client_obj(&obj)?;
for format in FORMATS { for format in FORMATS {
if format.shm_supported { if format.shm_info.is_some() {
client.event(Format { client.event(Format {
self_id: id, self_id: id,
format: format.wl_id.unwrap_or(format.drm), format: format.wl_id.unwrap_or(format.drm),

View file

@ -45,7 +45,7 @@ impl WlShmPool {
let req: CreateBuffer = self.client.parse(self, parser)?; let req: CreateBuffer = self.client.parse(self, parser)?;
let drm_format = map_wayland_format_id(req.format); let drm_format = map_wayland_format_id(req.format);
let format = match formats().get(&drm_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)), _ => return Err(WlShmPoolError::InvalidFormat(req.format)),
}; };
if req.height < 0 || req.width < 0 || req.stride < 0 || req.offset < 0 { if req.height < 0 || req.width < 0 || req.stride < 0 || req.offset < 0 {