bedrock/
sync.rs

1//! Vulkan Synchronization Primitives(Fence, Semaphore, Event)
2
3use crate::*;
4use derives::implements;
5
6pub trait Fence: VkHandle<Handle = VkFence> + DeviceChildHandle + Status {
7    /// Wait for a fence to become signaled, returns `Ok(true)` if operation is timed out
8    /// # Failures
9    /// On failure, this command returns
10    ///
11    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
12    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
13    /// * [`VK_ERROR_DEVICE_LOST`]
14    #[implements]
15    #[inline(always)]
16    fn wait_timeout(&self, timeout: u64) -> crate::Result<bool> {
17        let vr =
18            unsafe { crate::vkfn::wait_for_fences(self.device_handle(), 1, &self.native_ptr(), false as _, timeout) };
19        match vr {
20            VK_SUCCESS => Ok(false),
21            VK_TIMEOUT => Ok(true),
22            _ => Err(vr),
23        }
24    }
25
26    /// Wait for a fence to become signaled
27    /// # Failures
28    /// On failure, this command returns
29    ///
30    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
31    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
32    /// * [`VK_ERROR_DEVICE_LOST`]
33    #[implements]
34    #[inline(always)]
35    fn wait(&self) -> crate::Result<()> {
36        self.wait_timeout(std::u64::MAX).map(drop)
37    }
38}
39DerefContainerBracketImpl!(for Fence {});
40GuardsImpl!(for Fence {});
41
42pub trait FenceMut: Fence + VkHandleMut {
43    /// Resets a fence object
44    /// # Failures
45    /// On failure, this command returns
46    ///
47    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
48    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
49    #[implements]
50    #[inline(always)]
51    fn reset(&mut self) -> crate::Result<()> {
52        unsafe {
53            crate::vkfn::reset_fences(self.device_handle(), 1, &self.native_ptr_mut())
54                .into_result()
55                .map(drop)
56        }
57    }
58}
59DerefContainerBracketImpl!(for mut FenceMut {});
60GuardsImpl!(for mut FenceMut {});
61
62pub trait DeviceChildFence: DeviceChild + Fence {}
63impl<T: DeviceChild + Fence> DeviceChildFence for T {}
64
65pub trait Semaphore: VkHandle<Handle = VkSemaphore> + DeviceChild {
66    /// Creates a submit info structure for this semaphore.
67    #[cfg(feature = "VK_KHR_synchronization2")]
68    #[inline(always)]
69    fn submit_info(&self) -> SemaphoreSubmitInfo {
70        SemaphoreSubmitInfo::new(self)
71    }
72
73    /// Query the current state of a timeline semaphore
74    #[implements("Allow1_2APIs")]
75    #[inline(always)]
76    fn counter_value(&self) -> crate::Result<u64> {
77        let mut sink = core::mem::MaybeUninit::uninit();
78
79        unsafe {
80            crate::vkfn::get_semaphore_counter_value(self.device().native_ptr(), self.native_ptr(), sink.as_mut_ptr())
81                .into_result()?;
82        }
83
84        Ok(unsafe { sink.assume_init() })
85    }
86}
87DerefContainerBracketImpl!(for Semaphore {});
88GuardsImpl!(for Semaphore {});
89
90pub trait SemaphoreMut: Semaphore + VkHandleMut {}
91DerefContainerBracketImpl!(for mut SemaphoreMut {});
92GuardsImpl!(for mut SemaphoreMut {});
93
94pub trait Event: VkHandle<Handle = VkEvent> + DeviceChild + Status {}
95DerefContainerBracketImpl!(for Event {});
96GuardsImpl!(for Event {});
97
98pub trait EventMut: Event + VkHandleMut {
99    /// Set an event to signaled state
100    /// # Failures
101    /// On failure, this command returns
102    ///
103    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
104    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
105    #[implements]
106    #[inline]
107    fn set(&mut self) -> crate::Result<()> {
108        unsafe {
109            crate::vkfn::set_event(self.device().native_ptr(), self.native_ptr_mut())
110                .into_result()
111                .map(drop)
112        }
113    }
114
115    /// Reset an event to non-signaled state
116    /// # Failures
117    /// On failure, this command returns
118    ///
119    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
120    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
121    #[implements]
122    #[inline]
123    fn reset(&mut self) -> crate::Result<()> {
124        unsafe {
125            crate::vkfn::reset_event(self.device().native_ptr(), self.native_ptr_mut())
126                .into_result()
127                .map(drop)
128        }
129    }
130}
131DerefContainerBracketImpl!(for mut EventMut {});
132GuardsImpl!(for mut EventMut {});
133
134pub trait Status {
135    /// Retrieve the status(whether is signaled or not) of a synchronize object
136    /// # Failures
137    /// On failure, this command returns
138    ///
139    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
140    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
141    /// * [`VK_ERROR_DEVICE_LOST`]
142    #[implements]
143    fn status(&self) -> crate::Result<bool>;
144}
145DerefContainerBracketImpl!(for Status {
146    #[implements]
147    #[inline(always)]
148    fn status(&self) -> crate::Result<bool> {
149        T::status(self)
150    }
151});
152GuardsImpl!(for Status {
153    #[implements]
154    #[inline(always)]
155    fn status(&self) -> crate::Result<bool> {
156        T::status(&self)
157    }
158});
159
160#[repr(transparent)]
161#[derive(Clone)]
162pub struct FenceCreateInfo<'d>(
163    VkFenceCreateInfo,
164    core::marker::PhantomData<Option<&'d dyn VulkanStructure>>,
165);
166impl<'d> FenceCreateInfo<'d> {
167    pub const fn new(flags: VkFenceCreateFlags) -> Self {
168        Self(
169            VkFenceCreateInfo {
170                sType: VkFenceCreateInfo::TYPE,
171                pNext: core::ptr::null(),
172                flags,
173            },
174            core::marker::PhantomData,
175        )
176    }
177
178    pub const unsafe fn from_raw(raw: VkFenceCreateInfo) -> Self {
179        Self(raw, core::marker::PhantomData)
180    }
181
182    pub const fn into_raw(self) -> VkFenceCreateInfo {
183        self.0
184    }
185
186    #[inline(always)]
187    pub fn with_next(mut self, next: &'d (impl TypedVulkanStructure + ?Sized)) -> Self {
188        self.0.pNext = next.as_generic() as *const _ as _;
189        self
190    }
191}
192
193#[derive(VkHandle, VkObject)]
194#[VkObject(type = VkFence::OBJECT_TYPE)]
195pub struct FenceObject<Device: VkHandle<Handle = VkDevice>>(VkFence, Device);
196#[implements]
197impl<Device: VkHandle<Handle = VkDevice>> Drop for FenceObject<Device> {
198    fn drop(&mut self) {
199        unsafe {
200            crate::vkfn::destroy_fence(self.1.native_ptr(), self.0, core::ptr::null());
201        }
202    }
203}
204unsafe impl<Device: VkHandle<Handle = VkDevice> + Sync> Sync for FenceObject<Device> {}
205unsafe impl<Device: VkHandle<Handle = VkDevice> + Send> Send for FenceObject<Device> {}
206impl<Device: VkHandle<Handle = VkDevice>> DeviceChildHandle for FenceObject<Device> {
207    #[inline(always)]
208    fn device_handle(&self) -> VkDevice {
209        self.1.native_ptr()
210    }
211}
212impl<Device: crate::Device> DeviceChild for FenceObject<Device> {
213    type ConcreteDevice = Device;
214
215    #[inline(always)]
216    fn device(&self) -> &Self::ConcreteDevice {
217        &self.1
218    }
219}
220impl<Device: VkHandle<Handle = VkDevice>> Fence for FenceObject<Device> {}
221impl<Device: VkHandle<Handle = VkDevice>> FenceMut for FenceObject<Device> {}
222impl<Device: VkHandle<Handle = VkDevice>> Status for FenceObject<Device> {
223    #[inline(always)]
224    #[implements]
225    fn status(&self) -> crate::Result<bool> {
226        match unsafe { crate::vkfn::get_fence_status(self.1.native_ptr(), self.0) } {
227            VK_SUCCESS => Ok(true),
228            VK_NOT_READY => Ok(false),
229            vr => Err(vr),
230        }
231    }
232}
233impl<Device: VkHandle<Handle = VkDevice>> FenceObject<Device> {
234    /// Constructs from raw values
235    /// # Safety
236    /// the resource must be created from the device and not freed anywhere
237    pub const unsafe fn manage(handle: VkFence, parent: Device) -> Self {
238        Self(handle, parent)
239    }
240
241    /// Purges the construct (Drop will not be called for this resource)
242    pub const fn unmanage(self) -> (VkFence, Device) {
243        let h = self.0;
244        let p = unsafe { core::ptr::read(&self.1) };
245        core::mem::forget(self);
246
247        (h, p)
248    }
249}
250impl<Device: VkHandle<Handle = VkDevice> + Clone> FenceObject<&'_ Device> {
251    /// Owning parent object by cloning it.
252    #[inline(always)]
253    pub fn clone_parent(self) -> FenceObject<Device> {
254        FenceObject(self.0, self.1.clone())
255    }
256}
257impl<Device: crate::Device> FenceObject<Device> {
258    /// Create a new fence object
259    /// # Failures
260    /// On failure, this command returns
261    ///
262    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
263    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
264    #[implements]
265    #[inline]
266    pub fn new(device: Device, create_info: &FenceCreateInfo) -> crate::Result<Self> {
267        Ok(unsafe { Self::manage(device.new_fence_raw(create_info, None)?, device) })
268    }
269}
270
271#[repr(transparent)]
272#[derive(Clone)]
273pub struct SemaphoreCreateInfo<'d>(
274    VkSemaphoreCreateInfo,
275    core::marker::PhantomData<Option<&'d dyn VulkanStructure>>,
276);
277impl<'d> SemaphoreCreateInfo<'d> {
278    pub const fn new() -> Self {
279        Self(
280            VkSemaphoreCreateInfo {
281                sType: VkSemaphoreCreateInfo::TYPE,
282                pNext: core::ptr::null(),
283                flags: 0,
284            },
285            core::marker::PhantomData,
286        )
287    }
288
289    pub const unsafe fn from_raw(raw: VkSemaphoreCreateInfo) -> Self {
290        Self(raw, core::marker::PhantomData)
291    }
292
293    pub const fn into_raw(self) -> VkSemaphoreCreateInfo {
294        self.0
295    }
296
297    #[inline(always)]
298    pub fn with_next(mut self, next: &'d (impl VulkanStructure + ?Sized)) -> Self {
299        self.0.pNext = next.as_generic() as *const _ as _;
300        self
301    }
302}
303
304#[cfg(feature = "VK_KHR_timeline_semaphore")]
305pub struct SemaphoreTypeCreateInfo<'d>(
306    VkSemaphoreTypeCreateInfoKHR,
307    core::marker::PhantomData<Option<&'d dyn VulkanStructure>>,
308);
309#[cfg(feature = "VK_KHR_timeline_semaphore")]
310impl<'d> SemaphoreTypeCreateInfo<'d> {
311    pub const fn binary() -> Self {
312        Self(
313            VkSemaphoreTypeCreateInfoKHR {
314                sType: VkSemaphoreTypeCreateInfoKHR::TYPE,
315                pNext: core::ptr::null(),
316                semaphoreType: VK_SEMAPHORE_TYPE_BINARY_KHR,
317                initialValue: 0,
318            },
319            core::marker::PhantomData,
320        )
321    }
322
323    pub const fn timeline(init: u64) -> Self {
324        Self(
325            VkSemaphoreTypeCreateInfoKHR {
326                sType: VkSemaphoreTypeCreateInfoKHR::TYPE,
327                pNext: core::ptr::null(),
328                semaphoreType: VK_SEMAPHORE_TYPE_TIMELINE_KHR,
329                initialValue: init,
330            },
331            core::marker::PhantomData,
332        )
333    }
334
335    pub const unsafe fn from_raw(raw: VkSemaphoreTypeCreateInfoKHR) -> Self {
336        Self(raw, core::marker::PhantomData)
337    }
338
339    pub const fn into_raw(self) -> VkSemaphoreTypeCreateInfoKHR {
340        self.0
341    }
342
343    #[inline(always)]
344    pub fn with_next(mut self, next: &'d (impl VulkanStructure + ?Sized)) -> Self {
345        self.0.pNext = next.as_generic() as *const _ as _;
346        self
347    }
348}
349#[cfg(feature = "VK_KHR_timeline_semaphore")]
350unsafe impl VulkanStructure for SemaphoreTypeCreateInfo<'_> {
351    #[inline(always)]
352    fn as_generic(&self) -> &GenericVulkanStructure {
353        self.0.as_generic()
354    }
355
356    #[inline(always)]
357    fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
358        self.0.as_generic_mut()
359    }
360}
361
362#[derive(VkHandle, VkObject)]
363#[VkObject(type = VkSemaphore::OBJECT_TYPE)]
364pub struct SemaphoreObject<Device: VkHandle<Handle = VkDevice>>(VkSemaphore, Device);
365#[implements]
366impl<Device: VkHandle<Handle = VkDevice>> Drop for SemaphoreObject<Device> {
367    #[inline(always)]
368    fn drop(&mut self) {
369        unsafe {
370            crate::vkfn::destroy_semaphore(self.1.native_ptr(), self.0, core::ptr::null());
371        }
372    }
373}
374unsafe impl<Device: VkHandle<Handle = VkDevice> + Sync> Sync for SemaphoreObject<Device> {}
375unsafe impl<Device: VkHandle<Handle = VkDevice> + Send> Send for SemaphoreObject<Device> {}
376impl<Device: VkHandle<Handle = VkDevice>> DeviceChildHandle for SemaphoreObject<Device> {
377    #[inline(always)]
378    fn device_handle(&self) -> VkDevice {
379        self.1.native_ptr()
380    }
381}
382impl<Device: crate::Device> DeviceChild for SemaphoreObject<Device> {
383    type ConcreteDevice = Device;
384
385    #[inline(always)]
386    fn device(&self) -> &Self::ConcreteDevice {
387        &self.1
388    }
389}
390impl<Device: crate::Device> Semaphore for SemaphoreObject<Device> {}
391impl<Device: crate::Device> SemaphoreMut for SemaphoreObject<Device> {}
392impl<Device: VkHandle<Handle = VkDevice>> SemaphoreObject<Device> {
393    /// Constructs from raw values
394    /// # Safety
395    /// the resource must be created from the device and not freed anywhere
396    pub const unsafe fn manage(handle: VkSemaphore, parent: Device) -> Self {
397        Self(handle, parent)
398    }
399
400    /// Purges the construct (Drop will not be called for this resource)
401    pub const fn unmanage(self) -> (VkSemaphore, Device) {
402        let h = self.0;
403        let p = unsafe { core::ptr::read(&self.1) };
404        core::mem::forget(self);
405
406        (h, p)
407    }
408}
409impl<Device: VkHandle<Handle = VkDevice> + Clone> SemaphoreObject<&'_ Device> {
410    /// Owning parent object by cloning it.
411    #[inline(always)]
412    pub fn clone_parent(self) -> SemaphoreObject<Device> {
413        SemaphoreObject(self.0, self.1.clone())
414    }
415}
416impl<Device: crate::Device> SemaphoreObject<Device> {
417    /// Create a new queue semaphore object
418    /// # Failures
419    /// On failure, this command returns
420    ///
421    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
422    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
423    #[implements]
424    #[inline]
425    pub fn new(device: Device, info: &SemaphoreCreateInfo) -> crate::Result<Self> {
426        Ok(unsafe { Self::manage(device.new_semaphore_raw(info, None)?, device) })
427    }
428}
429
430#[cfg(feature = "VK_KHR_timeline_semaphore")]
431#[repr(C)]
432pub enum SemaphoreType {
433    Binary = VK_SEMAPHORE_TYPE_BINARY_KHR as _,
434    Timeline = VK_SEMAPHORE_TYPE_TIMELINE_KHR as _,
435}
436
437#[cfg(feature = "VK_KHR_timeline_semaphore")]
438#[repr(transparent)]
439pub struct SemaphoreSignalInfo<'s, 'n>(
440    VkSemaphoreSignalInfoKHR,
441    core::marker::PhantomData<(&'s dyn VkHandle<Handle = VkSemaphore>, Option<&'n dyn VulkanStructure>)>,
442);
443#[cfg(feature = "VK_KHR_timeline_semaphore")]
444impl<'s, 'n> SemaphoreSignalInfo<'s, 'n> {
445    #[inline(always)]
446    pub fn new(semaphore: &'s (impl VkHandle<Handle = VkSemaphore> + ?Sized), value: u64) -> Self {
447        Self(
448            VkSemaphoreSignalInfoKHR {
449                sType: VkSemaphoreSignalInfoKHR::TYPE,
450                pNext: core::ptr::null(),
451                semaphore: semaphore.native_ptr(),
452                value,
453            },
454            core::marker::PhantomData,
455        )
456    }
457
458    pub const unsafe fn new_raw(semaphore: VkSemaphore, value: u64) -> Self {
459        Self(
460            VkSemaphoreSignalInfoKHR {
461                sType: VkSemaphoreSignalInfoKHR::TYPE,
462                pNext: core::ptr::null(),
463                semaphore,
464                value,
465            },
466            core::marker::PhantomData,
467        )
468    }
469
470    /// Constructs from raw values
471    /// # Safety
472    /// the resource must be created from the device and not freed anywhere
473    pub const unsafe fn from_raw(raw: VkSemaphoreSignalInfoKHR) -> Self {
474        Self(raw, core::marker::PhantomData)
475    }
476
477    pub const fn into_raw(self) -> VkSemaphoreSignalInfoKHR {
478        self.0
479    }
480
481    #[inline(always)]
482    pub fn with_next(mut self, next: &'n (impl VulkanStructure + ?Sized)) -> Self {
483        self.0.pNext = next.as_generic() as *const _ as _;
484        self
485    }
486}
487#[cfg(feature = "VK_KHR_timeline_semaphore")]
488unsafe impl VulkanStructure for SemaphoreSignalInfo<'_, '_> {
489    #[inline(always)]
490    fn as_generic(&self) -> &GenericVulkanStructure {
491        self.0.as_generic()
492    }
493
494    #[inline(always)]
495    fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
496        self.0.as_generic_mut()
497    }
498}
499
500#[cfg(feature = "VK_KHR_timeline_semaphore")]
501#[repr(transparent)]
502pub struct SemaphoreWaitInfo<'s, 'n, 'xs>(
503    VkSemaphoreWaitInfoKHR,
504    core::marker::PhantomData<(
505        &'xs [&'s dyn VkHandle<Handle = VkSemaphore>],
506        &'xs [u64],
507        Option<&'n dyn VulkanStructure>,
508    )>,
509);
510#[cfg(feature = "VK_KHR_timeline_semaphore")]
511impl<'s, 'n, 'xs> SemaphoreWaitInfo<'s, 'n, 'xs> {
512    #[inline(always)]
513    pub fn new(semaphores: &'xs [VkHandleRef<'s, VkSemaphore>], values: &'xs [u64]) -> Self {
514        use crate::ffi_helper::slice_as_ptr_empty_null;
515
516        debug_assert_eq!(semaphores.len(), values.len());
517
518        Self(
519            VkSemaphoreWaitInfoKHR {
520                sType: VkSemaphoreWaitInfoKHR::TYPE,
521                pNext: core::ptr::null(),
522                flags: 0,
523                semaphoreCount: semaphores.len() as _,
524                pSemaphores: slice_as_ptr_empty_null(semaphores) as _,
525                pValues: slice_as_ptr_empty_null(values),
526            },
527            core::marker::PhantomData,
528        )
529    }
530
531    #[inline(always)]
532    pub fn new_array<const N: usize>(
533        semaphores: &'xs [VkHandleRef<'s, VkSemaphore>; N],
534        values: &'xs [u64; N],
535    ) -> Self {
536        use crate::ffi_helper::slice_as_ptr_empty_null;
537
538        Self(
539            VkSemaphoreWaitInfoKHR {
540                sType: VkSemaphoreWaitInfoKHR::TYPE,
541                pNext: core::ptr::null(),
542                flags: 0,
543                semaphoreCount: N as _,
544                pSemaphores: slice_as_ptr_empty_null(semaphores) as _,
545                pValues: slice_as_ptr_empty_null(values),
546            },
547            core::marker::PhantomData,
548        )
549    }
550
551    /// Constructs from raw values
552    /// # Safety
553    /// the resource must be created from the device and not freed anywhere
554    pub const unsafe fn from_raw(raw: VkSemaphoreWaitInfoKHR) -> Self {
555        Self(raw, core::marker::PhantomData)
556    }
557
558    pub const fn into_raw(self) -> VkSemaphoreWaitInfoKHR {
559        self.0
560    }
561
562    #[inline(always)]
563    pub const fn for_any(mut self) -> Self {
564        self.0.flags |= VK_SEMAPHORE_WAIT_ANY_BIT_KHR;
565        self
566    }
567
568    #[inline(always)]
569    pub fn with_next(mut self, next: &'n (impl VulkanStructure + ?Sized)) -> Self {
570        self.0.pNext = next.as_generic() as *const _ as _;
571        self
572    }
573}
574#[cfg(feature = "VK_KHR_timeline_semaphore")]
575unsafe impl VulkanStructure for SemaphoreWaitInfo<'_, '_, '_> {
576    #[inline(always)]
577    fn as_generic(&self) -> &GenericVulkanStructure {
578        self.0.as_generic()
579    }
580
581    #[inline(always)]
582    fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
583        self.0.as_generic_mut()
584    }
585}
586
587#[repr(transparent)]
588#[derive(Clone)]
589pub struct EventCreateInfo(VkEventCreateInfo);
590impl EventCreateInfo {
591    pub const fn new() -> Self {
592        Self(VkEventCreateInfo {
593            sType: VkEventCreateInfo::TYPE,
594            pNext: core::ptr::null(),
595            flags: 0,
596        })
597    }
598}
599
600#[derive(VkHandle, VkObject)]
601#[VkObject(type = VkEvent::OBJECT_TYPE)]
602pub struct EventObject<Device: VkHandle<Handle = VkDevice>>(VkEvent, Device);
603#[implements]
604impl<Device: VkHandle<Handle = VkDevice>> Drop for EventObject<Device> {
605    #[inline(always)]
606    fn drop(&mut self) {
607        unsafe {
608            crate::vkfn::destroy_event(self.1.native_ptr(), self.0, core::ptr::null());
609        }
610    }
611}
612unsafe impl<Device: VkHandle<Handle = VkDevice> + Sync> Sync for EventObject<Device> {}
613unsafe impl<Device: VkHandle<Handle = VkDevice> + Send> Send for EventObject<Device> {}
614impl<Device: VkHandle<Handle = VkDevice>> DeviceChildHandle for EventObject<Device> {
615    #[inline(always)]
616    fn device_handle(&self) -> VkDevice {
617        self.1.native_ptr()
618    }
619}
620impl<Device: crate::Device> DeviceChild for EventObject<Device> {
621    type ConcreteDevice = Device;
622
623    #[inline(always)]
624    fn device(&self) -> &Self::ConcreteDevice {
625        &self.1
626    }
627}
628impl<Device: VkHandle<Handle = VkDevice>> Status for EventObject<Device> {
629    #[implements]
630    fn status(&self) -> crate::Result<bool> {
631        match unsafe { crate::vkfn::get_event_status(self.1.native_ptr(), self.0) } {
632            VK_EVENT_SET => Ok(true),
633            VK_EVENT_RESET => Ok(false),
634            vr => Err(vr),
635        }
636    }
637}
638impl<Device: VkHandle<Handle = VkDevice>> EventObject<Device> {
639    /// Constructs from raw values
640    /// # Safety
641    /// the resource must be created from the device and not freed anywhere
642    pub const unsafe fn manage(handle: VkEvent, parent: Device) -> Self {
643        Self(handle, parent)
644    }
645
646    /// Purges the construct (Drop will not be called for this resource)
647    pub const fn unmanage(self) -> (VkEvent, Device) {
648        let h = self.0;
649        let p = unsafe { core::ptr::read(&self.1) };
650        core::mem::forget(self);
651
652        (h, p)
653    }
654}
655impl<Device: VkHandle<Handle = VkDevice> + Clone> EventObject<&'_ Device> {
656    /// Owning parent object by cloning it.
657    #[inline(always)]
658    pub fn clone_parent(self) -> EventObject<Device> {
659        EventObject(self.0, self.1.clone())
660    }
661}
662impl<Device: crate::Device> EventObject<Device> {
663    /// Create a new event object
664    /// # Failure
665    /// On failure, this command returns
666    ///
667    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
668    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
669    #[implements]
670    #[inline]
671    pub fn new(device: Device, create_info: &EventCreateInfo) -> crate::Result<Self> {
672        Ok(unsafe { Self::manage(device.new_event_raw(create_info, None)?, device) })
673    }
674}
675
676#[cfg(feature = "VK_KHR_synchronization2")]
677#[repr(transparent)]
678pub struct SemaphoreSubmitInfo<'s>(
679    VkSemaphoreSubmitInfoKHR,
680    core::marker::PhantomData<&'s dyn VkHandle<Handle = VkSemaphore>>,
681);
682#[cfg(feature = "VK_KHR_synchronization2")]
683impl<'s> SemaphoreSubmitInfo<'s> {
684    #[inline]
685    pub fn new(semaphore: &'s (impl VkHandle<Handle = VkSemaphore> + ?Sized)) -> Self {
686        Self(
687            VkSemaphoreSubmitInfoKHR {
688                sType: VkSemaphoreSubmitInfoKHR::TYPE,
689                pNext: core::ptr::null(),
690                semaphore: semaphore.native_ptr(),
691                value: 0,
692                stageMask: VK_PIPELINE_STAGE_2_NONE_KHR,
693                deviceIndex: 0,
694            },
695            core::marker::PhantomData,
696        )
697    }
698
699    #[inline(always)]
700    pub const fn with_value(mut self, value: u64) -> Self {
701        self.0.value = value;
702        self
703    }
704
705    #[inline(always)]
706    pub const fn with_on_stage(mut self, stage_mask: VkPipelineStageFlags2KHR) -> Self {
707        self.0.stageMask |= stage_mask;
708        self
709    }
710
711    #[inline(always)]
712    pub const fn on_top_of_pipe(self) -> Self {
713        self.with_on_stage(VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR)
714    }
715
716    #[inline(always)]
717    pub const fn on_draw_indirect(self) -> Self {
718        self.with_on_stage(VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR)
719    }
720
721    #[inline(always)]
722    pub const fn on_vertex_input(self) -> Self {
723        self.with_on_stage(VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR)
724    }
725
726    #[inline(always)]
727    pub const fn on_vertex_shader(self) -> Self {
728        self.with_on_stage(VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR)
729    }
730
731    #[inline(always)]
732    pub const fn on_tessellation_control_shader(self) -> Self {
733        self.with_on_stage(VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR)
734    }
735
736    #[inline(always)]
737    pub const fn on_tessellation_evaluation_shader(self) -> Self {
738        self.with_on_stage(VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR)
739    }
740
741    #[inline(always)]
742    pub const fn on_geometry_shader(self) -> Self {
743        self.with_on_stage(VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR)
744    }
745
746    #[inline(always)]
747    pub const fn on_fragment_shader(self) -> Self {
748        self.with_on_stage(VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR)
749    }
750
751    #[inline(always)]
752    pub const fn on_early_fragment_tests(self) -> Self {
753        self.with_on_stage(VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR)
754    }
755
756    #[inline(always)]
757    pub const fn on_late_fragment_tests(self) -> Self {
758        self.with_on_stage(VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR)
759    }
760
761    #[inline(always)]
762    pub const fn on_color_attachment_output(self) -> Self {
763        self.with_on_stage(VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR)
764    }
765
766    #[inline(always)]
767    pub const fn on_compute_shader(self) -> Self {
768        self.with_on_stage(VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR)
769    }
770
771    #[inline(always)]
772    pub const fn on_any_transfer(self) -> Self {
773        self.with_on_stage(VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR)
774    }
775
776    #[inline(always)]
777    pub const fn on_bottom_of_pipe(self) -> Self {
778        self.with_on_stage(VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR)
779    }
780
781    #[inline(always)]
782    pub const fn on_host(self) -> Self {
783        self.with_on_stage(VK_PIPELINE_STAGE_2_HOST_BIT_KHR)
784    }
785
786    #[inline(always)]
787    pub const fn on_any_graphics(self) -> Self {
788        self.with_on_stage(VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR)
789    }
790
791    #[inline(always)]
792    pub const fn on_any_command(self) -> Self {
793        self.with_on_stage(VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR)
794    }
795
796    #[inline(always)]
797    pub const fn on_copy(self) -> Self {
798        self.with_on_stage(VK_PIPELINE_STAGE_2_COPY_BIT_KHR)
799    }
800
801    #[inline(always)]
802    pub const fn on_resolve(self) -> Self {
803        self.with_on_stage(VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR)
804    }
805
806    #[inline(always)]
807    pub const fn on_blit(self) -> Self {
808        self.with_on_stage(VK_PIPELINE_STAGE_2_BLIT_BIT_KHR)
809    }
810
811    #[inline(always)]
812    pub const fn on_clear(self) -> Self {
813        self.with_on_stage(VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR)
814    }
815
816    #[inline(always)]
817    pub const fn on_index_input(self) -> Self {
818        self.with_on_stage(VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR)
819    }
820
821    #[inline(always)]
822    pub const fn on_vertex_attribute_input(self) -> Self {
823        self.with_on_stage(VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR)
824    }
825
826    #[inline(always)]
827    pub const fn on_pre_rasterization_shaders(self) -> Self {
828        self.with_on_stage(VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR)
829    }
830}
831
832#[cfg(feature = "VK_KHR_synchronization2")]
833#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
834#[derives::bitflags_newtype]
835pub struct AccessFlags2(pub VkAccessFlags2KHR);
836#[cfg(feature = "VK_KHR_synchronization2")]
837impl AccessFlags2 {
838    pub const NONE: Self = Self(VK_ACCESS_2_NONE_KHR);
839
840    pub const INDIRECT_COMMAND_READ: Self = Self(VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR);
841    pub const INDEX_READ: Self = Self(VK_ACCESS_2_INDEX_READ_BIT_KHR);
842    pub const VERTEX_ATTRIBUTE_READ: Self = Self(VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR);
843    pub const UNIFORM_READ: Self = Self(VK_ACCESS_2_UNIFORM_READ_BIT_KHR);
844    pub const INPUT_ATTACHMENT_READ: Self = Self(VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR);
845    pub const SHADER: AccessFlags2ReadWriteBits = AccessFlags2ReadWriteBits {
846        read: Self(VK_ACCESS_2_SHADER_READ_BIT_KHR),
847        write: Self(VK_ACCESS_2_SHADER_WRITE_BIT_KHR),
848    };
849    pub const COLOR_ATTACHMENT: AccessFlags2ReadWriteBits = AccessFlags2ReadWriteBits {
850        read: Self(VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR),
851        write: Self(VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR),
852    };
853    pub const DEPTH_STENCIL_ATTACHMENT: AccessFlags2ReadWriteBits = AccessFlags2ReadWriteBits {
854        read: Self(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR),
855        write: Self(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR),
856    };
857    pub const TRANSFER: AccessFlags2ReadWriteBits = AccessFlags2ReadWriteBits {
858        read: Self(VK_ACCESS_2_TRANSFER_READ_BIT_KHR),
859        write: Self(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),
860    };
861    pub const HOST: AccessFlags2ReadWriteBits = AccessFlags2ReadWriteBits {
862        read: Self(VK_ACCESS_2_HOST_READ_BIT_KHR),
863        write: Self(VK_ACCESS_2_HOST_WRITE_BIT_KHR),
864    };
865    pub const MEMORY: AccessFlags2ReadWriteBits = AccessFlags2ReadWriteBits {
866        read: Self(VK_ACCESS_2_MEMORY_READ_BIT_KHR),
867        write: Self(VK_ACCESS_2_MEMORY_WRITE_BIT_KHR),
868    };
869    pub const SHADER_SAMPLED_READ: Self = Self(VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR);
870    pub const SHADER_STORAGE: AccessFlags2ReadWriteBits = AccessFlags2ReadWriteBits {
871        read: Self(VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR),
872        write: Self(VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR),
873    };
874}
875#[cfg(feature = "VK_KHR_synchronization2")]
876impl Default for AccessFlags2 {
877    fn default() -> Self {
878        Self::NONE
879    }
880}
881
882#[cfg(feature = "VK_KHR_synchronization2")]
883pub struct AccessFlags2ReadWriteBits {
884    pub read: AccessFlags2,
885    pub write: AccessFlags2,
886}