1use crate::ffi_helper::{ArrayFFIExtensions, slice_as_ptr_empty_null};
2use crate::*;
3use core::marker::PhantomData;
4
5#[cfg(feature = "alloc")]
6#[deprecated = "old batching library"]
7pub struct TemporalSubmissionBatchResources {
8 command_buffers: Vec<VkCommandBuffer>,
9 wait_semaphores: Vec<VkSemaphore>,
10 wait_stages: Vec<VkPipelineStageFlags>,
11 signal_semaphores: Vec<VkSemaphore>,
12}
13#[cfg(feature = "alloc")]
14#[allow(deprecated)]
15impl TemporalSubmissionBatchResources {
16 pub const fn new() -> Self {
17 Self {
18 command_buffers: Vec::new(),
19 wait_semaphores: Vec::new(),
20 wait_stages: Vec::new(),
21 signal_semaphores: Vec::new(),
22 }
23 }
24
25 pub fn make_info_struct(&self) -> SubmitInfo {
26 unsafe {
27 SubmitInfo::from_raw(VkSubmitInfo {
28 sType: VkSubmitInfo::TYPE,
29 pNext: std::ptr::null(),
30 commandBufferCount: self.command_buffers.len() as _,
31 pCommandBuffers: self.command_buffers.as_ptr_empty_null(),
32 waitSemaphoreCount: self.wait_semaphores.len() as _,
33 pWaitSemaphores: self.wait_semaphores.as_ptr_empty_null(),
34 pWaitDstStageMask: self.wait_stages.as_ptr_empty_null(),
35 signalSemaphoreCount: self.signal_semaphores.len() as _,
36 pSignalSemaphores: self.signal_semaphores.as_ptr_empty_null(),
37 })
38 }
39 }
40}
41
42#[deprecated = "old batching library"]
43pub trait SubmissionBatch {
44 #[cfg(feature = "alloc")]
45 #[allow(deprecated)]
46 fn collect_resources(&self, target: &mut TemporalSubmissionBatchResources);
47
48 #[cfg(feature = "alloc")]
49 #[allow(deprecated)]
50 #[inline]
51 fn with_command_buffers<'d, CommandBuffer: crate::CommandBuffer + 'd>(
52 self,
53 command_buffers: &'d [CommandBuffer],
54 ) -> SubmissionWithCommandBuffers<'d, Self, CommandBuffer>
55 where
56 Self: Sized,
57 {
58 SubmissionWithCommandBuffers(
59 self,
60 crate::alloc::collect_vec(command_buffers.iter().map(crate::VkHandle::native_ptr)),
61 std::marker::PhantomData,
62 )
63 }
64
65 #[cfg(feature = "alloc")]
66 #[allow(deprecated)]
67 #[inline]
68 fn with_wait_semaphores<'d, Semaphore: crate::Semaphore + 'd>(
69 self,
70 wait_semaphores: &'d [(Semaphore, PipelineStageFlags)],
71 ) -> SubmissionWithWaitSemaphores<'d, Self, Semaphore>
72 where
73 Self: Sized,
74 {
75 let (hs, fs) = crate::alloc::unzip_vec(
76 wait_semaphores
77 .iter()
78 .map(|(a, b)| (crate::VkHandle::native_ptr(a), b.0)),
79 );
80 SubmissionWithWaitSemaphores(self, hs, fs, std::marker::PhantomData)
81 }
82
83 #[cfg(feature = "alloc")]
84 #[allow(deprecated)]
85 #[inline]
86 fn with_signal_semaphores<'d, Semaphore: crate::Semaphore + 'd>(
87 self,
88 signal_semaphores: &'d [Semaphore],
89 ) -> SubmissionWithSignalSemaphores<'d, Self, Semaphore>
90 where
91 Self: Sized,
92 {
93 SubmissionWithSignalSemaphores(
94 self,
95 crate::alloc::collect_vec(signal_semaphores.iter().map(crate::VkHandle::native_ptr)),
96 std::marker::PhantomData,
97 )
98 }
99}
100#[allow(deprecated)]
101impl<T: SubmissionBatch + ?Sized> SubmissionBatch for Box<T> {
102 #[cfg(feature = "alloc")]
103 #[inline]
104 fn collect_resources(&self, target: &mut TemporalSubmissionBatchResources) {
105 T::collect_resources(self, target)
106 }
107}
108
109#[repr(transparent)]
110pub struct SubmitInfo<'r, 'rs, 'n>(
111 VkSubmitInfo,
112 PhantomData<(
113 Option<&'n dyn VulkanStructure>,
114 &'rs [VkHandleRef<'r, VkSemaphore>],
115 &'rs [PipelineStageFlags],
116 &'rs [VkHandleRef<'r, VkCommandBuffer>],
117 &'rs [VkHandleRef<'r, VkSemaphore>],
118 )>,
119);
120impl<'r, 'rs, 'n> SubmitInfo<'r, 'rs, 'n> {
121 pub unsafe fn new_unchecked(
122 wait_semaphores: &'rs [VkHandleRef<'r, VkSemaphore>],
123 wait_semaphore_dst_stages: &'rs [PipelineStageFlags],
124 command_buffers: &'rs [VkHandleRef<'r, VkCommandBuffer>],
125 signal_semaphores: &'rs [VkHandleRef<'r, VkSemaphore>],
126 ) -> Self {
127 Self(
128 VkSubmitInfo {
129 sType: VkSubmitInfo::TYPE,
130 pNext: core::ptr::null(),
131 waitSemaphoreCount: wait_semaphores.len() as _,
132 pWaitSemaphores: slice_as_ptr_empty_null(wait_semaphores) as _,
133 pWaitDstStageMask: slice_as_ptr_empty_null(wait_semaphore_dst_stages) as _,
134 commandBufferCount: command_buffers.len() as _,
135 pCommandBuffers: slice_as_ptr_empty_null(command_buffers) as _,
136 signalSemaphoreCount: signal_semaphores.len() as _,
137 pSignalSemaphores: slice_as_ptr_empty_null(signal_semaphores) as _,
138 },
139 PhantomData,
140 )
141 }
142
143 pub fn new(
144 wait_semaphores: &'rs [VkHandleRef<'r, VkSemaphore>],
145 wait_semaphore_dst_stages: &'rs [PipelineStageFlags],
146 command_buffers: &'rs [VkHandleRef<'r, VkCommandBuffer>],
147 signal_semaphores: &'rs [VkHandleRef<'r, VkSemaphore>],
148 ) -> Self {
149 assert_eq!(wait_semaphores.len(), wait_semaphore_dst_stages.len());
150
151 unsafe {
152 Self::new_unchecked(
153 wait_semaphores,
154 wait_semaphore_dst_stages,
155 command_buffers,
156 signal_semaphores,
157 )
158 }
159 }
160
161 pub const fn new_array<const NW: usize, const NC: usize, const NS: usize>(
162 wait_semaphores: &'rs [VkHandleRef<'r, VkSemaphore>; NW],
163 wait_semaphore_dst_stages: &'rs [PipelineStageFlags; NW],
164 command_buffers: &'rs [VkHandleRef<'r, VkCommandBuffer>; NC],
165 signal_semaphores: &'rs [VkHandleRef<'r, VkSemaphore>; NS],
166 ) -> Self {
167 Self(
168 VkSubmitInfo {
169 sType: VkSubmitInfo::TYPE,
170 pNext: core::ptr::null(),
171 waitSemaphoreCount: NW as _,
172 pWaitSemaphores: slice_as_ptr_empty_null(wait_semaphores) as _,
173 pWaitDstStageMask: slice_as_ptr_empty_null(wait_semaphore_dst_stages) as _,
174 commandBufferCount: NC as _,
175 pCommandBuffers: slice_as_ptr_empty_null(command_buffers) as _,
176 signalSemaphoreCount: NS as _,
177 pSignalSemaphores: slice_as_ptr_empty_null(signal_semaphores) as _,
178 },
179 PhantomData,
180 )
181 }
182
183 pub const unsafe fn from_raw(raw: VkSubmitInfo) -> Self {
184 Self(raw, PhantomData)
185 }
186
187 pub const fn into_raw(self) -> VkSubmitInfo {
188 self.0
189 }
190
191 pub const fn with_next(mut self, next: &'n (impl VulkanStructure + ?Sized)) -> Self {
192 self.0.pNext = next as *const _ as _;
193 self
194 }
195}
196
197#[cfg(feature = "VK_KHR_timeline_semaphore")]
198#[repr(transparent)]
199pub struct TimelineSemaphoreSubmitInfo<'d, 'xs>(
200 VkTimelineSemaphoreSubmitInfoKHR,
201 core::marker::PhantomData<(Option<&'d dyn VulkanStructure>, &'xs [u64])>,
202);
203#[cfg(feature = "VK_KHR_timeline_semaphore")]
204impl<'d, 'xs> TimelineSemaphoreSubmitInfo<'d, 'xs> {
205 pub const fn new(wait_semaphore_values: &'xs [u64], signal_semaphore_values: &'xs [u64]) -> Self {
206 Self(
207 VkTimelineSemaphoreSubmitInfoKHR {
208 sType: VkTimelineSemaphoreSubmitInfoKHR::TYPE,
209 pNext: core::ptr::null(),
210 waitSemaphoreValueCount: wait_semaphore_values.len() as _,
211 pWaitSemaphoreValues: slice_as_ptr_empty_null(wait_semaphore_values) as _,
212 signalSemaphoreValueCount: signal_semaphore_values.len() as _,
213 pSignalSemaphoreValues: slice_as_ptr_empty_null(signal_semaphore_values) as _,
214 },
215 core::marker::PhantomData,
216 )
217 }
218
219 pub const unsafe fn from_raw(raw: VkTimelineSemaphoreSubmitInfoKHR) -> Self {
220 Self(raw, core::marker::PhantomData)
221 }
222
223 pub const fn into_raw(self) -> VkTimelineSemaphoreSubmitInfoKHR {
224 self.0
225 }
226
227 #[inline(always)]
228 pub fn with_next(mut self, next: &'d (impl VulkanStructure + ?Sized)) -> Self {
229 self.0.pNext = next.as_generic() as *const _ as _;
230 self
231 }
232}
233#[cfg(feature = "VK_KHR_timeline_semaphore")]
234unsafe impl VulkanStructure for TimelineSemaphoreSubmitInfo<'_, '_> {
235 #[inline(always)]
236 fn as_generic(&self) -> &GenericVulkanStructure {
237 self.0.as_generic()
238 }
239
240 #[inline(always)]
241 fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
242 self.0.as_generic_mut()
243 }
244}
245
246#[deprecated = "old batching library"]
247pub struct EmptySubmissionBatch;
248#[allow(deprecated)]
249impl SubmissionBatch for EmptySubmissionBatch {
250 #[cfg(feature = "alloc")]
251 fn collect_resources(&self, _: &mut TemporalSubmissionBatchResources) {}
252}
253#[cfg(feature = "alloc")]
254#[deprecated = "old batching library"]
255#[allow(deprecated)]
256pub struct SubmissionWithCommandBuffers<'d, Parent: SubmissionBatch, CommandBuffer: crate::CommandBuffer + 'd>(
257 Parent,
258 Vec<VkCommandBuffer>,
259 std::marker::PhantomData<&'d [CommandBuffer]>,
260);
261#[cfg(feature = "alloc")]
262#[allow(deprecated)]
263impl<'d, Parent, CommandBuffer> SubmissionBatch for SubmissionWithCommandBuffers<'d, Parent, CommandBuffer>
264where
265 Parent: SubmissionBatch,
266 CommandBuffer: crate::CommandBuffer + 'd,
267{
268 #[inline]
269 fn collect_resources(&self, target: &mut TemporalSubmissionBatchResources) {
270 self.0.collect_resources(target);
271 target.command_buffers.extend(self.1.iter().copied());
272 }
273}
274#[cfg(feature = "alloc")]
275#[deprecated = "old batching library"]
276#[allow(deprecated)]
277pub struct SubmissionWithWaitSemaphores<'d, Parent: SubmissionBatch, Semaphore: crate::Semaphore + 'd>(
278 Parent,
279 Vec<VkSemaphore>,
280 Vec<VkPipelineStageFlags>,
281 std::marker::PhantomData<&'d [Semaphore]>,
282);
283#[cfg(feature = "alloc")]
284#[allow(deprecated)]
285impl<'d, Parent, Semaphore> SubmissionBatch for SubmissionWithWaitSemaphores<'d, Parent, Semaphore>
286where
287 Parent: SubmissionBatch,
288 Semaphore: crate::Semaphore + 'd,
289{
290 #[inline]
291 fn collect_resources(&self, target: &mut TemporalSubmissionBatchResources) {
292 self.0.collect_resources(target);
293 target.wait_semaphores.extend(self.1.iter().copied());
294 target.wait_stages.extend(self.2.iter().copied());
295 }
296}
297#[cfg(feature = "alloc")]
298#[deprecated = "old batching library"]
299#[allow(deprecated)]
300pub struct SubmissionWithSignalSemaphores<'d, Parent: SubmissionBatch, Semaphore: crate::Semaphore + 'd>(
301 Parent,
302 Vec<VkSemaphore>,
303 std::marker::PhantomData<&'d [Semaphore]>,
304);
305#[cfg(feature = "alloc")]
306#[allow(deprecated)]
307impl<'d, Parent, Semaphore> SubmissionBatch for SubmissionWithSignalSemaphores<'d, Parent, Semaphore>
308where
309 Parent: SubmissionBatch,
310 Semaphore: crate::Semaphore + 'd,
311{
312 #[inline]
313 fn collect_resources(&self, target: &mut TemporalSubmissionBatchResources) {
314 self.0.collect_resources(target);
315 target.signal_semaphores.extend(self.1.iter().copied());
316 }
317}
318
319pub trait SparseBindingOpBatch {
320 fn make_info_struct(&self) -> VkBindSparseInfo;
321
322 #[inline]
323 fn with_buffer_binds<'d>(
324 self,
325 buffer_binds: &'d [VkSparseBufferMemoryBindInfo],
326 ) -> SparseBindingOpBatchWithBufferBinds<'d, Self>
327 where
328 Self: Sized,
329 {
330 SparseBindingOpBatchWithBufferBinds(self, buffer_binds)
331 }
332
333 #[inline]
334 fn with_image_binds<'d>(
335 self,
336 buffer_binds: &'d [VkSparseImageMemoryBindInfo],
337 ) -> SparseBindingOpBatchWithImageBinds<'d, Self>
338 where
339 Self: Sized,
340 {
341 SparseBindingOpBatchWithImageBinds(self, buffer_binds)
342 }
343
344 #[inline]
345 fn with_image_opaque_binds<'d>(
346 self,
347 buffer_binds: &'d [VkSparseImageOpaqueMemoryBindInfo],
348 ) -> SparseBindingOpBatchWithImageOpaqueBinds<'d, Self>
349 where
350 Self: Sized,
351 {
352 SparseBindingOpBatchWithImageOpaqueBinds(self, buffer_binds)
353 }
354
355 #[cfg(feature = "alloc")]
356 #[inline]
357 fn with_wait_semaphores<'d, Semaphore: crate::Semaphore + 'd>(
358 self,
359 semaphores: &'d [Semaphore],
360 ) -> SparseBindingOpBatchWithWaitSemaphores<'d, Self, Semaphore>
361 where
362 Self: Sized,
363 {
364 SparseBindingOpBatchWithWaitSemaphores(
365 self,
366 crate::alloc::collect_vec(semaphores.iter().map(crate::VkHandle::native_ptr)),
367 std::marker::PhantomData,
368 )
369 }
370
371 #[cfg(feature = "alloc")]
372 #[inline]
373 fn with_signal_semaphores<'d, Semaphore: crate::Semaphore + 'd>(
374 self,
375 semaphores: &'d [Semaphore],
376 ) -> SparseBindingOpBatchWithSignalSemaphores<'d, Self, Semaphore>
377 where
378 Self: Sized,
379 {
380 SparseBindingOpBatchWithSignalSemaphores(
381 self,
382 crate::alloc::collect_vec(semaphores.iter().map(crate::VkHandle::native_ptr)),
383 std::marker::PhantomData,
384 )
385 }
386}
387impl SparseBindingOpBatch for VkBindSparseInfo {
388 #[inline]
389 fn make_info_struct(&self) -> VkBindSparseInfo {
390 self.clone()
391 }
392}
393
394pub struct EmptyBindingOpBatch;
395impl SparseBindingOpBatch for EmptyBindingOpBatch {
396 #[inline]
397 fn make_info_struct(&self) -> VkBindSparseInfo {
398 VkBindSparseInfo {
399 sType: VkBindSparseInfo::TYPE,
400 pNext: std::ptr::null(),
401 waitSemaphoreCount: 0,
402 pWaitSemaphores: std::ptr::null(),
403 bufferBindCount: 0,
404 pBufferBinds: std::ptr::null(),
405 imageBindCount: 0,
406 pImageBinds: std::ptr::null(),
407 imageOpaqueBindCount: 0,
408 pImageOpaqueBinds: std::ptr::null(),
409 signalSemaphoreCount: 0,
410 pSignalSemaphores: std::ptr::null(),
411 }
412 }
413}
414pub struct SparseBindingOpBatchWithBufferBinds<'d, Parent: SparseBindingOpBatch>(
415 Parent,
416 &'d [VkSparseBufferMemoryBindInfo],
417);
418impl<'d, Parent: SparseBindingOpBatch> SparseBindingOpBatch for SparseBindingOpBatchWithBufferBinds<'d, Parent> {
419 #[inline]
420 fn make_info_struct(&self) -> VkBindSparseInfo {
421 VkBindSparseInfo {
422 bufferBindCount: self.1.len() as _,
423 pBufferBinds: self.1.as_ptr_empty_null(),
424 ..self.0.make_info_struct()
425 }
426 }
427}
428pub struct SparseBindingOpBatchWithImageBinds<'d, Parent: SparseBindingOpBatch>(
429 Parent,
430 &'d [VkSparseImageMemoryBindInfo],
431);
432impl<'d, Parent: SparseBindingOpBatch> SparseBindingOpBatch for SparseBindingOpBatchWithImageBinds<'d, Parent> {
433 #[inline]
434 fn make_info_struct(&self) -> VkBindSparseInfo {
435 VkBindSparseInfo {
436 imageBindCount: self.1.len() as _,
437 pImageBinds: self.1.as_ptr_empty_null(),
438 ..self.0.make_info_struct()
439 }
440 }
441}
442pub struct SparseBindingOpBatchWithImageOpaqueBinds<'d, Parent: SparseBindingOpBatch>(
443 Parent,
444 &'d [VkSparseImageOpaqueMemoryBindInfo],
445);
446impl<'d, Parent: SparseBindingOpBatch> SparseBindingOpBatch for SparseBindingOpBatchWithImageOpaqueBinds<'d, Parent> {
447 #[inline]
448 fn make_info_struct(&self) -> VkBindSparseInfo {
449 VkBindSparseInfo {
450 imageOpaqueBindCount: self.1.len() as _,
451 pImageOpaqueBinds: self.1.as_ptr_empty_null(),
452 ..self.0.make_info_struct()
453 }
454 }
455}
456pub struct SparseBindingOpBatchWithWaitSemaphores<'d, Parent: SparseBindingOpBatch, Semaphore: crate::Semaphore + 'd>(
457 Parent,
458 Vec<VkSemaphore>,
459 std::marker::PhantomData<&'d [Semaphore]>,
460);
461impl<'d, Parent: SparseBindingOpBatch, Semaphore: crate::Semaphore + 'd> SparseBindingOpBatch
462 for SparseBindingOpBatchWithWaitSemaphores<'d, Parent, Semaphore>
463{
464 #[inline]
465 fn make_info_struct(&self) -> VkBindSparseInfo {
466 VkBindSparseInfo {
467 waitSemaphoreCount: self.1.len() as _,
468 pWaitSemaphores: self.1.as_ptr_empty_null(),
469 ..self.0.make_info_struct()
470 }
471 }
472}
473pub struct SparseBindingOpBatchWithSignalSemaphores<'d, Parent: SparseBindingOpBatch, Semaphore: crate::Semaphore + 'd>(
474 Parent,
475 Vec<VkSemaphore>,
476 std::marker::PhantomData<&'d [Semaphore]>,
477);
478impl<'d, Parent: SparseBindingOpBatch, Semaphore: crate::Semaphore + 'd> SparseBindingOpBatch
479 for SparseBindingOpBatchWithSignalSemaphores<'d, Parent, Semaphore>
480{
481 #[inline]
482 fn make_info_struct(&self) -> VkBindSparseInfo {
483 VkBindSparseInfo {
484 signalSemaphoreCount: self.1.len() as _,
485 pSignalSemaphores: self.1.as_ptr_empty_null(),
486 ..self.0.make_info_struct()
487 }
488 }
489}