Skip to main content

bedrock/
handle.rs

1use bedrock_vk::{self as brvk, VkRawHandle};
2
3/// Wrapping a Vulkan Dispatchable/Nondispatchable Handler
4pub trait VkHandle {
5    type Handle;
6
7    /// Retrieve an underlying handle
8    fn native_ptr(&self) -> Self::Handle;
9
10    #[inline(always)]
11    fn as_transparent_ref<'a>(&'a self) -> VkHandleRef<'a, Self::Handle> {
12        VkHandleRef::new(self)
13    }
14}
15/// Wrapping a Vulkan Dispatchable/Nondispatchable Mutable Handler
16pub trait VkHandleMut: VkHandle {
17    /// Retrieve an underlying mutable handle
18    fn native_ptr_mut(&mut self) -> Self::Handle;
19
20    #[inline(always)]
21    fn as_transparent_ref_mut<'a>(&'a mut self) -> VkHandleRefMut<'a, Self::Handle> {
22        VkHandleRefMut::new(self)
23    }
24}
25
26DerefContainerBracketImpl!(for VkHandle {
27    type Handle = T::Handle;
28
29    #[inline(always)]
30    fn native_ptr(&self) -> Self::Handle { T::native_ptr(self) }
31});
32DerefContainerBracketImpl!(for mut VkHandleMut {
33    #[inline(always)]
34    fn native_ptr_mut(&mut self) -> Self::Handle { T::native_ptr_mut(self) }
35});
36
37impl<T: VkHandle + ?Sized> VkHandle for std::cell::Ref<'_, T> {
38    type Handle = T::Handle;
39
40    #[inline(always)]
41    fn native_ptr(&self) -> Self::Handle {
42        T::native_ptr(&**self)
43    }
44}
45impl<T: VkHandle + ?Sized> VkHandle for std::cell::RefMut<'_, T> {
46    type Handle = T::Handle;
47
48    #[inline(always)]
49    fn native_ptr(&self) -> Self::Handle {
50        T::native_ptr(&**self)
51    }
52}
53impl<T: VkHandleMut + ?Sized> VkHandleMut for std::cell::RefMut<'_, T> {
54    #[inline(always)]
55    fn native_ptr_mut(&mut self) -> Self::Handle {
56        T::native_ptr_mut(&mut **self)
57    }
58}
59
60impl<T: VkHandle + ?Sized> VkHandle for std::sync::MutexGuard<'_, T> {
61    type Handle = T::Handle;
62
63    #[inline(always)]
64    fn native_ptr(&self) -> Self::Handle {
65        T::native_ptr(&**self)
66    }
67}
68impl<T: VkHandleMut + ?Sized> VkHandleMut for std::sync::MutexGuard<'_, T> {
69    #[inline(always)]
70    fn native_ptr_mut(&mut self) -> Self::Handle {
71        T::native_ptr_mut(&mut **self)
72    }
73}
74
75impl<T: VkHandle + ?Sized> VkHandle for std::sync::RwLockReadGuard<'_, T> {
76    type Handle = T::Handle;
77
78    #[inline(always)]
79    fn native_ptr(&self) -> Self::Handle {
80        T::native_ptr(&**self)
81    }
82}
83
84impl<T: VkHandle + ?Sized> VkHandle for std::sync::RwLockWriteGuard<'_, T> {
85    type Handle = T::Handle;
86
87    #[inline(always)]
88    fn native_ptr(&self) -> Self::Handle {
89        T::native_ptr(&**self)
90    }
91}
92impl<T: VkHandleMut + ?Sized> VkHandleMut for std::sync::RwLockWriteGuard<'_, T> {
93    #[inline(always)]
94    fn native_ptr_mut(&mut self) -> Self::Handle {
95        T::native_ptr_mut(&mut **self)
96    }
97}
98
99impl<T: VkHandle + ?Sized> VkHandle for parking_lot::RwLockReadGuard<'_, T> {
100    type Handle = T::Handle;
101
102    #[inline(always)]
103    fn native_ptr(&self) -> Self::Handle {
104        T::native_ptr(&**self)
105    }
106}
107impl<T: VkHandle + ?Sized> VkHandle for parking_lot::MappedRwLockReadGuard<'_, T> {
108    type Handle = T::Handle;
109
110    #[inline(always)]
111    fn native_ptr(&self) -> Self::Handle {
112        T::native_ptr(&**self)
113    }
114}
115impl<T: VkHandle + ?Sized> VkHandle for parking_lot::RwLockWriteGuard<'_, T> {
116    type Handle = T::Handle;
117
118    #[inline(always)]
119    fn native_ptr(&self) -> Self::Handle {
120        T::native_ptr(&**self)
121    }
122}
123impl<T: VkHandle + ?Sized> VkHandle for parking_lot::MappedRwLockWriteGuard<'_, T> {
124    type Handle = T::Handle;
125
126    #[inline(always)]
127    fn native_ptr(&self) -> Self::Handle {
128        T::native_ptr(&**self)
129    }
130}
131impl<T: VkHandleMut + ?Sized> VkHandleMut for parking_lot::RwLockWriteGuard<'_, T> {
132    #[inline(always)]
133    fn native_ptr_mut(&mut self) -> Self::Handle {
134        T::native_ptr_mut(&mut **self)
135    }
136}
137impl<T: VkHandleMut + ?Sized> VkHandleMut for parking_lot::MappedRwLockWriteGuard<'_, T> {
138    #[inline(always)]
139    fn native_ptr_mut(&mut self) -> Self::Handle {
140        T::native_ptr_mut(&mut **self)
141    }
142}
143
144impl<T: VkHandle + ?Sized> VkHandle for parking_lot::MutexGuard<'_, T> {
145    type Handle = T::Handle;
146
147    #[inline(always)]
148    fn native_ptr(&self) -> Self::Handle {
149        T::native_ptr(&**self)
150    }
151}
152impl<T: VkHandle + ?Sized> VkHandle for parking_lot::MappedMutexGuard<'_, T> {
153    type Handle = T::Handle;
154
155    #[inline(always)]
156    fn native_ptr(&self) -> Self::Handle {
157        T::native_ptr(&**self)
158    }
159}
160impl<T: VkHandleMut + ?Sized> VkHandleMut for parking_lot::MutexGuard<'_, T> {
161    #[inline(always)]
162    fn native_ptr_mut(&mut self) -> Self::Handle {
163        T::native_ptr_mut(&mut **self)
164    }
165}
166impl<T: VkHandleMut + ?Sized> VkHandleMut for parking_lot::MappedMutexGuard<'_, T> {
167    #[inline(always)]
168    fn native_ptr_mut(&mut self) -> Self::Handle {
169        T::native_ptr_mut(&mut **self)
170    }
171}
172
173/// Extension methods(not dyn compatible) for `VkHandle`
174pub trait VkHandleExt: VkHandle {
175    /// Checks the equality between vulkan objects by their handle value.
176    #[inline(always)]
177    fn eq_handle(&self, other: &Self) -> bool
178    where
179        Self::Handle: brvk::VkRawHandle,
180    {
181        self.native_ptr().raw_handle_value() == other.native_ptr().raw_handle_value()
182    }
183}
184impl<T: VkHandle> VkHandleExt for T {}
185
186pub trait VkDeviceChildNonExtDestroyable {
187    /// # Safety
188    ///
189    /// device must be a valid Vulkan device handle and must own this resource.
190    unsafe fn destroy(self, device: brvk::VkDevice, allocator: *const brvk::VkAllocationCallbacks);
191}
192
193/// A smart handle to a Vulkan object that holds a source lifetime
194/// (bitpattern as same as native handle type)
195#[repr(transparent)]
196#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
197pub struct VkHandleRef<'r, H>(pub(crate) H, core::marker::PhantomData<&'r dyn VkHandle<Handle = H>>);
198impl<'r, H> VkHandleRef<'r, H> {
199    pub fn new(r: &'r (impl VkHandle<Handle = H> + ?Sized)) -> Self {
200        Self(r.native_ptr(), core::marker::PhantomData)
201    }
202
203    pub const fn from_raw_ref(h: &'r H) -> &'r Self {
204        unsafe { core::mem::transmute(h) }
205    }
206
207    /// simple raw handle wrapper without any lifetime constraints.
208    /// # Safety
209    /// owner of the handle must be alive while the handle will be used.
210    pub const unsafe fn dangling(h: H) -> Self {
211        Self(h, core::marker::PhantomData)
212    }
213}
214impl<H: Copy> VkHandle for VkHandleRef<'_, H> {
215    type Handle = H;
216
217    #[inline(always)]
218    fn native_ptr(&self) -> H {
219        self.0
220    }
221}
222
223/// A smart handle to a Vulkan object that holds a source lifetime and mutable-borrowing
224/// (bitpattern as same as native handle type)
225#[repr(transparent)]
226#[derive(Clone, Hash, PartialEq, Eq, Debug)]
227pub struct VkHandleRefMut<'r, H>(
228    pub(crate) H,
229    core::marker::PhantomData<&'r mut dyn VkHandleMut<Handle = H>>,
230);
231impl<'r, H> VkHandleRefMut<'r, H> {
232    pub fn new(r: &'r mut (impl VkHandleMut<Handle = H> + ?Sized)) -> Self {
233        Self(r.native_ptr(), core::marker::PhantomData)
234    }
235
236    pub const fn from_raw_ref(h: &'r H) -> &'r Self {
237        unsafe { core::mem::transmute(h) }
238    }
239
240    /// simple raw handle wrapper without any lifetime constraints.
241    /// # Safety
242    /// owner of the handle must be alive while the handle will be used.
243    pub const unsafe fn dangling(h: H) -> Self {
244        Self(h, core::marker::PhantomData)
245    }
246}
247impl<H: Copy> VkHandle for VkHandleRefMut<'_, H> {
248    type Handle = H;
249
250    #[inline(always)]
251    fn native_ptr(&self) -> H {
252        self.0
253    }
254}
255impl<H: Copy> VkHandleMut for VkHandleRefMut<'_, H> {
256    #[inline(always)]
257    fn native_ptr_mut(&mut self) -> H {
258        self.0
259    }
260}