vulkan_rust/version.rs
1use core::fmt;
2
3/// Bit offset for the major version component (bits 31-22).
4const MAJOR_SHIFT: u32 = 22;
5/// Bit offset for the minor version component (bits 21-12).
6const MINOR_SHIFT: u32 = 12;
7/// Bitmask for the minor version component (10 bits).
8const MINOR_MASK: u32 = 0x3FF;
9/// Bitmask for the patch version component (12 bits).
10const PATCH_MASK: u32 = 0xFFF;
11
12/// Decoded Vulkan API version (major.minor.patch).
13///
14/// Vulkan packs versions into a `u32`: major (bits 31-22), minor (21-12),
15/// patch (11-0). This type provides named fields and a `Display` impl.
16///
17/// # Examples
18///
19/// ```
20/// use vulkan_rust::Version;
21///
22/// let v = Version::from_raw(0x00403000);
23/// assert_eq!(v.to_string(), "1.3.0");
24/// assert_eq!(v.to_raw(), 0x00403000);
25/// ```
26#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
27pub struct Version {
28 /// Major version number (bits 31-22 of the packed `u32`).
29 pub major: u32,
30 /// Minor version number (bits 21-12 of the packed `u32`).
31 pub minor: u32,
32 /// Patch version number (bits 11-0 of the packed `u32`).
33 pub patch: u32,
34}
35
36impl Version {
37 /// Create a version from major, minor, and patch components.
38 ///
39 /// ```
40 /// use vulkan_rust::Version;
41 ///
42 /// let v = Version::new(1, 3, 0);
43 /// assert_eq!(v.to_raw(), 0x00403000);
44 /// assert_eq!(v.to_string(), "1.3.0");
45 /// ```
46 pub const fn new(major: u32, minor: u32, patch: u32) -> Self {
47 Self {
48 major,
49 minor,
50 patch,
51 }
52 }
53
54 /// Decode a packed Vulkan version `u32` into its components.
55 ///
56 /// ```
57 /// use vulkan_rust::Version;
58 ///
59 /// let v = Version::from_raw(0x00403000); // Vulkan 1.3.0
60 /// assert_eq!(v.major, 1);
61 /// assert_eq!(v.minor, 3);
62 /// assert_eq!(v.patch, 0);
63 /// ```
64 pub const fn from_raw(raw: u32) -> Self {
65 Self {
66 major: raw >> MAJOR_SHIFT,
67 minor: (raw >> MINOR_SHIFT) & MINOR_MASK,
68 patch: raw & PATCH_MASK,
69 }
70 }
71
72 /// Encode this version back into the packed `u32` representation.
73 ///
74 /// ```
75 /// use vulkan_rust::Version;
76 ///
77 /// let v = Version { major: 1, minor: 3, patch: 0 };
78 /// assert_eq!(v.to_raw(), 0x00403000);
79 /// ```
80 pub const fn to_raw(self) -> u32 {
81 (self.major << MAJOR_SHIFT) | (self.minor << MINOR_SHIFT) | self.patch
82 }
83}
84
85impl fmt::Display for Version {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn round_trip() {
97 let v = Version {
98 major: 1,
99 minor: 3,
100 patch: 250,
101 };
102 assert_eq!(Version::from_raw(v.to_raw()), v);
103 }
104
105 #[test]
106 fn from_raw_known_versions() {
107 // VK_API_VERSION_1_0 = VK_MAKE_API_VERSION(0, 1, 0, 0)
108 let v10 = Version::from_raw(Version::new(1, 0, 0).to_raw());
109 assert_eq!(
110 v10,
111 Version {
112 major: 1,
113 minor: 0,
114 patch: 0
115 }
116 );
117
118 // VK_API_VERSION_1_3 = 0x00403000
119 let v13 = Version::from_raw(0x00403000);
120 assert_eq!(
121 v13,
122 Version {
123 major: 1,
124 minor: 3,
125 patch: 0
126 }
127 );
128 }
129
130 #[test]
131 fn display_format() {
132 let v = Version {
133 major: 1,
134 minor: 2,
135 patch: 195,
136 };
137 assert_eq!(v.to_string(), "1.2.195");
138 }
139
140 #[test]
141 fn ordering() {
142 let v10 = Version {
143 major: 1,
144 minor: 0,
145 patch: 0,
146 };
147 let v12 = Version {
148 major: 1,
149 minor: 2,
150 patch: 0,
151 };
152 let v13 = Version {
153 major: 1,
154 minor: 3,
155 patch: 0,
156 };
157 assert!(v10 < v12);
158 assert!(v12 < v13);
159 }
160
161 #[test]
162 fn to_raw_known_versions() {
163 let v13 = Version {
164 major: 1,
165 minor: 3,
166 patch: 0,
167 };
168 assert_eq!(v13.to_raw(), 0x00403000);
169 }
170}