wgpu_hal/vulkan/
semaphore_list.rs1use alloc::vec::Vec;
4use ash::vk;
5use core::mem::MaybeUninit;
6
7#[derive(Debug, PartialEq)]
8pub enum SemaphoreListMode {
9 Wait,
10 Signal,
11}
12
13#[derive(Debug)]
27pub struct SemaphoreList {
28 mode: SemaphoreListMode,
30
31 semaphores: Vec<vk::Semaphore>,
35
36 values: Vec<u64>,
46
47 pub stage_masks: Vec<vk::PipelineStageFlags>,
51}
52
53impl SemaphoreList {
54 pub fn new(mode: SemaphoreListMode) -> Self {
55 Self {
56 mode,
57 semaphores: Vec::new(),
58 values: Vec::new(),
59 stage_masks: Vec::new(),
60 }
61 }
62
63 pub fn is_empty(&self) -> bool {
64 self.semaphores.is_empty()
65 }
66
67 pub fn add_to_submit<'info, 'semaphores: 'info>(
78 wait_semaphores: &'semaphores mut Self,
79 signal_semaphores: &'semaphores mut Self,
80 submit_info: vk::SubmitInfo<'info>,
81 timeline_info: &'info mut MaybeUninit<vk::TimelineSemaphoreSubmitInfo<'info>>,
82 ) -> vk::SubmitInfo<'info> {
83 wait_semaphores.check();
84 signal_semaphores.check();
85
86 assert!(matches!(wait_semaphores.mode, SemaphoreListMode::Wait));
87 assert!(matches!(signal_semaphores.mode, SemaphoreListMode::Signal));
88
89 let timeline_info = timeline_info.write(vk::TimelineSemaphoreSubmitInfo::default());
90
91 let mut uses_timeline = false;
92
93 if !wait_semaphores.values.is_empty() {
94 *timeline_info = timeline_info.wait_semaphore_values(&wait_semaphores.values);
95 uses_timeline = true;
96 }
97
98 if !signal_semaphores.values.is_empty() {
99 *timeline_info = timeline_info.signal_semaphore_values(&signal_semaphores.values);
100 uses_timeline = true;
101 }
102
103 let mut submit_info = submit_info
104 .wait_semaphores(&wait_semaphores.semaphores)
105 .wait_dst_stage_mask(&wait_semaphores.stage_masks)
106 .signal_semaphores(&signal_semaphores.semaphores);
107
108 if uses_timeline {
109 submit_info = submit_info.push_next(timeline_info);
110 }
111
112 submit_info
113 }
114
115 pub fn push_signal(&mut self, semaphore: SemaphoreType) {
117 assert!(matches!(self.mode, SemaphoreListMode::Signal));
118 self.push_inner(semaphore);
119 }
120
121 pub fn push_wait(&mut self, semaphore: SemaphoreType, stage: vk::PipelineStageFlags) {
123 assert!(matches!(self.mode, SemaphoreListMode::Wait));
124
125 self.stage_masks.push(stage);
126 self.push_inner(semaphore);
127 }
128
129 fn push_inner(&mut self, semaphore: SemaphoreType) {
130 match semaphore {
131 SemaphoreType::Binary(semaphore) => {
132 self.semaphores.push(semaphore);
133 if !self.values.is_empty() {
135 self.values.push(!0);
136 }
137 }
138 SemaphoreType::Timeline(semaphore, value) => {
139 self.pad_values();
142 self.semaphores.push(semaphore);
143 self.values.push(value);
144 }
145 }
146
147 self.check();
148 }
149
150 pub fn remove(&mut self, semaphore: vk::Semaphore) -> bool {
153 let mut removed = false;
154 let mut i = 0;
155 while i < self.semaphores.len() {
156 if self.semaphores[i] == semaphore {
157 self.semaphores.swap_remove(i);
158 if !self.values.is_empty() {
159 self.values.swap_remove(i);
160 }
161 if !self.stage_masks.is_empty() {
162 self.stage_masks.swap_remove(i);
163 }
164 removed = true;
165 } else {
166 i += 1;
167 }
168 }
169 self.check();
170 removed
171 }
172
173 pub fn append(&mut self, other: &mut Self) {
175 assert_eq!(self.mode, other.mode);
176
177 if !other.values.is_empty() {
179 self.pad_values();
180 }
181 self.semaphores.append(&mut other.semaphores);
182 self.values.append(&mut other.values);
183 if !self.values.is_empty() {
185 self.pad_values();
186 }
187 self.stage_masks.append(&mut other.stage_masks);
188 self.check();
189 }
190
191 fn pad_values(&mut self) {
196 self.values.resize(self.semaphores.len(), !0);
197 }
198
199 #[track_caller]
200 fn check(&self) {
201 debug_assert!(self.values.is_empty() || self.values.len() == self.semaphores.len());
202 match self.mode {
203 SemaphoreListMode::Wait => {
204 debug_assert!(
205 self.stage_masks.is_empty() || self.stage_masks.len() == self.semaphores.len()
206 );
207 }
208 SemaphoreListMode::Signal => {
209 debug_assert!(self.stage_masks.is_empty());
210 }
211 }
212 }
213}
214
215pub enum SemaphoreType {
216 Binary(vk::Semaphore),
217 Timeline(vk::Semaphore, u64),
218}