vulk_ext/vkx/
semaphore.rs

1use super::*;
2
3pub trait SemaphoreOps {
4    fn handle(&self) -> vk::Semaphore;
5
6    fn submit_info(
7        &self,
8        value: u64,
9        stage_mask: impl Into<vk::PipelineStageFlags2> + Copy,
10    ) -> vk::SemaphoreSubmitInfo {
11        vk::SemaphoreSubmitInfo {
12            s_type: vk::StructureType::SemaphoreSubmitInfo,
13            p_next: null(),
14            semaphore: self.handle(),
15            value,
16            stage_mask: stage_mask.into(),
17            device_index: 0,
18        }
19    }
20}
21
22#[derive(Debug)]
23pub struct TimelineSemaphore {
24    semaphore: vk::Semaphore,
25}
26
27impl TimelineSemaphore {
28    pub unsafe fn create(device: &Device, initial_value: u64) -> Result<Self> {
29        let semaphore_type_create_info = vk::SemaphoreTypeCreateInfo {
30            s_type: vk::StructureType::SemaphoreTypeCreateInfo,
31            p_next: null(),
32            semaphore_type: vk::SemaphoreType::Timeline,
33            initial_value,
34        };
35        let semaphore_create_info = vk::SemaphoreCreateInfo {
36            s_type: vk::StructureType::SemaphoreCreateInfo,
37            p_next: addr_of!(semaphore_type_create_info).cast(),
38            flags: vk::SemaphoreCreateFlags::empty(),
39        };
40        let semaphore = device.create_semaphore(&semaphore_create_info)?;
41        Ok(Self { semaphore })
42    }
43
44    pub unsafe fn destroy(self, device: &Device) {
45        device.destroy_semaphore(self.semaphore);
46    }
47
48    pub unsafe fn wait(&self, device: &Device, value: u64, timeout: u64) -> Result<()> {
49        device.wait_semaphores(
50            &vk::SemaphoreWaitInfo {
51                s_type: vk::StructureType::SemaphoreWaitInfo,
52                p_next: null(),
53                flags: vk::SemaphoreWaitFlagBits::Any.into(),
54                semaphore_count: 1,
55                p_semaphores: &self.semaphore,
56                p_values: [value].as_ptr(),
57            },
58            timeout,
59        )?;
60        Ok(())
61    }
62}
63
64impl SemaphoreOps for TimelineSemaphore {
65    fn handle(&self) -> vk::Semaphore {
66        self.semaphore
67    }
68}
69
70/// [`BinarySemaphore`] is only intended to be used with WSI. Prefer
71/// [`TimelineSemaphore`] for everything else.
72#[derive(Debug)]
73pub struct BinarySemaphore {
74    semaphore: vk::Semaphore,
75}
76
77impl BinarySemaphore {
78    pub unsafe fn create(device: &Device) -> Result<Self> {
79        let semaphore_type_create_info = vk::SemaphoreTypeCreateInfo {
80            s_type: vk::StructureType::SemaphoreTypeCreateInfo,
81            p_next: null(),
82            semaphore_type: vk::SemaphoreType::Binary,
83            initial_value: 0,
84        };
85        let semaphore_create_info = vk::SemaphoreCreateInfo {
86            s_type: vk::StructureType::SemaphoreCreateInfo,
87            p_next: addr_of!(semaphore_type_create_info).cast(),
88            flags: vk::SemaphoreCreateFlags::empty(),
89        };
90        let semaphore = device.create_semaphore(&semaphore_create_info)?;
91        Ok(Self { semaphore })
92    }
93
94    pub unsafe fn destroy(self, device: &Device) {
95        device.destroy_semaphore(self.semaphore);
96    }
97}
98
99impl SemaphoreOps for BinarySemaphore {
100    fn handle(&self) -> vk::Semaphore {
101        self.semaphore
102    }
103}