bedrock/
batching.rs

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}