1use std::marker::PhantomData;
6use std::fmt;
7
8#[repr(transparent)]
10#[derive(Clone, Copy, PartialEq, Eq, Hash)]
11pub struct Handle<T> {
12 pub(crate) raw: u64,
13 pub(crate) _marker: PhantomData<*const T>,
14}
15
16impl<T> Handle<T> {
17 pub const NULL: Self = Self {
18 raw: 0,
19 _marker: PhantomData,
20 };
21
22 #[inline]
23 pub const fn from_raw(raw: u64) -> Self {
24 Self {
25 raw,
26 _marker: PhantomData,
27 }
28 }
29
30 #[inline]
31 pub const fn as_raw(&self) -> u64 {
32 self.raw
33 }
34
35 #[inline]
36 pub const fn is_null(&self) -> bool {
37 self.raw == 0
38 }
39}
40
41impl<T> fmt::Debug for Handle<T> {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 f.debug_struct("Handle")
44 .field("raw", &self.raw)
45 .field("_marker", &self._marker)
46 .finish()
47 }
48}
49
50unsafe impl<T> Send for Handle<T> {}
55unsafe impl<T> Sync for Handle<T> {}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
59pub enum InstanceT {}
60#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
61pub enum PhysicalDeviceT {}
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
63pub enum DeviceT {}
64#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
65pub enum QueueT {}
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
67pub enum CommandBufferT {}
68#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
69pub enum BufferT {}
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
71pub enum DeviceMemoryT {}
72#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
73pub enum PipelineT {}
74#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
75pub enum PipelineLayoutT {}
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
77pub enum ShaderModuleT {}
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
79pub enum DescriptorSetT {}
80#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
81pub enum DescriptorSetLayoutT {}
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
83pub enum DescriptorPoolT {}
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
85pub enum CommandPoolT {}
86#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
87pub enum FenceT {}
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
89pub enum SemaphoreT {}
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
91pub enum EventT {}
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
93pub enum PipelineCacheT {}
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
95pub enum SamplerT {}
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
97pub enum ImageViewT {}
98
99pub type VkInstance = Handle<InstanceT>;
101pub type VkPhysicalDevice = Handle<PhysicalDeviceT>;
102pub type VkDevice = Handle<DeviceT>;
103pub type VkQueue = Handle<QueueT>;
104pub type VkCommandBuffer = Handle<CommandBufferT>;
105pub type VkBuffer = Handle<BufferT>;
106pub type VkDeviceMemory = Handle<DeviceMemoryT>;
107pub type VkPipeline = Handle<PipelineT>;
108pub type VkPipelineLayout = Handle<PipelineLayoutT>;
109pub type VkShaderModule = Handle<ShaderModuleT>;
110pub type VkDescriptorSet = Handle<DescriptorSetT>;
111pub type VkDescriptorSetLayout = Handle<DescriptorSetLayoutT>;
112pub type VkDescriptorPool = Handle<DescriptorPoolT>;
113pub type VkCommandPool = Handle<CommandPoolT>;
114pub type VkFence = Handle<FenceT>;
115pub type VkSemaphore = Handle<SemaphoreT>;
116pub type VkEvent = Handle<EventT>;
117pub type VkPipelineCache = Handle<PipelineCacheT>;
118pub type VkSampler = Handle<SamplerT>;
119pub type VkImageView = Handle<ImageViewT>;
120
121pub type VkBool32 = u32;
123pub type VkFlags = u32;
124pub type VkDeviceSize = u64;
125
126pub const VK_TRUE: VkBool32 = 1;
128pub const VK_FALSE: VkBool32 = 0;
129pub const VK_WHOLE_SIZE: VkDeviceSize = !0;
130pub const VK_QUEUE_FAMILY_IGNORED: u32 = !0;
131
132pub const VK_MAX_PHYSICAL_DEVICE_NAME_SIZE: usize = 256;
134pub const VK_UUID_SIZE: usize = 16;
135pub const VK_MAX_MEMORY_HEAPS: usize = 16;
136pub const VK_MAX_MEMORY_TYPES: usize = 32;
137
138pub const VK_API_VERSION_1_0: u32 = (1 << 22) | (0 << 12) | 0;
140pub const VK_API_VERSION_1_1: u32 = (1 << 22) | (1 << 12) | 0;
141pub const VK_API_VERSION_1_2: u32 = (1 << 22) | (2 << 12) | 0;
142pub const VK_API_VERSION_1_3: u32 = (1 << 22) | (3 << 12) | 0;
143
144#[inline]
146pub const fn VK_MAKE_VERSION(major: u32, minor: u32, patch: u32) -> u32 {
147 (major << 22) | (minor << 12) | patch
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153
154 #[test]
155 fn test_handle_null() {
156 let handle: VkDevice = Handle::NULL;
157 assert!(handle.is_null());
158 assert_eq!(handle.as_raw(), 0);
159 }
160
161 #[test]
162 fn test_handle_creation() {
163 let handle: VkBuffer = Handle::from_raw(42);
164 assert!(!handle.is_null());
165 assert_eq!(handle.as_raw(), 42);
166 }
167
168 #[test]
169 fn test_handle_equality() {
170 let h1: VkPipeline = Handle::from_raw(123);
171 let h2: VkPipeline = Handle::from_raw(123);
172 let h3: VkPipeline = Handle::from_raw(456);
173
174 assert_eq!(h1, h2);
175 assert_ne!(h1, h3);
176 }
177
178 #[test]
179 fn test_handle_copy() {
180 let h1: VkQueue = Handle::from_raw(789);
181 let h2 = h1; assert_eq!(h1, h2);
183 assert_eq!(h1.as_raw(), h2.as_raw());
184 }
185
186 #[test]
187 fn test_constants() {
188 assert_eq!(VK_TRUE, 1);
189 assert_eq!(VK_FALSE, 0);
190 assert_eq!(VK_WHOLE_SIZE, u64::MAX);
191 assert_eq!(VK_QUEUE_FAMILY_IGNORED, u32::MAX);
192 }
193
194 #[test]
195 fn test_handle_debug() {
196 let handle: VkDevice = Handle::from_raw(999);
197 let debug_str = format!("{:?}", handle);
198 assert!(debug_str.contains("raw: 999"));
199 }
200}