asche/
semaphore.rs

1use std::sync::Arc;
2
3use erupt::vk;
4#[cfg(feature = "tracing")]
5use tracing1::error;
6
7use crate::context::Context;
8use crate::{AscheError, Result};
9
10/// A handle of a binary semaphore.
11#[derive(Debug, Clone, Copy)]
12pub struct BinarySemaphoreHandle(pub(crate) vk::Semaphore);
13
14/// A handle of a timeline semaphore.
15#[derive(Debug, Clone, Copy)]
16pub struct TimelineSemaphoreHandle(pub(crate) vk::Semaphore);
17
18/// A binary semaphore.
19#[derive(Debug, Clone)]
20pub struct BinarySemaphore {
21    raw: vk::Semaphore,
22    context: Arc<Context>,
23}
24
25impl Drop for BinarySemaphore {
26    fn drop(&mut self) {
27        unsafe {
28            self.context.device.destroy_semaphore(Some(self.raw), None);
29        };
30    }
31}
32
33impl BinarySemaphore {
34    /// Creates a new semaphore.
35    pub(crate) fn new(context: Arc<Context>, semaphore: vk::Semaphore) -> Self {
36        Self {
37            context,
38            raw: semaphore,
39        }
40    }
41
42    /// Returns the handle of the binary semaphore.
43    pub fn handle(&self) -> BinarySemaphoreHandle {
44        BinarySemaphoreHandle(self.raw)
45    }
46
47    /// The raw Vulkan semaphore handle.
48    #[inline]
49    pub(crate) fn raw(&self) -> vk::Semaphore {
50        self.raw
51    }
52}
53
54/// A semaphore that uses the timeline feature.
55#[derive(Debug)]
56pub struct TimelineSemaphore {
57    pub(crate) raw: vk::Semaphore,
58    context: Arc<Context>,
59}
60
61impl Drop for TimelineSemaphore {
62    fn drop(&mut self) {
63        unsafe {
64            self.context.device.destroy_semaphore(Some(self.raw), None);
65        };
66    }
67}
68
69impl TimelineSemaphore {
70    /// Creates a new timeline semaphore.
71    pub(crate) fn new(context: Arc<Context>, semaphore: vk::Semaphore) -> Self {
72        Self {
73            context,
74            raw: semaphore,
75        }
76    }
77
78    /// Returns the handle of the timeline semaphore.
79    pub fn handle(&self) -> TimelineSemaphoreHandle {
80        TimelineSemaphoreHandle(self.raw)
81    }
82
83    /// Query the timeline value.
84    #[cfg_attr(feature = "profiling", profiling::function)]
85    pub unsafe fn query_value(&self) -> Result<u64> {
86        let value = self
87            .context
88            .device
89            .get_semaphore_counter_value(self.raw)
90            .map_err(|err| {
91                #[cfg(feature = "tracing")]
92                error!("Unable to get a semaphore counter value: {}", err);
93                AscheError::VkResult(err)
94            })?;
95        Ok(value)
96    }
97
98    /// Sets the timeline value.
99    #[cfg_attr(feature = "profiling", profiling::function)]
100    pub unsafe fn set_value(&self, timeline_value: u64) -> Result<()> {
101        let signal_info = vk::SemaphoreSignalInfoBuilder::new()
102            .semaphore(self.raw)
103            .value(timeline_value);
104
105        self.context
106            .device
107            .signal_semaphore(&signal_info)
108            .map_err(|err| {
109                #[cfg(feature = "tracing")]
110                error!("Unable to signal a semaphore: {}", err);
111                AscheError::VkResult(err)
112            })?;
113
114        Ok(())
115    }
116
117    /// Wait for the given timeline value.
118    #[cfg_attr(feature = "profiling", profiling::function)]
119    pub unsafe fn wait_for_value(&self, timeline_value: u64) -> Result<()> {
120        let semaphores = [self.raw];
121        let timeline_values = [timeline_value];
122        let wait_info = vk::SemaphoreWaitInfoBuilder::new()
123            .semaphores(&semaphores)
124            .values(&timeline_values);
125
126        // 10 sec timeout
127        self.context
128            .device
129            .wait_semaphores(&wait_info, 10000000000)
130            .map_err(|err| {
131                #[cfg(feature = "tracing")]
132                error!("Unable to wait for a semaphore: {}", err);
133                AscheError::VkResult(err)
134            })?;
135
136        Ok(())
137    }
138}