Skip to main content

bedrock/
batching.rs

1use bedrock_vk::{self as brvk, TypedVulkanStructure};
2
3use crate::ffi_helper::{ArrayFFIExtensions, slice_as_ptr_empty_null};
4use crate::*;
5use core::marker::PhantomData;
6
7#[cfg(feature = "alloc")]
8#[deprecated = "old batching library"]
9pub struct TemporalSubmissionBatchResources {
10    command_buffers: Vec<brvk::VkCommandBuffer>,
11    wait_semaphores: Vec<brvk::VkSemaphore>,
12    wait_stages: Vec<brvk::VkPipelineStageFlags>,
13    signal_semaphores: Vec<brvk::VkSemaphore>,
14}
15#[cfg(feature = "alloc")]
16#[allow(deprecated)]
17impl TemporalSubmissionBatchResources {
18    pub const fn new() -> Self {
19        Self {
20            command_buffers: Vec::new(),
21            wait_semaphores: Vec::new(),
22            wait_stages: Vec::new(),
23            signal_semaphores: Vec::new(),
24        }
25    }
26
27    pub fn make_info_struct<'a>(&'a self) -> SubmitInfo<'a, 'a, 'a> {
28        unsafe {
29            SubmitInfo::from_raw(brvk::VkSubmitInfo {
30                sType: brvk::VkSubmitInfo::TYPE,
31                pNext: std::ptr::null(),
32                commandBufferCount: self.command_buffers.len() as _,
33                pCommandBuffers: self.command_buffers.as_ptr_empty_null(),
34                waitSemaphoreCount: self.wait_semaphores.len() as _,
35                pWaitSemaphores: self.wait_semaphores.as_ptr_empty_null(),
36                pWaitDstStageMask: self.wait_stages.as_ptr_empty_null(),
37                signalSemaphoreCount: self.signal_semaphores.len() as _,
38                pSignalSemaphores: self.signal_semaphores.as_ptr_empty_null(),
39            })
40        }
41    }
42}
43
44#[deprecated = "old batching library"]
45pub trait SubmissionBatch {
46    #[cfg(feature = "alloc")]
47    #[allow(deprecated)]
48    fn collect_resources(&self, target: &mut TemporalSubmissionBatchResources);
49
50    #[cfg(feature = "alloc")]
51    #[allow(deprecated)]
52    #[inline]
53    fn with_command_buffers<'d, CommandBuffer: crate::CommandBuffer + 'd>(
54        self,
55        command_buffers: &'d [CommandBuffer],
56    ) -> SubmissionWithCommandBuffers<'d, Self, CommandBuffer>
57    where
58        Self: Sized,
59    {
60        SubmissionWithCommandBuffers(
61            self,
62            crate::alloc::collect_vec(command_buffers.iter().map(crate::VkHandle::native_ptr)),
63            std::marker::PhantomData,
64        )
65    }
66
67    #[cfg(feature = "alloc")]
68    #[allow(deprecated)]
69    #[inline]
70    fn with_wait_semaphores<'d, Semaphore: crate::Semaphore + 'd>(
71        self,
72        wait_semaphores: &'d [(Semaphore, PipelineStageFlags)],
73    ) -> SubmissionWithWaitSemaphores<'d, Self, Semaphore>
74    where
75        Self: Sized,
76    {
77        let (hs, fs) = crate::alloc::unzip_vec(
78            wait_semaphores
79                .iter()
80                .map(|(a, b)| (crate::VkHandle::native_ptr(a), b.0)),
81        );
82        SubmissionWithWaitSemaphores(self, hs, fs, std::marker::PhantomData)
83    }
84
85    #[cfg(feature = "alloc")]
86    #[allow(deprecated)]
87    #[inline]
88    fn with_signal_semaphores<'d, Semaphore: crate::Semaphore + 'd>(
89        self,
90        signal_semaphores: &'d [Semaphore],
91    ) -> SubmissionWithSignalSemaphores<'d, Self, Semaphore>
92    where
93        Self: Sized,
94    {
95        SubmissionWithSignalSemaphores(
96            self,
97            crate::alloc::collect_vec(signal_semaphores.iter().map(crate::VkHandle::native_ptr)),
98            std::marker::PhantomData,
99        )
100    }
101}
102#[allow(deprecated)]
103impl<T: SubmissionBatch + ?Sized> SubmissionBatch for Box<T> {
104    #[cfg(feature = "alloc")]
105    #[inline]
106    fn collect_resources(&self, target: &mut TemporalSubmissionBatchResources) {
107        T::collect_resources(self, target)
108    }
109}
110
111#[repr(transparent)]
112pub struct SubmitInfo<'r, 'rs, 'n>(
113    brvk::VkSubmitInfo,
114    #[allow(clippy::type_complexity)]
115    PhantomData<(
116        Option<&'n dyn brvk::VulkanStructure>,
117        &'rs [VkHandleRef<'r, brvk::VkSemaphore>],
118        &'rs [PipelineStageFlags],
119        &'rs [VkHandleRef<'r, brvk::VkCommandBuffer>],
120        &'rs [VkHandleRef<'r, brvk::VkSemaphore>],
121    )>,
122);
123impl<'r, 'rs, 'n> SubmitInfo<'r, 'rs, 'n> {
124    /// # Safety
125    ///
126    /// `wait_semaphores`, `wait_semaphore_dst_stages`, `command_buffers`, and `signal_semaphores` must have same length.
127    pub unsafe fn new_unchecked(
128        wait_semaphores: &'rs [VkHandleRef<'r, brvk::VkSemaphore>],
129        wait_semaphore_dst_stages: &'rs [PipelineStageFlags],
130        command_buffers: &'rs [VkHandleRef<'r, brvk::VkCommandBuffer>],
131        signal_semaphores: &'rs [VkHandleRef<'r, brvk::VkSemaphore>],
132    ) -> Self {
133        Self(
134            brvk::VkSubmitInfo {
135                sType: brvk::VkSubmitInfo::TYPE,
136                pNext: core::ptr::null(),
137                waitSemaphoreCount: wait_semaphores.len() as _,
138                pWaitSemaphores: slice_as_ptr_empty_null(wait_semaphores) as _,
139                pWaitDstStageMask: slice_as_ptr_empty_null(wait_semaphore_dst_stages) as _,
140                commandBufferCount: command_buffers.len() as _,
141                pCommandBuffers: slice_as_ptr_empty_null(command_buffers) as _,
142                signalSemaphoreCount: signal_semaphores.len() as _,
143                pSignalSemaphores: slice_as_ptr_empty_null(signal_semaphores) as _,
144            },
145            PhantomData,
146        )
147    }
148
149    pub fn new(
150        wait_semaphores: &'rs [VkHandleRef<'r, brvk::VkSemaphore>],
151        wait_semaphore_dst_stages: &'rs [PipelineStageFlags],
152        command_buffers: &'rs [VkHandleRef<'r, brvk::VkCommandBuffer>],
153        signal_semaphores: &'rs [VkHandleRef<'r, brvk::VkSemaphore>],
154    ) -> Self {
155        assert_eq!(wait_semaphores.len(), wait_semaphore_dst_stages.len());
156
157        unsafe {
158            Self::new_unchecked(
159                wait_semaphores,
160                wait_semaphore_dst_stages,
161                command_buffers,
162                signal_semaphores,
163            )
164        }
165    }
166
167    pub const fn new_array<const NW: usize, const NC: usize, const NS: usize>(
168        wait_semaphores: &'rs [VkHandleRef<'r, brvk::VkSemaphore>; NW],
169        wait_semaphore_dst_stages: &'rs [PipelineStageFlags; NW],
170        command_buffers: &'rs [VkHandleRef<'r, brvk::VkCommandBuffer>; NC],
171        signal_semaphores: &'rs [VkHandleRef<'r, brvk::VkSemaphore>; NS],
172    ) -> Self {
173        Self(
174            brvk::VkSubmitInfo {
175                sType: brvk::VkSubmitInfo::TYPE,
176                pNext: core::ptr::null(),
177                waitSemaphoreCount: NW as _,
178                pWaitSemaphores: slice_as_ptr_empty_null(wait_semaphores) as _,
179                pWaitDstStageMask: slice_as_ptr_empty_null(wait_semaphore_dst_stages) as _,
180                commandBufferCount: NC as _,
181                pCommandBuffers: slice_as_ptr_empty_null(command_buffers) as _,
182                signalSemaphoreCount: NS as _,
183                pSignalSemaphores: slice_as_ptr_empty_null(signal_semaphores) as _,
184            },
185            PhantomData,
186        )
187    }
188
189    /// # Safety
190    ///
191    /// `raw` must be a valid [`brvk::VkSubmitInfo`] struct.
192    pub const unsafe fn from_raw(raw: brvk::VkSubmitInfo) -> Self {
193        Self(raw, PhantomData)
194    }
195
196    pub const fn into_raw(self) -> brvk::VkSubmitInfo {
197        self.0
198    }
199
200    pub const fn with_next(mut self, next: &'n (impl brvk::VulkanStructure + ?Sized)) -> Self {
201        self.0.pNext = next as *const _ as _;
202        self
203    }
204}
205
206#[cfg(feature = "VK_KHR_timeline_semaphore")]
207#[repr(transparent)]
208pub struct TimelineSemaphoreSubmitInfo<'d, 'xs>(
209    brvk::VkTimelineSemaphoreSubmitInfoKHR,
210    core::marker::PhantomData<(Option<&'d dyn brvk::VulkanStructure>, &'xs [u64])>,
211);
212#[cfg(feature = "VK_KHR_timeline_semaphore")]
213impl<'d, 'xs> TimelineSemaphoreSubmitInfo<'d, 'xs> {
214    pub const fn new(wait_semaphore_values: &'xs [u64], signal_semaphore_values: &'xs [u64]) -> Self {
215        Self(
216            brvk::VkTimelineSemaphoreSubmitInfoKHR {
217                sType: brvk::VkTimelineSemaphoreSubmitInfoKHR::TYPE,
218                pNext: core::ptr::null(),
219                waitSemaphoreValueCount: wait_semaphore_values.len() as _,
220                pWaitSemaphoreValues: slice_as_ptr_empty_null(wait_semaphore_values) as _,
221                signalSemaphoreValueCount: signal_semaphore_values.len() as _,
222                pSignalSemaphoreValues: slice_as_ptr_empty_null(signal_semaphore_values) as _,
223            },
224            core::marker::PhantomData,
225        )
226    }
227
228    /// # Safety
229    ///
230    /// `raw` must be a valid [`VkTimelineSemaphoreSubmitInfoKHR`] struct.
231    pub const unsafe fn from_raw(raw: brvk::VkTimelineSemaphoreSubmitInfoKHR) -> Self {
232        Self(raw, core::marker::PhantomData)
233    }
234
235    pub const fn into_raw(self) -> brvk::VkTimelineSemaphoreSubmitInfoKHR {
236        self.0
237    }
238
239    #[inline(always)]
240    pub fn with_next(mut self, next: &'d (impl brvk::VulkanStructure + ?Sized)) -> Self {
241        self.0.pNext = next.as_generic() as *const _ as _;
242        self
243    }
244}
245#[cfg(feature = "VK_KHR_timeline_semaphore")]
246unsafe impl brvk::VulkanStructure for TimelineSemaphoreSubmitInfo<'_, '_> {
247    #[inline(always)]
248    fn as_generic(&self) -> &brvk::GenericVulkanStructure {
249        self.0.as_generic()
250    }
251
252    #[inline(always)]
253    fn as_generic_mut(&mut self) -> &mut brvk::GenericVulkanStructure {
254        self.0.as_generic_mut()
255    }
256}
257
258#[deprecated = "old batching library"]
259pub struct EmptySubmissionBatch;
260#[allow(deprecated)]
261impl SubmissionBatch for EmptySubmissionBatch {
262    #[cfg(feature = "alloc")]
263    fn collect_resources(&self, _: &mut TemporalSubmissionBatchResources) {}
264}
265#[cfg(feature = "alloc")]
266#[deprecated = "old batching library"]
267#[allow(deprecated)]
268pub struct SubmissionWithCommandBuffers<'d, Parent: SubmissionBatch, CommandBuffer: crate::CommandBuffer + 'd>(
269    Parent,
270    Vec<brvk::VkCommandBuffer>,
271    std::marker::PhantomData<&'d [CommandBuffer]>,
272);
273#[cfg(feature = "alloc")]
274#[allow(deprecated)]
275impl<'d, Parent, CommandBuffer> SubmissionBatch for SubmissionWithCommandBuffers<'d, Parent, CommandBuffer>
276where
277    Parent: SubmissionBatch,
278    CommandBuffer: crate::CommandBuffer + 'd,
279{
280    #[inline]
281    fn collect_resources(&self, target: &mut TemporalSubmissionBatchResources) {
282        self.0.collect_resources(target);
283        target.command_buffers.extend(self.1.iter().copied());
284    }
285}
286#[cfg(feature = "alloc")]
287#[deprecated = "old batching library"]
288#[allow(deprecated)]
289pub struct SubmissionWithWaitSemaphores<'d, Parent: SubmissionBatch, Semaphore: crate::Semaphore + 'd>(
290    Parent,
291    Vec<brvk::VkSemaphore>,
292    Vec<brvk::VkPipelineStageFlags>,
293    std::marker::PhantomData<&'d [Semaphore]>,
294);
295#[cfg(feature = "alloc")]
296#[allow(deprecated)]
297impl<'d, Parent, Semaphore> SubmissionBatch for SubmissionWithWaitSemaphores<'d, Parent, Semaphore>
298where
299    Parent: SubmissionBatch,
300    Semaphore: crate::Semaphore + 'd,
301{
302    #[inline]
303    fn collect_resources(&self, target: &mut TemporalSubmissionBatchResources) {
304        self.0.collect_resources(target);
305        target.wait_semaphores.extend(self.1.iter().copied());
306        target.wait_stages.extend(self.2.iter().copied());
307    }
308}
309#[cfg(feature = "alloc")]
310#[deprecated = "old batching library"]
311#[allow(deprecated)]
312pub struct SubmissionWithSignalSemaphores<'d, Parent: SubmissionBatch, Semaphore: crate::Semaphore + 'd>(
313    Parent,
314    Vec<brvk::VkSemaphore>,
315    std::marker::PhantomData<&'d [Semaphore]>,
316);
317#[cfg(feature = "alloc")]
318#[allow(deprecated)]
319impl<'d, Parent, Semaphore> SubmissionBatch for SubmissionWithSignalSemaphores<'d, Parent, Semaphore>
320where
321    Parent: SubmissionBatch,
322    Semaphore: crate::Semaphore + 'd,
323{
324    #[inline]
325    fn collect_resources(&self, target: &mut TemporalSubmissionBatchResources) {
326        self.0.collect_resources(target);
327        target.signal_semaphores.extend(self.1.iter().copied());
328    }
329}
330
331pub trait SparseBindingOpBatch {
332    fn make_info_struct<'a>(&'a self) -> BindSparseInfo<'a>;
333
334    #[inline]
335    fn with_buffer_binds<'d>(
336        self,
337        buffer_binds: &'d [brvk::VkSparseBufferMemoryBindInfo],
338    ) -> SparseBindingOpBatchWithBufferBinds<'d, Self>
339    where
340        Self: Sized,
341    {
342        SparseBindingOpBatchWithBufferBinds(self, buffer_binds)
343    }
344
345    #[inline]
346    fn with_image_binds<'d>(
347        self,
348        buffer_binds: &'d [brvk::VkSparseImageMemoryBindInfo],
349    ) -> SparseBindingOpBatchWithImageBinds<'d, Self>
350    where
351        Self: Sized,
352    {
353        SparseBindingOpBatchWithImageBinds(self, buffer_binds)
354    }
355
356    #[inline]
357    fn with_image_opaque_binds<'d>(
358        self,
359        buffer_binds: &'d [brvk::VkSparseImageOpaqueMemoryBindInfo],
360    ) -> SparseBindingOpBatchWithImageOpaqueBinds<'d, Self>
361    where
362        Self: Sized,
363    {
364        SparseBindingOpBatchWithImageOpaqueBinds(self, buffer_binds)
365    }
366
367    #[cfg(feature = "alloc")]
368    #[inline]
369    fn with_wait_semaphores<'d, Semaphore: crate::Semaphore + 'd>(
370        self,
371        semaphores: &'d [Semaphore],
372    ) -> SparseBindingOpBatchWithWaitSemaphores<'d, Self, Semaphore>
373    where
374        Self: Sized,
375    {
376        SparseBindingOpBatchWithWaitSemaphores(
377            self,
378            crate::alloc::collect_vec(semaphores.iter().map(crate::VkHandle::native_ptr)),
379            std::marker::PhantomData,
380        )
381    }
382
383    #[cfg(feature = "alloc")]
384    #[inline]
385    fn with_signal_semaphores<'d, Semaphore: crate::Semaphore + 'd>(
386        self,
387        semaphores: &'d [Semaphore],
388    ) -> SparseBindingOpBatchWithSignalSemaphores<'d, Self, Semaphore>
389    where
390        Self: Sized,
391    {
392        SparseBindingOpBatchWithSignalSemaphores(
393            self,
394            crate::alloc::collect_vec(semaphores.iter().map(crate::VkHandle::native_ptr)),
395            std::marker::PhantomData,
396        )
397    }
398}
399impl SparseBindingOpBatch for BindSparseInfo<'_> {
400    #[inline]
401    fn make_info_struct<'a>(&'a self) -> BindSparseInfo<'a> {
402        unsafe { BindSparseInfo::from_raw(self.as_raw_ref().clone()) }
403    }
404}
405
406pub struct EmptyBindingOpBatch;
407impl SparseBindingOpBatch for EmptyBindingOpBatch {
408    #[inline]
409    fn make_info_struct<'a>(&'a self) -> BindSparseInfo<'a> {
410        unsafe {
411            BindSparseInfo::from_raw(brvk::VkBindSparseInfo {
412                sType: brvk::VkBindSparseInfo::TYPE,
413                pNext: std::ptr::null(),
414                waitSemaphoreCount: 0,
415                pWaitSemaphores: std::ptr::null(),
416                bufferBindCount: 0,
417                pBufferBinds: std::ptr::null(),
418                imageBindCount: 0,
419                pImageBinds: std::ptr::null(),
420                imageOpaqueBindCount: 0,
421                pImageOpaqueBinds: std::ptr::null(),
422                signalSemaphoreCount: 0,
423                pSignalSemaphores: std::ptr::null(),
424            })
425        }
426    }
427}
428pub struct SparseBindingOpBatchWithBufferBinds<'d, Parent: SparseBindingOpBatch>(
429    Parent,
430    &'d [brvk::VkSparseBufferMemoryBindInfo],
431);
432impl<'d, Parent: SparseBindingOpBatch> SparseBindingOpBatch for SparseBindingOpBatchWithBufferBinds<'d, Parent> {
433    #[inline]
434    fn make_info_struct<'a>(&'a self) -> BindSparseInfo<'a> {
435        unsafe {
436            BindSparseInfo::from_raw(brvk::VkBindSparseInfo {
437                bufferBindCount: self.1.len() as _,
438                pBufferBinds: self.1.as_ptr_empty_null(),
439                ..self.0.make_info_struct().into_raw()
440            })
441        }
442    }
443}
444pub struct SparseBindingOpBatchWithImageBinds<'d, Parent: SparseBindingOpBatch>(
445    Parent,
446    &'d [brvk::VkSparseImageMemoryBindInfo],
447);
448impl<'d, Parent: SparseBindingOpBatch> SparseBindingOpBatch for SparseBindingOpBatchWithImageBinds<'d, Parent> {
449    #[inline]
450    fn make_info_struct<'a>(&'a self) -> BindSparseInfo<'a> {
451        unsafe {
452            BindSparseInfo::from_raw(brvk::VkBindSparseInfo {
453                imageBindCount: self.1.len() as _,
454                pImageBinds: self.1.as_ptr_empty_null(),
455                ..self.0.make_info_struct().into_raw()
456            })
457        }
458    }
459}
460pub struct SparseBindingOpBatchWithImageOpaqueBinds<'d, Parent: SparseBindingOpBatch>(
461    Parent,
462    &'d [brvk::VkSparseImageOpaqueMemoryBindInfo],
463);
464impl<'d, Parent: SparseBindingOpBatch> SparseBindingOpBatch for SparseBindingOpBatchWithImageOpaqueBinds<'d, Parent> {
465    #[inline]
466    fn make_info_struct<'a>(&'a self) -> BindSparseInfo<'a> {
467        unsafe {
468            BindSparseInfo::from_raw(brvk::VkBindSparseInfo {
469                imageOpaqueBindCount: self.1.len() as _,
470                pImageOpaqueBinds: self.1.as_ptr_empty_null(),
471                ..self.0.make_info_struct().into_raw()
472            })
473        }
474    }
475}
476pub struct SparseBindingOpBatchWithWaitSemaphores<'d, Parent: SparseBindingOpBatch, Semaphore: crate::Semaphore + 'd>(
477    Parent,
478    Vec<brvk::VkSemaphore>,
479    std::marker::PhantomData<&'d [Semaphore]>,
480);
481impl<'d, Parent: SparseBindingOpBatch, Semaphore: crate::Semaphore + 'd> SparseBindingOpBatch
482    for SparseBindingOpBatchWithWaitSemaphores<'d, Parent, Semaphore>
483{
484    #[inline]
485    fn make_info_struct<'a>(&'a self) -> BindSparseInfo<'a> {
486        unsafe {
487            BindSparseInfo::from_raw(brvk::VkBindSparseInfo {
488                waitSemaphoreCount: self.1.len() as _,
489                pWaitSemaphores: self.1.as_ptr_empty_null(),
490                ..self.0.make_info_struct().into_raw()
491            })
492        }
493    }
494}
495pub struct SparseBindingOpBatchWithSignalSemaphores<'d, Parent: SparseBindingOpBatch, Semaphore: crate::Semaphore + 'd>(
496    Parent,
497    Vec<brvk::VkSemaphore>,
498    std::marker::PhantomData<&'d [Semaphore]>,
499);
500impl<'d, Parent: SparseBindingOpBatch, Semaphore: crate::Semaphore + 'd> SparseBindingOpBatch
501    for SparseBindingOpBatchWithSignalSemaphores<'d, Parent, Semaphore>
502{
503    #[inline]
504    fn make_info_struct<'a>(&'a self) -> BindSparseInfo<'a> {
505        unsafe {
506            BindSparseInfo::from_raw(brvk::VkBindSparseInfo {
507                signalSemaphoreCount: self.1.len() as _,
508                pSignalSemaphores: self.1.as_ptr_empty_null(),
509                ..self.0.make_info_struct().into_raw()
510            })
511        }
512    }
513}
514
515#[repr(transparent)]
516pub struct BindSparseInfo<'a> {
517    vk: brvk::VkBindSparseInfo,
518    _wait_semaphores: core::marker::PhantomData<&'a [VkHandleRef<'a, brvk::VkSemaphore>]>,
519    _signal_semaphores: core::marker::PhantomData<&'a [VkHandleRef<'a, brvk::VkSemaphore>]>,
520    _buffer_binds: core::marker::PhantomData<&'a [SparseBufferMemoryBindInfo<'a>]>,
521    _image_binds: core::marker::PhantomData<&'a [SparseImageMemoryBindInfo<'a>]>,
522    _image_opaque_binds: core::marker::PhantomData<&'a [SparseImageOpaqueMemoryBindInfo<'a>]>,
523}
524impl<'a> BindSparseInfo<'a> {
525    #[inline(always)]
526    pub const fn new() -> Self {
527        unsafe {
528            Self::from_raw(brvk::VkBindSparseInfo {
529                sType: brvk::VkBindSparseInfo::TYPE,
530                pNext: core::ptr::null(),
531                waitSemaphoreCount: 0,
532                pWaitSemaphores: core::ptr::null(),
533                signalSemaphoreCount: 0,
534                pSignalSemaphores: core::ptr::null(),
535                bufferBindCount: 0,
536                pBufferBinds: core::ptr::null(),
537                imageBindCount: 0,
538                pImageBinds: core::ptr::null(),
539                imageOpaqueBindCount: 0,
540                pImageOpaqueBinds: core::ptr::null(),
541            })
542        }
543    }
544
545    #[inline(always)]
546    pub const fn into_raw(self) -> brvk::VkBindSparseInfo {
547        self.vk
548    }
549
550    /// # Safety
551    ///
552    /// `raw` must be a valid [`VkBindSparseInfo`] struct.
553    pub const unsafe fn from_raw(vk: brvk::VkBindSparseInfo) -> Self {
554        Self {
555            vk,
556            _wait_semaphores: core::marker::PhantomData,
557            _signal_semaphores: core::marker::PhantomData,
558            _buffer_binds: core::marker::PhantomData,
559            _image_binds: core::marker::PhantomData,
560            _image_opaque_binds: core::marker::PhantomData,
561        }
562    }
563
564    pub const fn as_raw_ref(&self) -> &brvk::VkBindSparseInfo {
565        &self.vk
566    }
567
568    pub const unsafe fn as_raw_ref_mut(&mut self) -> &mut brvk::VkBindSparseInfo {
569        &mut self.vk
570    }
571
572    #[inline(always)]
573    pub const fn wait_semaphores(mut self, semaphores: &'a [VkHandleRef<'a, brvk::VkSemaphore>]) -> Self {
574        self.vk.waitSemaphoreCount = semaphores.len() as _;
575        self.vk.pWaitSemaphores = semaphores.as_ptr() as _;
576
577        self
578    }
579
580    #[inline(always)]
581    pub const fn signal_semaphores(mut self, semaphores: &'a [VkHandleRef<'a, brvk::VkSemaphore>]) -> Self {
582        self.vk.signalSemaphoreCount = semaphores.len() as _;
583        self.vk.pSignalSemaphores = semaphores.as_ptr() as _;
584
585        self
586    }
587
588    #[inline(always)]
589    pub const fn buffer_binds(mut self, binds: &'a [SparseBufferMemoryBindInfo<'a>]) -> Self {
590        self.vk.bufferBindCount = binds.len() as _;
591        self.vk.pBufferBinds = binds.as_ptr() as _;
592
593        self
594    }
595
596    #[inline(always)]
597    pub const fn image_binds(mut self, binds: &'a [SparseImageMemoryBindInfo<'a>]) -> Self {
598        self.vk.imageBindCount = binds.len() as _;
599        self.vk.pImageBinds = binds.as_ptr() as _;
600
601        self
602    }
603
604    #[inline(always)]
605    pub const fn image_opaque_binds(mut self, binds: &'a [SparseImageOpaqueMemoryBindInfo<'a>]) -> Self {
606        self.vk.imageOpaqueBindCount = binds.len() as _;
607        self.vk.pImageOpaqueBinds = binds.as_ptr() as _;
608
609        self
610    }
611}
612
613#[repr(transparent)]
614pub struct SparseBufferMemoryBindInfo<'a> {
615    vk: brvk::VkSparseBufferMemoryBindInfo,
616    _buffer: core::marker::PhantomData<&'a dyn VkHandle<Handle = brvk::VkBuffer>>,
617    _binds: core::marker::PhantomData<&'a [SparseMemoryBind<'a>]>,
618}
619impl<'a> SparseBufferMemoryBindInfo<'a> {
620    #[inline(always)]
621    pub fn new(
622        buffer: &'a (impl VkHandle<Handle = brvk::VkBuffer> + ?Sized),
623        binds: &'a [SparseMemoryBind<'a>],
624    ) -> Self {
625        unsafe {
626            Self::from_raw(brvk::VkSparseBufferMemoryBindInfo {
627                buffer: buffer.native_ptr(),
628                bindCount: binds.len() as _,
629                pBinds: binds.as_ptr() as _,
630            })
631        }
632    }
633
634    #[inline(always)]
635    pub const fn into_raw(self) -> brvk::VkSparseBufferMemoryBindInfo {
636        self.vk
637    }
638
639    /// # Safety
640    ///
641    /// `raw` must be a valid [`brvk::VkSparseBufferMemoryBindInfo`] struct.
642    #[inline(always)]
643    pub const unsafe fn from_raw(vk: brvk::VkSparseBufferMemoryBindInfo) -> Self {
644        Self {
645            vk,
646            _buffer: core::marker::PhantomData,
647            _binds: core::marker::PhantomData,
648        }
649    }
650
651    #[inline(always)]
652    pub const fn as_raw_ref(&self) -> &brvk::VkSparseBufferMemoryBindInfo {
653        &self.vk
654    }
655
656    #[inline(always)]
657    pub const unsafe fn as_raw_ref_mut(&mut self) -> &mut brvk::VkSparseBufferMemoryBindInfo {
658        &mut self.vk
659    }
660}
661
662#[repr(transparent)]
663pub struct SparseImageMemoryBindInfo<'a> {
664    vk: brvk::VkSparseImageMemoryBindInfo,
665    _image: core::marker::PhantomData<&'a dyn VkHandle<Handle = brvk::VkImage>>,
666    _binds: core::marker::PhantomData<&'a [SparseImageMemoryBind<'a>]>,
667}
668impl<'a> SparseImageMemoryBindInfo<'a> {
669    #[inline(always)]
670    pub fn new(
671        image: &'a (impl VkHandle<Handle = brvk::VkImage> + ?Sized),
672        binds: &'a [SparseImageMemoryBind<'a>],
673    ) -> Self {
674        unsafe {
675            Self::from_raw(brvk::VkSparseImageMemoryBindInfo {
676                image: image.native_ptr(),
677                bindCount: binds.len() as _,
678                pBinds: binds.as_ptr() as _,
679            })
680        }
681    }
682
683    #[inline(always)]
684    pub const fn into_raw(self) -> brvk::VkSparseImageMemoryBindInfo {
685        self.vk
686    }
687
688    /// # Safety
689    ///
690    /// `raw` must be a valid [`brvk::VkSparseImageMemoryBindInfo`] struct.
691    #[inline(always)]
692    pub const unsafe fn from_raw(vk: brvk::VkSparseImageMemoryBindInfo) -> Self {
693        Self {
694            vk,
695            _image: core::marker::PhantomData,
696            _binds: core::marker::PhantomData,
697        }
698    }
699
700    #[inline(always)]
701    pub const fn as_raw_ref(&self) -> &brvk::VkSparseImageMemoryBindInfo {
702        &self.vk
703    }
704
705    #[inline(always)]
706    pub const unsafe fn as_raw_ref_mut(&mut self) -> &mut brvk::VkSparseImageMemoryBindInfo {
707        &mut self.vk
708    }
709}
710
711#[repr(transparent)]
712pub struct SparseImageOpaqueMemoryBindInfo<'a> {
713    vk: brvk::VkSparseImageOpaqueMemoryBindInfo,
714    _image: core::marker::PhantomData<&'a dyn VkHandle<Handle = brvk::VkImage>>,
715    _binds: core::marker::PhantomData<&'a [SparseMemoryBind<'a>]>,
716}
717impl<'a> SparseImageOpaqueMemoryBindInfo<'a> {
718    #[inline(always)]
719    pub fn new(image: &'a (impl VkHandle<Handle = brvk::VkImage> + ?Sized), binds: &'a [SparseMemoryBind<'a>]) -> Self {
720        unsafe {
721            Self::from_raw(brvk::VkSparseImageOpaqueMemoryBindInfo {
722                image: image.native_ptr(),
723                bindCount: binds.len() as _,
724                pBinds: binds.as_ptr() as _,
725            })
726        }
727    }
728
729    #[inline(always)]
730    pub const fn into_raw(self) -> brvk::VkSparseImageOpaqueMemoryBindInfo {
731        self.vk
732    }
733
734    /// # Safety
735    ///
736    /// `raw` must be a valid [`brvk::VkSparseImageOpaqueMemoryBindInfo`] struct.
737    #[inline(always)]
738    pub const unsafe fn from_raw(vk: brvk::VkSparseImageOpaqueMemoryBindInfo) -> Self {
739        Self {
740            vk,
741            _image: core::marker::PhantomData,
742            _binds: core::marker::PhantomData,
743        }
744    }
745
746    #[inline(always)]
747    pub const fn as_raw_ref(&self) -> &brvk::VkSparseImageOpaqueMemoryBindInfo {
748        &self.vk
749    }
750
751    #[inline(always)]
752    pub const unsafe fn as_raw_ref_mut(&mut self) -> &mut brvk::VkSparseImageOpaqueMemoryBindInfo {
753        &mut self.vk
754    }
755}
756
757#[repr(transparent)]
758pub struct SparseMemoryBind<'a> {
759    vk: brvk::VkSparseMemoryBind,
760    _memory: core::marker::PhantomData<&'a dyn VkHandle<Handle = brvk::VkDeviceMemory>>,
761}
762impl<'a> SparseMemoryBind<'a> {
763    pub fn new(
764        resource_byte_range: core::ops::Range<brvk::VkDeviceSize>,
765        memory: &'a (impl VkHandle<Handle = brvk::VkDeviceMemory> + ?Sized),
766        memory_offset: brvk::VkDeviceSize,
767    ) -> Self {
768        unsafe {
769            Self::from_raw(brvk::VkSparseMemoryBind {
770                resourceOffset: resource_byte_range.start,
771                size: resource_byte_range.end - resource_byte_range.start,
772                memory: memory.native_ptr(),
773                memoryOffset: memory_offset,
774                flags: 0,
775            })
776        }
777    }
778
779    #[inline(always)]
780    pub const fn into_raw(self) -> brvk::VkSparseMemoryBind {
781        self.vk
782    }
783
784    /// # Safety
785    ///
786    /// `raw` must be a valid [`brvk::VkSparseMemoryBind`] struct.
787    #[inline(always)]
788    pub const unsafe fn from_raw(vk: brvk::VkSparseMemoryBind) -> Self {
789        Self {
790            vk,
791            _memory: core::marker::PhantomData,
792        }
793    }
794
795    #[inline(always)]
796    pub const fn as_raw_ref(&self) -> &brvk::VkSparseMemoryBind {
797        &self.vk
798    }
799
800    #[inline(always)]
801    pub const unsafe fn as_raw_ref_mut(&mut self) -> &mut brvk::VkSparseMemoryBind {
802        &mut self.vk
803    }
804}
805
806#[repr(transparent)]
807pub struct SparseImageMemoryBind<'a> {
808    vk: brvk::VkSparseImageMemoryBind,
809    _memory: core::marker::PhantomData<&'a dyn VkHandle<Handle = brvk::VkDeviceMemory>>,
810}
811impl<'a> SparseImageMemoryBind<'a> {
812    pub fn new(
813        subresource: ImageSubresource,
814        offset: brvk::VkOffset3D,
815        extent: brvk::VkExtent3D,
816        memory: &'a (impl VkHandle<Handle = brvk::VkDeviceMemory> + ?Sized),
817        memory_offset: brvk::VkDeviceSize,
818    ) -> Self {
819        unsafe {
820            Self::from_raw(brvk::VkSparseImageMemoryBind {
821                subresource: subresource.0,
822                offset,
823                extent,
824                memory: memory.native_ptr(),
825                memoryOffset: memory_offset,
826                flags: 0,
827            })
828        }
829    }
830
831    #[inline(always)]
832    pub const fn into_raw(self) -> brvk::VkSparseImageMemoryBind {
833        self.vk
834    }
835
836    /// # Safety
837    ///
838    /// `raw` must be a valid [`brvk::VkSparseImageMemoryBind`] struct.
839    #[inline(always)]
840    pub const unsafe fn from_raw(vk: brvk::VkSparseImageMemoryBind) -> Self {
841        Self {
842            vk,
843            _memory: core::marker::PhantomData,
844        }
845    }
846
847    #[inline(always)]
848    pub const fn as_raw_ref(&self) -> &brvk::VkSparseImageMemoryBind {
849        &self.vk
850    }
851
852    #[inline(always)]
853    pub const unsafe fn as_raw_ref_mut(&mut self) -> &mut brvk::VkSparseImageMemoryBind {
854        &mut self.vk
855    }
856}