1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 // Copyright 2018 Jacob Lifshay
4 use api_impl::{Device, Instance, PhysicalDevice, Queue};
6 use device_memory::DeviceMemory;
8 use sampler::SamplerYcbcrConversion;
9 use shader_module::ShaderModule;
11 use std::marker::PhantomData;
14 use std::ops::DerefMut;
15 use std::ptr::null_mut;
16 use std::ptr::NonNull;
17 use swapchain::Swapchain;
20 pub struct DispatchableType<T> {
21 loader_dispatch_ptr: usize,
25 impl<T> From<T> for DispatchableType<T> {
26 fn from(v: T) -> Self {
28 loader_dispatch_ptr: api::ICD_LOADER_MAGIC as usize,
34 impl<T> Deref for DispatchableType<T> {
36 fn deref(&self) -> &T {
41 impl<T> DerefMut for DispatchableType<T> {
42 fn deref_mut(&mut self) -> &mut T {
47 pub trait HandleAllocFree: Handle {
48 unsafe fn allocate<T: Into<Self::Value>>(v: T) -> Self {
49 Self::new(Some(NonNull::new_unchecked(Box::into_raw(Box::new(
53 unsafe fn free(self) {
54 Box::from_raw(self.get().unwrap().as_ptr());
58 pub trait Handle: Copy + Eq + fmt::Debug {
60 fn get(&self) -> Option<NonNull<Self::Value>>;
61 fn new(v: Option<NonNull<Self::Value>>) -> Self;
65 fn is_null(&self) -> bool {
68 fn take(&mut self) -> Self {
69 let retval = self.clone();
76 pub struct DispatchableHandle<T>(Option<NonNull<()>>, PhantomData<*mut DispatchableType<T>>);
78 impl<T> Clone for DispatchableHandle<T> {
79 fn clone(&self) -> Self {
80 DispatchableHandle(self.0, PhantomData)
84 impl<T> Copy for DispatchableHandle<T> {}
86 impl<T> Eq for DispatchableHandle<T> {}
88 impl<T> PartialEq for DispatchableHandle<T> {
89 fn eq(&self, rhs: &Self) -> bool {
94 impl<T> fmt::Debug for DispatchableHandle<T> {
95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96 f.debug_tuple("DispatchableHandle")
101 .unwrap_or(null_mut::<*mut ()>() as *mut _),
107 impl<T> Handle for DispatchableHandle<T> {
108 type Value = DispatchableType<T>;
109 fn get(&self) -> Option<NonNull<DispatchableType<T>>> {
110 unsafe { mem::transmute(self.0) }
112 fn new(v: Option<NonNull<DispatchableType<T>>>) -> Self {
113 unsafe { DispatchableHandle(mem::transmute(v), PhantomData) }
118 pub struct NondispatchableHandle<T>(u64, PhantomData<Option<NonNull<T>>>);
120 impl<T> Clone for NondispatchableHandle<T> {
121 fn clone(&self) -> Self {
122 NondispatchableHandle(self.0, PhantomData)
126 impl<T> Copy for NondispatchableHandle<T> {}
128 impl<T> Eq for NondispatchableHandle<T> {}
130 impl<T> PartialEq for NondispatchableHandle<T> {
131 fn eq(&self, rhs: &Self) -> bool {
136 impl<T> fmt::Debug for NondispatchableHandle<T> {
137 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138 f.debug_tuple("NondispatchableHandle")
139 .field(&self.get().map(|v| v.as_ptr()).unwrap_or(null_mut()))
144 impl<T> Handle for NondispatchableHandle<T> {
146 fn get(&self) -> Option<NonNull<T>> {
147 NonNull::new(self.0 as *mut T)
149 fn new(v: Option<NonNull<T>>) -> Self {
150 NondispatchableHandle(
151 v.map(|v| v.as_ptr()).unwrap_or(null_mut()) as u64,
157 pub struct OwnedHandle<T: HandleAllocFree>(NonNull<T::Value>);
159 impl<T: HandleAllocFree> OwnedHandle<T> {
160 pub fn new<I: Into<T::Value>>(v: I) -> Self {
161 unsafe { OwnedHandle(T::allocate(v).get().unwrap()) }
163 pub unsafe fn from(v: T) -> Option<Self> {
164 v.get().map(OwnedHandle)
166 pub unsafe fn take(self) -> T {
171 pub unsafe fn get_handle(&self) -> T {
176 impl<T: HandleAllocFree> Deref for OwnedHandle<T> {
177 type Target = T::Value;
178 fn deref(&self) -> &T::Value {
179 unsafe { &*self.0.as_ptr() }
183 impl<T: HandleAllocFree> DerefMut for OwnedHandle<T> {
184 fn deref_mut(&mut self) -> &mut T::Value {
185 unsafe { &mut *self.0.as_ptr() }
189 impl<T: HandleAllocFree> Drop for OwnedHandle<T> {
192 T::new(Some(self.0)).free();
197 impl<T: HandleAllocFree> fmt::Debug for OwnedHandle<T>
199 T::Value: fmt::Debug,
201 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
202 f.debug_tuple("OwnedHandle").field((*self).deref()).finish()
206 #[derive(Copy, Clone)]
208 pub struct SharedHandle<T: Handle>(NonNull<T::Value>);
210 impl<T: Handle> SharedHandle<T> {
211 pub unsafe fn from(v: T) -> Option<Self> {
212 v.get().map(SharedHandle)
214 pub unsafe fn take(self) -> T {
217 pub unsafe fn get_handle(&self) -> T {
220 pub fn into_nonnull(self) -> NonNull<T::Value> {
225 impl<T: Handle> Deref for SharedHandle<T> {
226 type Target = T::Value;
227 fn deref(&self) -> &T::Value {
228 unsafe { &*self.0.as_ptr() }
232 impl<T: Handle> fmt::Debug for SharedHandle<T>
234 T::Value: fmt::Debug,
236 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
237 f.debug_tuple("SharedHandle")
238 .field((*self).deref())
243 pub type VkInstance = DispatchableHandle<Instance>;
245 impl HandleAllocFree for VkInstance {}
247 pub type VkPhysicalDevice = DispatchableHandle<PhysicalDevice>;
249 impl HandleAllocFree for VkPhysicalDevice {}
251 pub type VkDevice = DispatchableHandle<Device>;
253 impl HandleAllocFree for VkDevice {}
255 pub type VkQueue = DispatchableHandle<Queue>;
257 impl HandleAllocFree for VkQueue {}
259 pub struct CommandBuffer {}
261 pub type VkCommandBuffer = DispatchableHandle<CommandBuffer>;
263 impl HandleAllocFree for VkCommandBuffer {}
265 pub struct Semaphore {}
267 pub type VkSemaphore = NondispatchableHandle<Semaphore>;
269 impl HandleAllocFree for VkSemaphore {}
273 pub type VkFence = NondispatchableHandle<Fence>;
275 impl HandleAllocFree for VkFence {}
277 pub type VkDeviceMemory = NondispatchableHandle<DeviceMemory>;
279 impl HandleAllocFree for VkDeviceMemory {}
281 pub type VkBuffer = NondispatchableHandle<Buffer>;
283 impl HandleAllocFree for VkBuffer {}
287 pub type VkImage = NondispatchableHandle<Image>;
289 impl HandleAllocFree for VkImage {}
293 pub type VkEvent = NondispatchableHandle<Event>;
295 impl HandleAllocFree for VkEvent {}
297 pub struct QueryPool {}
299 pub type VkQueryPool = NondispatchableHandle<QueryPool>;
301 impl HandleAllocFree for VkQueryPool {}
303 pub struct BufferView {}
305 pub type VkBufferView = NondispatchableHandle<BufferView>;
307 impl HandleAllocFree for VkBufferView {}
309 pub struct ImageView {}
311 pub type VkImageView = NondispatchableHandle<ImageView>;
313 impl HandleAllocFree for VkImageView {}
315 pub type VkShaderModule = NondispatchableHandle<ShaderModule>;
317 impl HandleAllocFree for VkShaderModule {}
319 pub struct PipelineCache {}
321 pub type VkPipelineCache = NondispatchableHandle<PipelineCache>;
323 impl HandleAllocFree for VkPipelineCache {}
325 pub struct PipelineLayout {}
327 pub type VkPipelineLayout = NondispatchableHandle<PipelineLayout>;
329 impl HandleAllocFree for VkPipelineLayout {}
331 pub struct RenderPass {}
333 pub type VkRenderPass = NondispatchableHandle<RenderPass>;
335 impl HandleAllocFree for VkRenderPass {}
337 pub struct Pipeline {}
339 pub type VkPipeline = NondispatchableHandle<Pipeline>;
341 impl HandleAllocFree for VkPipeline {}
343 pub struct DescriptorSetLayout {}
345 pub type VkDescriptorSetLayout = NondispatchableHandle<DescriptorSetLayout>;
347 impl HandleAllocFree for VkDescriptorSetLayout {}
349 pub type VkSampler = NondispatchableHandle<Sampler>;
351 impl HandleAllocFree for VkSampler {}
353 pub struct DescriptorPool {}
355 pub type VkDescriptorPool = NondispatchableHandle<DescriptorPool>;
357 impl HandleAllocFree for VkDescriptorPool {}
359 pub struct DescriptorSet {}
361 pub type VkDescriptorSet = NondispatchableHandle<DescriptorSet>;
363 impl HandleAllocFree for VkDescriptorSet {}
365 pub struct Framebuffer {}
367 pub type VkFramebuffer = NondispatchableHandle<Framebuffer>;
369 impl HandleAllocFree for VkFramebuffer {}
371 pub struct CommandPool {}
373 pub type VkCommandPool = NondispatchableHandle<CommandPool>;
375 impl HandleAllocFree for VkCommandPool {}
377 pub type VkSamplerYcbcrConversion = NondispatchableHandle<SamplerYcbcrConversion>;
379 impl HandleAllocFree for VkSamplerYcbcrConversion {}
381 pub struct DescriptorUpdateTemplate {}
383 pub type VkDescriptorUpdateTemplate = NondispatchableHandle<DescriptorUpdateTemplate>;
385 impl HandleAllocFree for VkDescriptorUpdateTemplate {}
387 pub type VkSurfaceKHR = NondispatchableHandle<api::VkIcdSurfaceBase>;
389 // HandleAllocFree specifically not implemented for VkSurfaceKHR
391 pub type VkSwapchainKHR = NondispatchableHandle<Box<Swapchain>>;
393 impl HandleAllocFree for VkSwapchainKHR {}
395 pub struct DisplayKHR {}
397 pub type VkDisplayKHR = NondispatchableHandle<DisplayKHR>;
399 impl HandleAllocFree for VkDisplayKHR {}
401 pub struct DisplayModeKHR {}
403 pub type VkDisplayModeKHR = NondispatchableHandle<DisplayModeKHR>;
405 impl HandleAllocFree for VkDisplayModeKHR {}
407 pub struct DebugReportCallbackEXT {}
409 pub type VkDebugReportCallbackEXT = NondispatchableHandle<DebugReportCallbackEXT>;
411 impl HandleAllocFree for VkDebugReportCallbackEXT {}
413 pub struct DebugUtilsMessengerEXT {}
415 pub type VkDebugUtilsMessengerEXT = NondispatchableHandle<DebugUtilsMessengerEXT>;
417 impl HandleAllocFree for VkDebugUtilsMessengerEXT {}
419 pub struct ValidationCacheEXT {}
421 pub type VkValidationCacheEXT = NondispatchableHandle<ValidationCacheEXT>;
423 impl HandleAllocFree for VkValidationCacheEXT {}