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;
9 use sampler::SamplerYcbcrConversion;
10 use shader_module::ShaderModule;
12 use std::marker::PhantomData;
15 use std::ops::DerefMut;
16 use std::ptr::null_mut;
17 use std::ptr::NonNull;
18 use swapchain::Swapchain;
21 pub struct DispatchableType<T> {
22 loader_dispatch_ptr: usize,
26 impl<T> From<T> for DispatchableType<T> {
27 fn from(v: T) -> Self {
29 loader_dispatch_ptr: api::ICD_LOADER_MAGIC as usize,
35 impl<T> Deref for DispatchableType<T> {
37 fn deref(&self) -> &T {
42 impl<T> DerefMut for DispatchableType<T> {
43 fn deref_mut(&mut self) -> &mut T {
48 pub trait HandleAllocFree: Handle {
49 unsafe fn allocate<T: Into<Self::Value>>(v: T) -> Self {
50 Self::new(Some(NonNull::new_unchecked(Box::into_raw(Box::new(
54 unsafe fn free(self) {
55 Box::from_raw(self.get().unwrap().as_ptr());
59 pub trait Handle: Copy + Eq + fmt::Debug {
61 fn get(&self) -> Option<NonNull<Self::Value>>;
62 fn new(v: Option<NonNull<Self::Value>>) -> Self;
66 fn is_null(&self) -> bool {
69 fn take(&mut self) -> Self {
77 pub struct DispatchableHandle<T>(Option<NonNull<()>>, PhantomData<*mut DispatchableType<T>>);
79 impl<T> Clone for DispatchableHandle<T> {
80 fn clone(&self) -> Self {
81 DispatchableHandle(self.0, PhantomData)
85 impl<T> Copy for DispatchableHandle<T> {}
87 impl<T> Eq for DispatchableHandle<T> {}
89 impl<T> PartialEq for DispatchableHandle<T> {
90 fn eq(&self, rhs: &Self) -> bool {
95 impl<T> fmt::Debug for DispatchableHandle<T> {
96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 f.debug_tuple("DispatchableHandle")
102 .unwrap_or(null_mut::<*mut ()>() as *mut _),
108 impl<T> Handle for DispatchableHandle<T> {
109 type Value = DispatchableType<T>;
110 fn get(&self) -> Option<NonNull<DispatchableType<T>>> {
111 unsafe { mem::transmute(self.0) }
113 fn new(v: Option<NonNull<DispatchableType<T>>>) -> Self {
114 unsafe { DispatchableHandle(mem::transmute(v), PhantomData) }
119 pub struct NondispatchableHandle<T>(u64, PhantomData<Option<NonNull<T>>>);
121 impl<T> Clone for NondispatchableHandle<T> {
122 fn clone(&self) -> Self {
123 NondispatchableHandle(self.0, PhantomData)
127 impl<T> Copy for NondispatchableHandle<T> {}
129 impl<T> Eq for NondispatchableHandle<T> {}
131 impl<T> PartialEq for NondispatchableHandle<T> {
132 fn eq(&self, rhs: &Self) -> bool {
137 impl<T> fmt::Debug for NondispatchableHandle<T> {
138 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
139 f.debug_tuple("NondispatchableHandle")
140 .field(&self.get().map(|v| v.as_ptr()).unwrap_or(null_mut()))
145 impl<T> Handle for NondispatchableHandle<T> {
147 fn get(&self) -> Option<NonNull<T>> {
148 NonNull::new(self.0 as *mut T)
150 fn new(v: Option<NonNull<T>>) -> Self {
151 NondispatchableHandle(
152 v.map(|v| v.as_ptr()).unwrap_or(null_mut()) as u64,
159 pub struct OwnedHandle<T: HandleAllocFree>(NonNull<T::Value>);
161 impl<T: HandleAllocFree> OwnedHandle<T> {
162 pub fn new<I: Into<T::Value>>(v: I) -> Self {
163 unsafe { OwnedHandle(T::allocate(v).get().unwrap()) }
165 pub unsafe fn from(v: T) -> Option<Self> {
166 v.get().map(OwnedHandle)
168 pub unsafe fn take(self) -> T {
173 pub unsafe fn get_handle(&self) -> T {
178 impl<T: HandleAllocFree> Deref for OwnedHandle<T> {
179 type Target = T::Value;
180 fn deref(&self) -> &T::Value {
181 unsafe { &*self.0.as_ptr() }
185 impl<T: HandleAllocFree> DerefMut for OwnedHandle<T> {
186 fn deref_mut(&mut self) -> &mut T::Value {
187 unsafe { &mut *self.0.as_ptr() }
191 impl<T: HandleAllocFree> Drop for OwnedHandle<T> {
194 T::new(Some(self.0)).free();
199 impl<T: HandleAllocFree> fmt::Debug for OwnedHandle<T>
201 T::Value: fmt::Debug,
203 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
204 f.debug_tuple("OwnedHandle").field((*self).deref()).finish()
208 #[derive(Copy, Clone)]
210 pub struct SharedHandle<T: Handle>(NonNull<T::Value>);
212 impl<T: Handle> SharedHandle<T> {
213 pub unsafe fn from(v: T) -> Option<Self> {
214 v.get().map(SharedHandle)
217 pub unsafe fn take(self) -> T {
220 pub unsafe fn get_handle(&self) -> T {
223 pub fn into_nonnull(self) -> NonNull<T::Value> {
228 impl<T: Handle> Deref for SharedHandle<T> {
229 type Target = T::Value;
230 fn deref(&self) -> &T::Value {
231 unsafe { &*self.0.as_ptr() }
235 impl<T: Handle> fmt::Debug for SharedHandle<T>
237 T::Value: fmt::Debug,
239 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
240 f.debug_tuple("SharedHandle")
241 .field((*self).deref())
247 pub struct MutHandle<T: Handle>(NonNull<T::Value>);
249 impl<T: Handle> MutHandle<T> {
250 pub unsafe fn from(v: T) -> Option<Self> {
251 v.get().map(MutHandle)
254 pub unsafe fn take(self) -> T {
258 pub unsafe fn get_handle(&self) -> T {
262 pub fn into_nonnull(self) -> NonNull<T::Value> {
267 impl<T: Handle> Deref for MutHandle<T> {
268 type Target = T::Value;
269 fn deref(&self) -> &T::Value {
270 unsafe { &*self.0.as_ptr() }
274 impl<T: Handle> DerefMut for MutHandle<T> {
275 fn deref_mut(&mut self) -> &mut T::Value {
276 unsafe { &mut *self.0.as_ptr() }
280 impl<T: Handle> fmt::Debug for MutHandle<T>
282 T::Value: fmt::Debug,
284 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
285 f.debug_tuple("MutHandle").field((*self).deref()).finish()
289 pub type VkInstance = DispatchableHandle<Instance>;
291 impl HandleAllocFree for VkInstance {}
293 pub type VkPhysicalDevice = DispatchableHandle<PhysicalDevice>;
295 impl HandleAllocFree for VkPhysicalDevice {}
297 pub type VkDevice = DispatchableHandle<Device>;
299 impl HandleAllocFree for VkDevice {}
301 pub type VkQueue = DispatchableHandle<Queue>;
303 impl HandleAllocFree for VkQueue {}
305 pub struct CommandBuffer {}
307 pub type VkCommandBuffer = DispatchableHandle<CommandBuffer>;
309 impl HandleAllocFree for VkCommandBuffer {}
311 pub struct Semaphore {}
313 pub type VkSemaphore = NondispatchableHandle<Semaphore>;
315 impl HandleAllocFree for VkSemaphore {}
319 pub type VkFence = NondispatchableHandle<Fence>;
321 impl HandleAllocFree for VkFence {}
323 pub type VkDeviceMemory = NondispatchableHandle<DeviceMemory>;
325 impl HandleAllocFree for VkDeviceMemory {}
327 pub type VkBuffer = NondispatchableHandle<Buffer>;
329 impl HandleAllocFree for VkBuffer {}
331 pub type VkImage = NondispatchableHandle<Image>;
333 impl HandleAllocFree for VkImage {}
337 pub type VkEvent = NondispatchableHandle<Event>;
339 impl HandleAllocFree for VkEvent {}
341 pub struct QueryPool {}
343 pub type VkQueryPool = NondispatchableHandle<QueryPool>;
345 impl HandleAllocFree for VkQueryPool {}
347 pub struct BufferView {}
349 pub type VkBufferView = NondispatchableHandle<BufferView>;
351 impl HandleAllocFree for VkBufferView {}
353 pub struct ImageView {}
355 pub type VkImageView = NondispatchableHandle<ImageView>;
357 impl HandleAllocFree for VkImageView {}
359 pub type VkShaderModule = NondispatchableHandle<ShaderModule>;
361 impl HandleAllocFree for VkShaderModule {}
363 pub struct PipelineCache {}
365 pub type VkPipelineCache = NondispatchableHandle<PipelineCache>;
367 impl HandleAllocFree for VkPipelineCache {}
369 pub struct PipelineLayout {}
371 pub type VkPipelineLayout = NondispatchableHandle<PipelineLayout>;
373 impl HandleAllocFree for VkPipelineLayout {}
375 pub struct RenderPass {}
377 pub type VkRenderPass = NondispatchableHandle<RenderPass>;
379 impl HandleAllocFree for VkRenderPass {}
381 pub struct Pipeline {}
383 pub type VkPipeline = NondispatchableHandle<Pipeline>;
385 impl HandleAllocFree for VkPipeline {}
387 pub struct DescriptorSetLayout {}
389 pub type VkDescriptorSetLayout = NondispatchableHandle<DescriptorSetLayout>;
391 impl HandleAllocFree for VkDescriptorSetLayout {}
393 pub type VkSampler = NondispatchableHandle<Sampler>;
395 impl HandleAllocFree for VkSampler {}
397 pub struct DescriptorPool {}
399 pub type VkDescriptorPool = NondispatchableHandle<DescriptorPool>;
401 impl HandleAllocFree for VkDescriptorPool {}
403 pub struct DescriptorSet {}
405 pub type VkDescriptorSet = NondispatchableHandle<DescriptorSet>;
407 impl HandleAllocFree for VkDescriptorSet {}
409 pub struct Framebuffer {}
411 pub type VkFramebuffer = NondispatchableHandle<Framebuffer>;
413 impl HandleAllocFree for VkFramebuffer {}
415 pub struct CommandPool {}
417 pub type VkCommandPool = NondispatchableHandle<CommandPool>;
419 impl HandleAllocFree for VkCommandPool {}
421 pub type VkSamplerYcbcrConversion = NondispatchableHandle<SamplerYcbcrConversion>;
423 impl HandleAllocFree for VkSamplerYcbcrConversion {}
425 pub struct DescriptorUpdateTemplate {}
427 pub type VkDescriptorUpdateTemplate = NondispatchableHandle<DescriptorUpdateTemplate>;
429 impl HandleAllocFree for VkDescriptorUpdateTemplate {}
431 pub type VkSurfaceKHR = NondispatchableHandle<api::VkIcdSurfaceBase>;
433 // HandleAllocFree specifically not implemented for VkSurfaceKHR
435 pub type VkSwapchainKHR = NondispatchableHandle<Box<Swapchain>>;
437 impl HandleAllocFree for VkSwapchainKHR {}
439 pub struct DisplayKHR {}
441 pub type VkDisplayKHR = NondispatchableHandle<DisplayKHR>;
443 impl HandleAllocFree for VkDisplayKHR {}
445 pub struct DisplayModeKHR {}
447 pub type VkDisplayModeKHR = NondispatchableHandle<DisplayModeKHR>;
449 impl HandleAllocFree for VkDisplayModeKHR {}
451 pub struct DebugReportCallbackEXT {}
453 pub type VkDebugReportCallbackEXT = NondispatchableHandle<DebugReportCallbackEXT>;
455 impl HandleAllocFree for VkDebugReportCallbackEXT {}
457 pub struct DebugUtilsMessengerEXT {}
459 pub type VkDebugUtilsMessengerEXT = NondispatchableHandle<DebugUtilsMessengerEXT>;
461 impl HandleAllocFree for VkDebugUtilsMessengerEXT {}
463 pub struct ValidationCacheEXT {}
465 pub type VkValidationCacheEXT = NondispatchableHandle<ValidationCacheEXT>;
467 impl HandleAllocFree for VkValidationCacheEXT {}