1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 // Copyright 2018 Jacob Lifshay
4 use api_impl::{Device, Instance, PhysicalDevice, Queue};
5 use buffer::{Buffer, BufferView};
6 use descriptor_set::{DescriptorPool, DescriptorSet, DescriptorSetLayout};
7 use device_memory::DeviceMemory;
8 use image::{Image, ImageView};
9 use render_pass::RenderPass;
11 use sampler::SamplerYcbcrConversion;
12 use shader_module::ShaderModule;
14 use std::marker::PhantomData;
17 use std::ops::DerefMut;
18 use std::ptr::null_mut;
19 use std::ptr::NonNull;
20 use swapchain::Swapchain;
23 pub struct DispatchableType<T> {
24 loader_dispatch_ptr: usize,
28 impl<T> From<T> for DispatchableType<T> {
29 fn from(v: T) -> Self {
31 loader_dispatch_ptr: api::ICD_LOADER_MAGIC as usize,
37 impl<T> Deref for DispatchableType<T> {
39 fn deref(&self) -> &T {
44 impl<T> DerefMut for DispatchableType<T> {
45 fn deref_mut(&mut self) -> &mut T {
50 pub trait HandleAllocFree: Handle {
51 unsafe fn allocate<T: Into<Self::Value>>(v: T) -> Self {
52 Self::new(Some(NonNull::new_unchecked(Box::into_raw(Box::new(
56 unsafe fn free(self) {
57 Box::from_raw(self.get().unwrap().as_ptr());
61 pub trait Handle: Copy + Eq + fmt::Debug {
63 fn get(&self) -> Option<NonNull<Self::Value>>;
64 fn new(v: Option<NonNull<Self::Value>>) -> Self;
68 fn is_null(&self) -> bool {
71 fn take(&mut self) -> Self {
79 pub struct DispatchableHandle<T>(Option<NonNull<()>>, PhantomData<*mut DispatchableType<T>>);
81 impl<T> Clone for DispatchableHandle<T> {
82 fn clone(&self) -> Self {
83 DispatchableHandle(self.0, PhantomData)
87 impl<T> Copy for DispatchableHandle<T> {}
89 impl<T> Eq for DispatchableHandle<T> {}
91 impl<T> PartialEq for DispatchableHandle<T> {
92 fn eq(&self, rhs: &Self) -> bool {
97 impl<T> fmt::Debug for DispatchableHandle<T> {
98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99 f.debug_tuple("DispatchableHandle")
104 .unwrap_or(null_mut::<*mut ()>() as *mut _),
110 impl<T> Handle for DispatchableHandle<T> {
111 type Value = DispatchableType<T>;
112 fn get(&self) -> Option<NonNull<DispatchableType<T>>> {
113 unsafe { mem::transmute(self.0) }
115 fn new(v: Option<NonNull<DispatchableType<T>>>) -> Self {
116 unsafe { DispatchableHandle(mem::transmute(v), PhantomData) }
121 pub struct NondispatchableHandle<T>(u64, PhantomData<Option<NonNull<T>>>);
123 impl<T> Clone for NondispatchableHandle<T> {
124 fn clone(&self) -> Self {
125 NondispatchableHandle(self.0, PhantomData)
129 impl<T> Copy for NondispatchableHandle<T> {}
131 impl<T> Eq for NondispatchableHandle<T> {}
133 impl<T> PartialEq for NondispatchableHandle<T> {
134 fn eq(&self, rhs: &Self) -> bool {
139 impl<T> fmt::Debug for NondispatchableHandle<T> {
140 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
141 f.debug_tuple("NondispatchableHandle")
142 .field(&self.get().map(|v| v.as_ptr()).unwrap_or(null_mut()))
147 impl<T> Handle for NondispatchableHandle<T> {
149 fn get(&self) -> Option<NonNull<T>> {
150 NonNull::new(self.0 as *mut T)
152 fn new(v: Option<NonNull<T>>) -> Self {
153 NondispatchableHandle(
154 v.map(|v| v.as_ptr()).unwrap_or(null_mut()) as u64,
161 pub struct OwnedHandle<T: HandleAllocFree>(NonNull<T::Value>);
163 impl<T: HandleAllocFree> OwnedHandle<T> {
164 pub fn new<I: Into<T::Value>>(v: I) -> Self {
165 unsafe { OwnedHandle(T::allocate(v).get().unwrap()) }
167 pub unsafe fn from(v: T) -> Option<Self> {
168 v.get().map(OwnedHandle)
170 pub unsafe fn take(self) -> T {
175 pub unsafe fn get_handle(&self) -> T {
180 impl<T: HandleAllocFree> Deref for OwnedHandle<T> {
181 type Target = T::Value;
182 fn deref(&self) -> &T::Value {
183 unsafe { &*self.0.as_ptr() }
187 impl<T: HandleAllocFree> DerefMut for OwnedHandle<T> {
188 fn deref_mut(&mut self) -> &mut T::Value {
189 unsafe { &mut *self.0.as_ptr() }
193 impl<T: HandleAllocFree> Drop for OwnedHandle<T> {
196 T::new(Some(self.0)).free();
201 impl<T: HandleAllocFree> fmt::Debug for OwnedHandle<T>
203 T::Value: fmt::Debug,
205 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
206 f.debug_tuple("OwnedHandle").field((*self).deref()).finish()
211 pub struct SharedHandle<T: Handle>(NonNull<T::Value>);
213 impl<T: Handle> Clone for SharedHandle<T> {
214 fn clone(&self) -> Self {
219 impl<T: Handle> SharedHandle<T> {
220 pub unsafe fn from(v: T) -> Option<Self> {
221 v.get().map(SharedHandle)
224 pub unsafe fn take(self) -> T {
227 pub unsafe fn get_handle(&self) -> T {
230 pub fn into_nonnull(self) -> NonNull<T::Value> {
235 impl<T: Handle> Deref for SharedHandle<T> {
236 type Target = T::Value;
237 fn deref(&self) -> &T::Value {
238 unsafe { &*self.0.as_ptr() }
242 impl<T: Handle> fmt::Debug for SharedHandle<T>
244 T::Value: fmt::Debug,
246 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
247 f.debug_tuple("SharedHandle")
248 .field((*self).deref())
254 pub struct MutHandle<T: Handle>(NonNull<T::Value>);
256 impl<T: Handle> MutHandle<T> {
257 pub unsafe fn from(v: T) -> Option<Self> {
258 v.get().map(MutHandle)
261 pub unsafe fn take(self) -> T {
265 pub unsafe fn get_handle(&self) -> T {
269 pub fn into_nonnull(self) -> NonNull<T::Value> {
274 impl<T: Handle> Deref for MutHandle<T> {
275 type Target = T::Value;
276 fn deref(&self) -> &T::Value {
277 unsafe { &*self.0.as_ptr() }
281 impl<T: Handle> DerefMut for MutHandle<T> {
282 fn deref_mut(&mut self) -> &mut T::Value {
283 unsafe { &mut *self.0.as_ptr() }
287 impl<T: Handle> fmt::Debug for MutHandle<T>
289 T::Value: fmt::Debug,
291 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
292 f.debug_tuple("MutHandle").field((*self).deref()).finish()
296 pub type VkInstance = DispatchableHandle<Instance>;
298 impl HandleAllocFree for VkInstance {}
300 pub type VkPhysicalDevice = DispatchableHandle<PhysicalDevice>;
302 impl HandleAllocFree for VkPhysicalDevice {}
304 pub type VkDevice = DispatchableHandle<Device>;
306 impl HandleAllocFree for VkDevice {}
308 pub type VkQueue = DispatchableHandle<Queue>;
310 impl HandleAllocFree for VkQueue {}
312 pub struct CommandBuffer {}
314 pub type VkCommandBuffer = DispatchableHandle<CommandBuffer>;
316 impl HandleAllocFree for VkCommandBuffer {}
318 pub struct Semaphore {}
320 pub type VkSemaphore = NondispatchableHandle<Semaphore>;
322 impl HandleAllocFree for VkSemaphore {}
326 pub type VkFence = NondispatchableHandle<Fence>;
328 impl HandleAllocFree for VkFence {}
330 pub type VkDeviceMemory = NondispatchableHandle<DeviceMemory>;
332 impl HandleAllocFree for VkDeviceMemory {}
334 pub type VkBuffer = NondispatchableHandle<Buffer>;
336 impl HandleAllocFree for VkBuffer {}
338 pub type VkImage = NondispatchableHandle<Image>;
340 impl HandleAllocFree for VkImage {}
344 pub type VkEvent = NondispatchableHandle<Event>;
346 impl HandleAllocFree for VkEvent {}
348 pub struct QueryPool {}
350 pub type VkQueryPool = NondispatchableHandle<QueryPool>;
352 impl HandleAllocFree for VkQueryPool {}
354 pub type VkBufferView = NondispatchableHandle<BufferView>;
356 impl HandleAllocFree for VkBufferView {}
358 pub type VkImageView = NondispatchableHandle<ImageView>;
360 impl HandleAllocFree for VkImageView {}
362 pub type VkShaderModule = NondispatchableHandle<ShaderModule>;
364 impl HandleAllocFree for VkShaderModule {}
366 pub struct PipelineCache {}
368 pub type VkPipelineCache = NondispatchableHandle<PipelineCache>;
370 impl HandleAllocFree for VkPipelineCache {}
372 pub struct PipelineLayout {}
374 pub type VkPipelineLayout = NondispatchableHandle<PipelineLayout>;
376 impl HandleAllocFree for VkPipelineLayout {}
378 pub type VkRenderPass = NondispatchableHandle<RenderPass>;
380 impl HandleAllocFree for VkRenderPass {}
382 pub struct Pipeline {}
384 pub type VkPipeline = NondispatchableHandle<Pipeline>;
386 impl HandleAllocFree for VkPipeline {}
388 pub type VkDescriptorSetLayout = NondispatchableHandle<DescriptorSetLayout>;
390 impl HandleAllocFree for VkDescriptorSetLayout {}
392 pub type VkSampler = NondispatchableHandle<Sampler>;
394 impl HandleAllocFree for VkSampler {}
396 pub type VkDescriptorPool = NondispatchableHandle<DescriptorPool>;
398 impl HandleAllocFree for VkDescriptorPool {}
400 pub type VkDescriptorSet = NondispatchableHandle<DescriptorSet>;
402 impl HandleAllocFree for VkDescriptorSet {}
404 pub struct Framebuffer {}
406 pub type VkFramebuffer = NondispatchableHandle<Framebuffer>;
408 impl HandleAllocFree for VkFramebuffer {}
410 pub struct CommandPool {}
412 pub type VkCommandPool = NondispatchableHandle<CommandPool>;
414 impl HandleAllocFree for VkCommandPool {}
416 pub type VkSamplerYcbcrConversion = NondispatchableHandle<SamplerYcbcrConversion>;
418 impl HandleAllocFree for VkSamplerYcbcrConversion {}
420 pub struct DescriptorUpdateTemplate {}
422 pub type VkDescriptorUpdateTemplate = NondispatchableHandle<DescriptorUpdateTemplate>;
424 impl HandleAllocFree for VkDescriptorUpdateTemplate {}
426 pub type VkSurfaceKHR = NondispatchableHandle<api::VkIcdSurfaceBase>;
428 // HandleAllocFree specifically not implemented for VkSurfaceKHR
430 pub type VkSwapchainKHR = NondispatchableHandle<Box<Swapchain>>;
432 impl HandleAllocFree for VkSwapchainKHR {}
434 pub struct DisplayKHR {}
436 pub type VkDisplayKHR = NondispatchableHandle<DisplayKHR>;
438 impl HandleAllocFree for VkDisplayKHR {}
440 pub struct DisplayModeKHR {}
442 pub type VkDisplayModeKHR = NondispatchableHandle<DisplayModeKHR>;
444 impl HandleAllocFree for VkDisplayModeKHR {}
446 pub struct DebugReportCallbackEXT {}
448 pub type VkDebugReportCallbackEXT = NondispatchableHandle<DebugReportCallbackEXT>;
450 impl HandleAllocFree for VkDebugReportCallbackEXT {}
452 pub struct DebugUtilsMessengerEXT {}
454 pub type VkDebugUtilsMessengerEXT = NondispatchableHandle<DebugUtilsMessengerEXT>;
456 impl HandleAllocFree for VkDebugUtilsMessengerEXT {}
458 pub struct ValidationCacheEXT {}
460 pub type VkValidationCacheEXT = NondispatchableHandle<ValidationCacheEXT>;
462 impl HandleAllocFree for VkValidationCacheEXT {}