vulkayes_core/queue/
macros.rs1#[macro_export]
20macro_rules! const_queue_submit {
21 (
22 $(#[$attribute: meta])*
23 pub fn $name: ident (
24 &queue,
25 $waits: ident: [&Semaphore; $count_waits: literal],
26 stages: [vk::PipelineStageFlags; _],
27 $buffers: ident: [&CommandBuffer; $count_buffers: literal],
28 $signals: ident: [&Semaphore; $count_signals: literal],
29 fence: Option<&Fence>
30 ) -> Result<(), QueueSubmitError>;
31 ) => {
32 $(#[$attribute])*
33 #[allow(unused_variables)]
34 #[allow(unused_imports)]
35 pub fn $name(
36 queue: &$crate::queue::Queue,
37 $waits: [&$crate::sync::semaphore::Semaphore; $count_waits],
38 stages: [$crate::ash::vk::PipelineStageFlags; $count_waits],
39 $buffers: [&$crate::command::buffer::CommandBuffer; $count_buffers],
40 $signals: [&$crate::sync::semaphore::Semaphore; $count_signals],
41 fence: Option<&$crate::sync::fence::Fence>
42 ) -> Result<(), $crate::queue::error::QueueSubmitError> {
43 use $crate::queue::error::QueueSubmitError;
44 use $crate::util::sync::VutexGuard;
45 use $crate::ash::vk;
46
47 #[cfg(feature = "runtime_implicit_validations")]
48 {
49 for stage in stages.iter() {
50 if stage.is_empty() {
51 return Err(QueueSubmitError::WaitStagesEmpty)
52 }
53 }
54 { if !$crate::util::validations::validate_all_match(
56 $waits.iter().map(|w| w.device()).chain(
57 $buffers.iter().map(|b| b.pool().device())
58 ).chain(
59 $signals.iter().map(|s| s.device())
60 )
61 ) {
62 return Err(QueueSubmitError::WaitBufferSignalDeviceMismatch)
63 }
64 }
65 for cb in $buffers.iter() {
66 if cb.pool().queue_family_index() != queue.queue_family_index() {
67 return Err(QueueSubmitError::QueueFamilyMismatch)
68 }
69 }
70 if let Some(ref fence) = fence {
71 if queue.device() != fence.device() {
72 return Err(QueueSubmitError::QueueFenceDeviceMismatch)
73 }
74 }
75 }
76
77 $crate::lock_and_deref_closure!(
78 let [$waits; $count_waits]{.lock().expect("vutex poisoned")} => |$waits: [VutexGuard<vk::Semaphore>; $count_waits], w|
79 let [$buffers; $count_buffers]{.lock().expect("vutex poisoned")} => |$buffers: [VutexGuard<vk::CommandBuffer>; $count_buffers], b|
80 let [$signals; $count_signals]{.lock().expect("vutex poisoned")} => |$signals: [VutexGuard<vk::Semaphore>; $count_signals], s|
81 {
82 let submit_info = vk::SubmitInfo::builder()
83 .wait_semaphores(&w)
84 .wait_dst_stage_mask(&stages)
85 .command_buffers(&b)
86 .signal_semaphores(&s)
87 .build()
88 ;
89
90 unsafe {
91 queue.submit(
92 [submit_info],
93 fence
94 )
95 }
96 }
97 )
98 }
99 }
100}
101
102#[macro_export]
119macro_rules! const_queue_present {
120 (
121 $(#[$attribute: meta])*
122 pub fn $name: ident (
123 &queue,
124 $waits: ident: [&Semaphore; $count_waits: literal],
125 $images: ident: [&SwapchainImage; $count_images: literal],
126 result_for_all: bool
127 ) -> QueuePresentMultipleResult<[QueuePresentResult; _]>;
128 ) => {
129 $(#[$attribute])*
130 #[allow(unused_variables)]
131 #[allow(unused_imports)]
132 pub fn $name(
133 queue: &$crate::queue::Queue,
134 $waits: [&$crate::sync::semaphore::Semaphore; $count_waits],
135 $images: [&$crate::swapchain::image::SwapchainImage; $count_images],
136 result_for_all: bool
137 ) -> $crate::queue::error::QueuePresentMultipleResult<[$crate::queue::error::QueuePresentResult; $count_images]> {
138 use $crate::queue::error::{QueuePresentMultipleResult, QueuePresentResult, QueuePresentResultValue, QueuePresentError};
139 use $crate::util::sync::VutexGuard;
140 use $crate::ash::vk;
141
142 #[cfg(feature = "runtime_implicit_validations")]
143 {
144 if $count_images == 0 {
145 return QueuePresentMultipleResult::Single(
146 Err(QueuePresentError::SwapchainsEmpty)
147 )
148 }
149 if !$crate::util::validations::validate_all_match(
150 $images.iter().map(|&i| i.device().instance()).chain(
151 $waits.iter().map(|&w| w.device().instance())
152 )
153 ) {
154 return QueuePresentMultipleResult::Single(
155 Err(QueuePresentError::SwapchainsSempahoredInstanceMismatch)
156 )
157 }
158 }
159
160 let any_swapchain = $images[0].swapchain();
162
163 let indices = $crate::seq_macro::seq!(
164 N in 0 .. $count_images {
165 [ #( $images[N].index(), )* ]
166 }
167 );
168
169 $crate::lock_and_deref_closure!(
170 let [$waits; $count_waits]{.lock().expect("vutex poisoned")} => |$waits: [VutexGuard<vk::Semaphore>; $count_waits], w|
171 let [$images; $count_images]{.swapchain().lock().expect("vutex poisoned")} => |$images: [VutexGuard<vk::SwapchainKHR>; $count_images], s|
172 {
173 let present_info = vk::PresentInfoKHR::builder()
174 .wait_semaphores(&w)
175 .swapchains(&s)
176 .image_indices(&indices)
177 ;
178
179 if result_for_all {
180 let mut $name = [vk::Result::SUCCESS; $count_images];
182 let present_info = present_info.results(&mut $name);
183 let _ = unsafe {
184 any_swapchain.present(
185 queue,
186 present_info
187 )
188 };
189
190 let result_values: [QueuePresentResult; $count_images] = $crate::seq_macro::seq!(
191 N in 0 .. $count_images {
192 [
193 #(
194 match $name[N] {
195 vk::Result::SUCCESS => Ok(QueuePresentResultValue::SUCCESS),
196 vk::Result::SUBOPTIMAL_KHR => Ok(QueuePresentResultValue::SUBOPTIMAL_KHR),
197 err => Err(err.into())
198 },
199 )*
200 ]
201 }
202 );
203 QueuePresentMultipleResult::Multiple(
204 result_values
205 )
206 } else {
207 unsafe {
208 any_swapchain.present(
209 queue,
210 present_info
211 ).into()
212 }
213 }
214 }
215 )
216 }
217 }
218}