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 {
222 impl<T: Handle> Deref for SharedHandle<T> {
223 type Target = T::Value;
224 fn deref(&self) -> &T::Value {
225 unsafe { &*self.0.as_ptr() }
229 impl<T: Handle> fmt::Debug for SharedHandle<T>
231 T::Value: fmt::Debug,
233 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
234 f.debug_tuple("SharedHandle")
235 .field((*self).deref())
240 pub type VkInstance = DispatchableHandle<Instance>;
242 impl HandleAllocFree for VkInstance {}
244 pub type VkPhysicalDevice = DispatchableHandle<PhysicalDevice>;
246 impl HandleAllocFree for VkPhysicalDevice {}
248 pub type VkDevice = DispatchableHandle<Device>;
250 impl HandleAllocFree for VkDevice {}
252 pub type VkQueue = DispatchableHandle<Queue>;
254 impl HandleAllocFree for VkQueue {}
256 pub struct CommandBuffer {}
258 pub type VkCommandBuffer = DispatchableHandle<CommandBuffer>;
260 impl HandleAllocFree for VkCommandBuffer {}
262 pub struct Semaphore {}
264 pub type VkSemaphore = NondispatchableHandle<Semaphore>;
266 impl HandleAllocFree for VkSemaphore {}
270 pub type VkFence = NondispatchableHandle<Fence>;
272 impl HandleAllocFree for VkFence {}
274 pub type VkDeviceMemory = NondispatchableHandle<DeviceMemory>;
276 impl HandleAllocFree for VkDeviceMemory {}
278 pub type VkBuffer = NondispatchableHandle<Buffer>;
280 impl HandleAllocFree for VkBuffer {}
284 pub type VkImage = NondispatchableHandle<Image>;
286 impl HandleAllocFree for VkImage {}
290 pub type VkEvent = NondispatchableHandle<Event>;
292 impl HandleAllocFree for VkEvent {}
294 pub struct QueryPool {}
296 pub type VkQueryPool = NondispatchableHandle<QueryPool>;
298 impl HandleAllocFree for VkQueryPool {}
300 pub struct BufferView {}
302 pub type VkBufferView = NondispatchableHandle<BufferView>;
304 impl HandleAllocFree for VkBufferView {}
306 pub struct ImageView {}
308 pub type VkImageView = NondispatchableHandle<ImageView>;
310 impl HandleAllocFree for VkImageView {}
312 pub type VkShaderModule = NondispatchableHandle<ShaderModule>;
314 impl HandleAllocFree for VkShaderModule {}
316 pub struct PipelineCache {}
318 pub type VkPipelineCache = NondispatchableHandle<PipelineCache>;
320 impl HandleAllocFree for VkPipelineCache {}
322 pub struct PipelineLayout {}
324 pub type VkPipelineLayout = NondispatchableHandle<PipelineLayout>;
326 impl HandleAllocFree for VkPipelineLayout {}
328 pub struct RenderPass {}
330 pub type VkRenderPass = NondispatchableHandle<RenderPass>;
332 impl HandleAllocFree for VkRenderPass {}
334 pub struct Pipeline {}
336 pub type VkPipeline = NondispatchableHandle<Pipeline>;
338 impl HandleAllocFree for VkPipeline {}
340 pub struct DescriptorSetLayout {}
342 pub type VkDescriptorSetLayout = NondispatchableHandle<DescriptorSetLayout>;
344 impl HandleAllocFree for VkDescriptorSetLayout {}
346 pub type VkSampler = NondispatchableHandle<Sampler>;
348 impl HandleAllocFree for VkSampler {}
350 pub struct DescriptorPool {}
352 pub type VkDescriptorPool = NondispatchableHandle<DescriptorPool>;
354 impl HandleAllocFree for VkDescriptorPool {}
356 pub struct DescriptorSet {}
358 pub type VkDescriptorSet = NondispatchableHandle<DescriptorSet>;
360 impl HandleAllocFree for VkDescriptorSet {}
362 pub struct Framebuffer {}
364 pub type VkFramebuffer = NondispatchableHandle<Framebuffer>;
366 impl HandleAllocFree for VkFramebuffer {}
368 pub struct CommandPool {}
370 pub type VkCommandPool = NondispatchableHandle<CommandPool>;
372 impl HandleAllocFree for VkCommandPool {}
374 pub type VkSamplerYcbcrConversion = NondispatchableHandle<SamplerYcbcrConversion>;
376 impl HandleAllocFree for VkSamplerYcbcrConversion {}
378 pub struct DescriptorUpdateTemplate {}
380 pub type VkDescriptorUpdateTemplate = NondispatchableHandle<DescriptorUpdateTemplate>;
382 impl HandleAllocFree for VkDescriptorUpdateTemplate {}
384 pub type VkSurfaceKHR = NondispatchableHandle<api::VkIcdSurfaceBase>;
386 // HandleAllocFree specifically not implemented for VkSurfaceKHR
388 pub type VkSwapchainKHR = NondispatchableHandle<Box<Swapchain>>;
390 impl HandleAllocFree for VkSwapchainKHR {}
392 pub struct DisplayKHR {}
394 pub type VkDisplayKHR = NondispatchableHandle<DisplayKHR>;
396 impl HandleAllocFree for VkDisplayKHR {}
398 pub struct DisplayModeKHR {}
400 pub type VkDisplayModeKHR = NondispatchableHandle<DisplayModeKHR>;
402 impl HandleAllocFree for VkDisplayModeKHR {}
404 pub struct DebugReportCallbackEXT {}
406 pub type VkDebugReportCallbackEXT = NondispatchableHandle<DebugReportCallbackEXT>;
408 impl HandleAllocFree for VkDebugReportCallbackEXT {}
410 pub struct DebugUtilsMessengerEXT {}
412 pub type VkDebugUtilsMessengerEXT = NondispatchableHandle<DebugUtilsMessengerEXT>;
414 impl HandleAllocFree for VkDebugUtilsMessengerEXT {}
416 pub struct ValidationCacheEXT {}
418 pub type VkValidationCacheEXT = NondispatchableHandle<ValidationCacheEXT>;
420 impl HandleAllocFree for VkValidationCacheEXT {}