vulkanite/vk/
custom.rs

1//! Some custom Vulkan types which are implemented as Quality-Of-Life improvements over the existing ones
2use std::ffi::c_char;
3use std::ffi::{c_void, CStr};
4
5// to remove
6pub(crate) type VoidPtr = *const c_void;
7pub(crate) type FuncPtr = *const ();
8
9#[repr(u32)]
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkBool32.html>
12///
13/// According to the Vulkan specification:
14/// - All values returned from a Vulkan implementation in a VkBool32 will be either VK_TRUE or VK_FALSE.
15/// - Applications must not pass any other values than VK_TRUE or VK_FALSE into a Vulkan implementation where a VkBool32 is expected.
16pub enum Bool32 {
17    False = 0,
18    True = 1,
19}
20
21pub const TRUE: Bool32 = Bool32::True;
22pub const FALSE: Bool32 = Bool32::False;
23
24impl Default for Bool32 {
25    fn default() -> Self {
26        Self::False
27    }
28}
29
30impl From<bool> for Bool32 {
31    fn from(value: bool) -> Self {
32        match value {
33            true => Self::True,
34            false => Self::False,
35        }
36    }
37}
38
39impl From<Bool32> for bool {
40    fn from(value: Bool32) -> bool {
41        match value {
42            Bool32::True => true,
43            Bool32::False => false,
44        }
45    }
46}
47
48/// API Version used by Vulkan
49#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
50#[repr(transparent)]
51pub struct ApiVersion(u32);
52
53impl From<u32> for ApiVersion {
54    fn from(value: u32) -> Self {
55        Self(value)
56    }
57}
58
59impl Into<u32> for ApiVersion {
60    fn into(self) -> u32 {
61        self.0
62    }
63}
64
65impl ApiVersion {
66    pub const fn new(variant: u32, major: u32, minor: u32, patch: u32) -> Self {
67        assert!(variant < 8);
68        assert!(major < 128);
69        assert!(minor < 1024);
70        assert!(patch < 4096);
71        Self((variant << 29) | (major << 22) | (minor << 12) | patch)
72    }
73
74    pub const fn variant(self) -> u32 {
75        self.0 >> 29
76    }
77
78    pub const fn major(self) -> u32 {
79        (self.0 >> 22) & 0x7F
80    }
81
82    pub const fn minor(self) -> u32 {
83        (self.0 >> 12) & 0x3FF
84    }
85
86    pub const fn patch(self) -> u32 {
87        self.0 & 0xFFF
88    }
89}
90
91pub const API_VERSION_1_0: ApiVersion = ApiVersion::new(0, 1, 0, 0);
92#[cfg(feature = "version_1_1")]
93pub const API_VERSION_1_1: ApiVersion = ApiVersion::new(0, 1, 1, 0);
94#[cfg(feature = "version_1_2")]
95pub const API_VERSION_1_2: ApiVersion = ApiVersion::new(0, 1, 2, 0);
96#[cfg(feature = "version_1_3")]
97pub const API_VERSION_1_3: ApiVersion = ApiVersion::new(0, 1, 3, 0);
98#[cfg(feature = "version_1_4")]
99pub const API_VERSION_1_4: ApiVersion = ApiVersion::new(0, 1, 4, 0);
100
101impl Default for ApiVersion {
102    /// According to the doc, using an api version of 0 (default) is the same as using API_VERSION_1_0
103    fn default() -> Self {
104        API_VERSION_1_0
105    }
106}
107
108impl std::fmt::Display for ApiVersion {
109    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110        write!(f, "{}.{}.{}", self.major(), self.minor(), self.patch())
111    }
112}
113
114impl std::fmt::Debug for ApiVersion {
115    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116        f.debug_struct("ApiVersion")
117            .field("variant", &self.variant())
118            .field("major", &self.major())
119            .field("minor", &self.minor())
120            .field("patch", &self.patch())
121            .finish()
122    }
123}
124
125macro_rules! extension_name_decl {
126    ($name:ident) => {
127        #[derive(Clone, Copy)]
128        #[repr(transparent)]
129        pub struct $name(*const c_char);
130
131        impl $name {
132            /// Safety: name must live at least as long as the resulting object
133            /// This name must also be a valid instance/device extension name
134            pub const unsafe fn new(name: &CStr) -> Self {
135                Self(name.as_ptr())
136            }
137
138            pub fn get(&self) -> &CStr {
139                unsafe { CStr::from_ptr(self.0) }
140            }
141        }
142
143        impl PartialEq for $name {
144            fn eq(&self, other: &Self) -> bool {
145                self.get() == other.get()
146            }
147        }
148
149        impl Eq for $name {}
150
151        impl PartialOrd for $name {
152            fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
153                self.get().partial_cmp(other.get())
154            }
155        }
156
157        impl Ord for $name {
158            fn cmp(&self, other: &Self) -> std::cmp::Ordering {
159                self.get().cmp(other.get())
160            }
161        }
162
163        impl std::fmt::Debug for $name {
164            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165                self.get().fmt(f)
166            }
167        }
168
169        impl std::hash::Hash for $name {
170            fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
171                self.get().hash(state)
172            }
173        }
174    };
175}
176
177extension_name_decl!(InstanceExtensionName);
178extension_name_decl!(DeviceExtensionName);
179
180#[derive(Clone, PartialEq, Debug, Hash)]
181pub struct InstanceExtension {
182    pub name: InstanceExtensionName,
183    pub spec: u32,
184}
185
186#[derive(Clone, PartialEq, Debug, Hash)]
187pub struct DeviceExtension {
188    pub name: DeviceExtensionName,
189    pub spec: u32,
190}
191
192/// Replacement for PFN_vkDebugUtilsMessengerCallbackEXT (<https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/PFN_vkDebugUtilsMessengerCallbackEXT.html>)
193///
194/// Used by [vk::DebugUtilsMessengerCreateInfoEXT]
195#[cfg(feature = "ext_debug_utils")]
196pub type DebugUtilsMessengerCallbackEXT = Option<
197    extern "system" fn(
198        crate::vk::DebugUtilsMessageSeverityFlagsEXT,
199        crate::vk::DebugUtilsMessageTypeFlagsEXT,
200        &crate::vk::DebugUtilsMessengerCallbackDataEXT,
201        *const (),
202    ) -> Bool32,
203>;