Skip to main content

bedrock/
sync.rs

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