smithay/backend/allocator/vulkan/format.rs
1//! Format conversions between Vulkan and DRM formats.
2
3/// Macro to generate format conversions between Vulkan and FourCC format codes.
4///
5/// Any entry in this table may have attributes associated with a conversion. This is needed for `PACK` Vulkan
6/// formats which may only have an alternative given a specific host endian.
7///
8/// See the module documentation for usage details.
9macro_rules! vk_format_table {
10 (
11 $(
12 // This meta specifier is used for format conversions for PACK formats.
13 $(#[$conv_meta:meta])*
14 $fourcc: ident => $vk: ident
15 ),* $(,)?
16 ) => {
17 /// Converts a FourCC format code to a Vulkan format code.
18 ///
19 /// This will return [`None`] if the format is not known.
20 ///
21 /// These format conversions will return all known FourCC and Vulkan format conversions. However a
22 /// Vulkan implementation may not support some Vulkan format. One notable example of this are the
23 /// formats introduced in `VK_EXT_4444_formats`. The corresponding FourCC codes will return the
24 /// formats from `VK_EXT_4444_formats`, but the caller is responsible for testing that a Vulkan device
25 /// supports these formats.
26 pub const fn get_vk_format(fourcc: $crate::backend::allocator::Fourcc) -> Option<ash::vk::Format> {
27 // FIXME: Use reexport for ash::vk::Format
28 match fourcc {
29 $(
30 $(#[$conv_meta])*
31 $crate::backend::allocator::Fourcc::$fourcc => Some(ash::vk::Format::$vk),
32 )*
33
34 _ => None,
35 }
36 }
37
38 /// Returns all the known format conversions.
39 ///
40 /// The list contains FourCC format codes that may be converted using [`get_vk_format`].
41 pub const fn known_formats() -> &'static [$crate::backend::allocator::Fourcc] {
42 &[
43 $(
44 $crate::backend::allocator::Fourcc::$fourcc
45 ),*
46 ]
47 }
48 };
49}
50
51// FIXME: SRGB format is not always correct.
52//
53// Vulkan classifies formats by both channel sizes and colorspace. FourCC format codes do not classify formats
54// based on colorspace.
55//
56// To implement this correctly, it is likely that parsing vulkan.xml and classifying families of colorspaces
57// would be needed since there are a lot of formats.
58//
59// Many of these conversions come from wsi_common_wayland.c in Mesa
60vk_format_table! {
61 Argb8888 => B8G8R8A8_SRGB,
62 Xrgb8888 => B8G8R8A8_SRGB,
63
64 Abgr8888 => R8G8B8A8_SRGB,
65 Xbgr8888 => R8G8B8A8_SRGB,
66
67 // PACK32 formats are equivalent to u32 instead of [u8; 4] and thus depend their layout depends the host
68 // endian.
69 #[cfg(target_endian = "little")]
70 Rgba8888 => A8B8G8R8_SRGB_PACK32,
71 #[cfg(target_endian = "little")]
72 Rgbx8888 => A8B8G8R8_SRGB_PACK32,
73
74 #[cfg(target_endian = "little")]
75 Argb2101010 => A2R10G10B10_UNORM_PACK32,
76 #[cfg(target_endian = "little")]
77 Xrgb2101010 => A2R10G10B10_UNORM_PACK32,
78
79 #[cfg(target_endian = "little")]
80 Abgr2101010 => A2B10G10R10_UNORM_PACK32,
81 #[cfg(target_endian = "little")]
82 Xbgr2101010 => A2B10G10R10_UNORM_PACK32,
83}