Skip to main content

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}