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#[derive(Debug, Clone, Copy)]
12pub struct BinarySemaphoreHandle(pub(crate) vk::Semaphore);
13
14#[derive(Debug, Clone, Copy)]
16pub struct TimelineSemaphoreHandle(pub(crate) vk::Semaphore);
17
18#[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 pub(crate) fn new(context: Arc<Context>, semaphore: vk::Semaphore) -> Self {
36 Self {
37 context,
38 raw: semaphore,
39 }
40 }
41
42 pub fn handle(&self) -> BinarySemaphoreHandle {
44 BinarySemaphoreHandle(self.raw)
45 }
46
47 #[inline]
49 pub(crate) fn raw(&self) -> vk::Semaphore {
50 self.raw
51 }
52}
53
54#[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 pub(crate) fn new(context: Arc<Context>, semaphore: vk::Semaphore) -> Self {
72 Self {
73 context,
74 raw: semaphore,
75 }
76 }
77
78 pub fn handle(&self) -> TimelineSemaphoreHandle {
80 TimelineSemaphoreHandle(self.raw)
81 }
82
83 #[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 #[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 #[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 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}