bedrock/
command.rs

1//! Vulkan Commands
2
3use crate::*;
4use derives::implements;
5
6#[derive(VkHandle, VkObject)]
7#[VkObject(type = VkCommandPool::OBJECT_TYPE)]
8pub struct CommandPoolObject<Device: VkHandle<Handle = VkDevice>>(pub(crate) VkCommandPool, pub(crate) Device);
9#[implements]
10impl<Device: VkHandle<Handle = VkDevice>> Drop for CommandPoolObject<Device> {
11    #[inline(always)]
12    fn drop(&mut self) {
13        unsafe {
14            crate::vkfn::destroy_command_pool(self.1.native_ptr(), self.0, core::ptr::null());
15        }
16    }
17}
18unsafe impl<Device: VkHandle<Handle = VkDevice> + Sync> Sync for CommandPoolObject<Device> {}
19unsafe impl<Device: VkHandle<Handle = VkDevice> + Send> Send for CommandPoolObject<Device> {}
20impl<Device: VkHandle<Handle = VkDevice>> DeviceChildHandle for CommandPoolObject<Device> {
21    #[inline(always)]
22    fn device_handle(&self) -> VkDevice {
23        self.1.native_ptr()
24    }
25}
26impl<Device: crate::Device> DeviceChild for CommandPoolObject<Device> {
27    type ConcreteDevice = Device;
28
29    #[inline(always)]
30    fn device(&self) -> &Self::ConcreteDevice {
31        &self.1
32    }
33}
34impl<Device: crate::Device> CommandPool for CommandPoolObject<Device> {}
35impl<Device: crate::Device> CommandPoolMut for CommandPoolObject<Device> {}
36impl<Device: VkHandle<Handle = VkDevice>> CommandPoolObject<Device> {
37    /// Constructs from raw values
38    /// # Safety
39    /// the resource must be created from the device and not freed anywhere
40    pub const unsafe fn manage(handle: VkCommandPool, parent: Device) -> Self {
41        Self(handle, parent)
42    }
43
44    /// Purges the construct (Drop will not be called for this resource)
45    pub const fn unmanage(self) -> (VkCommandPool, Device) {
46        let h = self.0;
47        let p = unsafe { core::ptr::read(&self.1) };
48        core::mem::forget(self);
49
50        (h, p)
51    }
52}
53impl<Device: VkHandle<Handle = VkDevice> + Clone> CommandPoolObject<&'_ Device> {
54    /// Owning parent object by cloning it.
55    #[inline(always)]
56    pub fn clone_parent(self) -> CommandPoolObject<Device> {
57        let r = CommandPoolObject(self.0, self.1.clone());
58        core::mem::forget(self);
59
60        r
61    }
62}
63impl<Device: crate::Device> CommandPoolObject<Device> {
64    /// Create a new command pool object
65    /// # Failures
66    /// On failure, this command returns
67    ///
68    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
69    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
70    #[implements]
71    #[inline]
72    pub fn new(device: Device, info: &CommandPoolCreateInfo) -> crate::Result<Self> {
73        let h = device.new_command_pool_raw(info, None)?;
74
75        Ok(unsafe { Self::manage(h, device) })
76    }
77}
78
79/// Opaque handle to a command buffer object
80#[repr(transparent)]
81#[derive(VkHandle, VkObject)]
82#[VkObject(type = VkCommandBuffer::OBJECT_TYPE)]
83pub struct CommandBufferObject<Device>(VkCommandBuffer, core::marker::PhantomData<Device>);
84impl<Device> Clone for CommandBufferObject<Device> {
85    #[inline(always)]
86    fn clone(&self) -> Self {
87        Self(self.0, core::marker::PhantomData)
88    }
89}
90impl<Device> Copy for CommandBufferObject<Device> {}
91unsafe impl<Device: Sync> Sync for CommandBufferObject<Device> {}
92unsafe impl<Device: Send> Send for CommandBufferObject<Device> {}
93impl<Device> CommandBuffer for CommandBufferObject<Device> {}
94impl<Device> CommandBufferMut for CommandBufferObject<Device> {}
95impl<Device: VkHandle<Handle = VkDevice>> CommandBufferObject<Device> {
96    /// Allocate command buffers from an existing command pool
97    /// # Failures
98    /// On failure, this command returns
99    ///
100    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
101    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
102    #[implements("alloc")]
103    #[inline]
104    pub fn alloc(device: Device, info: &CommandBufferAllocateInfo) -> crate::Result<Vec<Self>> {
105        let mut hs = vec![VkCommandBuffer::NULL; info.0.commandBufferCount as _];
106
107        unsafe {
108            crate::vkfn::allocate_command_buffers(device.native_ptr(), &info.0, hs.as_mut_ptr()).into_result()?;
109
110            Ok(core::mem::transmute(hs))
111        }
112    }
113
114    /// Allocate a static amount of command buffers from an existing command pool
115    /// # Failures
116    /// On failure, this command returns
117    ///
118    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
119    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
120    #[implements]
121    #[inline]
122    pub fn alloc_array<const N: usize>(
123        device: Device,
124        info: &CommandBufferFixedCountAllocateInfo<'_, N>,
125    ) -> crate::Result<[Self; N]> {
126        let mut hs = [Self(VkCommandBuffer::NULL, core::marker::PhantomData); N];
127
128        unsafe {
129            crate::vkfn::allocate_command_buffers(device.native_ptr(), &info.0, hs.as_mut_ptr() as _).into_result()?;
130
131            Ok(hs)
132        }
133    }
134}
135impl<Device: Clone> CommandBufferObject<&'_ Device> {
136    /// clones internally-referenced parent object
137    pub const fn clone_parent(&self) -> CommandBufferObject<Device> {
138        CommandBufferObject(self.0, core::marker::PhantomData)
139    }
140}
141
142#[repr(transparent)]
143#[derive(Clone)]
144pub struct CommandPoolCreateInfo(VkCommandPoolCreateInfo);
145impl CommandPoolCreateInfo {
146    pub const fn new(queue_family_index: u32) -> Self {
147        Self(VkCommandPoolCreateInfo {
148            sType: VkCommandPoolCreateInfo::TYPE,
149            pNext: core::ptr::null(),
150            flags: 0,
151            queueFamilyIndex: queue_family_index,
152        })
153    }
154
155    pub const unsafe fn from_raw(raw: VkCommandPoolCreateInfo) -> Self {
156        Self(raw)
157    }
158
159    pub const fn into_raw(self) -> VkCommandPoolCreateInfo {
160        self.0
161    }
162
163    pub const fn transient(mut self) -> Self {
164        self.0.flags |= VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
165        self
166    }
167
168    pub const fn individual_resettable(mut self) -> Self {
169        self.0.flags |= VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
170        self
171    }
172}
173
174#[repr(i32)]
175#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
176pub enum CommandBufferLevel {
177    Primary = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
178    Secondary = VK_COMMAND_BUFFER_LEVEL_SECONDARY,
179}
180
181/// Bitmask controlling behavior of a command pool reset.
182#[derive(Debug, Clone, Copy, PartialEq, Eq)]
183#[bitflags_newtype]
184pub struct CommandPoolResetFlags(VkCommandPoolResetFlags);
185impl CommandPoolResetFlags {
186    /// Empty bits.
187    pub const EMPTY: Self = Self(0);
188
189    /// Resetting a command pool recycles all of the resources from the command pool back to the system.
190    pub const RELEASE_RESOURCES: Self = Self(VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
191}
192
193#[repr(transparent)]
194#[derive(Clone)]
195pub struct CommandBufferAllocateInfo<'r>(
196    pub(crate) VkCommandBufferAllocateInfo,
197    core::marker::PhantomData<&'r mut dyn VkHandleMut<Handle = VkCommandPool>>,
198);
199impl<'r> CommandBufferAllocateInfo<'r> {
200    #[inline(always)]
201    pub fn new(
202        command_pool: &'r mut (impl VkHandleMut<Handle = VkCommandPool> + ?Sized),
203        count: u32,
204        level: CommandBufferLevel,
205    ) -> Self {
206        Self(
207            VkCommandBufferAllocateInfo {
208                sType: VkCommandBufferAllocateInfo::TYPE,
209                pNext: core::ptr::null(),
210                commandPool: command_pool.native_ptr_mut(),
211                level: level as _,
212                commandBufferCount: count,
213            },
214            core::marker::PhantomData,
215        )
216    }
217
218    pub const unsafe fn from_raw(raw: VkCommandBufferAllocateInfo) -> Self {
219        Self(raw, core::marker::PhantomData)
220    }
221
222    pub const fn into_raw(self) -> VkCommandBufferAllocateInfo {
223        self.0
224    }
225}
226
227#[repr(transparent)]
228#[derive(Clone)]
229pub struct CommandBufferFixedCountAllocateInfo<'r, const N: usize>(
230    VkCommandBufferAllocateInfo,
231    core::marker::PhantomData<&'r mut dyn VkHandleMut<Handle = VkCommandPool>>,
232);
233impl<'r, const N: usize> CommandBufferFixedCountAllocateInfo<'r, N> {
234    #[inline(always)]
235    pub fn new(
236        command_pool: &'r mut (impl VkHandleMut<Handle = VkCommandPool> + ?Sized),
237        level: CommandBufferLevel,
238    ) -> Self {
239        assert!(N <= u32::MAX as usize, "too many command buffers will be allocated");
240
241        Self(
242            VkCommandBufferAllocateInfo {
243                sType: VkCommandBufferAllocateInfo::TYPE,
244                pNext: core::ptr::null(),
245                commandPool: command_pool.native_ptr_mut(),
246                level: level as _,
247                commandBufferCount: N as _,
248            },
249            core::marker::PhantomData,
250        )
251    }
252}
253
254pub trait CommandPool: VkHandle<Handle = VkCommandPool> + DeviceChild {}
255DerefContainerBracketImpl!(for CommandPool {});
256GuardsImpl!(for CommandPool {});
257
258pub trait CommandPoolMut: CommandPool + VkHandleMut {
259    /// Resets a command pool
260    /// # Safety
261    /// Application cannot use command buffers after this call
262    /// # Failures
263    /// On failure, this command returns
264    ///
265    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
266    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
267    #[implements]
268    unsafe fn reset(&mut self, flags: CommandPoolResetFlags) -> crate::Result<()> {
269        unsafe {
270            crate::vkfn::reset_command_pool(self.device_handle(), self.native_ptr_mut(), flags.bits())
271                .into_result()
272                .map(drop)
273        }
274    }
275
276    /// Free command buffers
277    /// # Safety
278    /// Application cannot use passed command buffers after this call
279    #[implements]
280    unsafe fn free(&mut self, buffers: &[VkHandleRefMut<VkCommandBuffer>]) {
281        unsafe {
282            crate::vkfn::free_command_buffers(
283                self.device().native_ptr(),
284                self.native_ptr_mut(),
285                buffers.len() as _,
286                crate::ffi_helper::slice_as_ptr_empty_null(buffers) as *const _,
287            )
288        }
289    }
290
291    /// Trim a command pool
292    #[implements("VK_KHR_maintenance1")]
293    fn trim_khr(&mut self, flags: CommandPoolTrimFlags)
294    where
295        Self::ConcreteDevice: DeviceMaintenance1Extension,
296    {
297        unsafe {
298            self.device().trim_command_pool_khr_fn().0(self.device_handle(), self.native_ptr_mut(), flags.bits());
299        }
300    }
301
302    /// Trim a command pool
303    #[implements("Allow1_1APIs")]
304    fn trim(&mut self, flags: CommandPoolTrimFlags) {
305        unsafe {
306            crate::vkfn::trim_command_pool(self.device_handle(), self.native_ptr_mut(), flags.bits());
307        }
308    }
309}
310DerefContainerBracketImpl!(for mut CommandPoolMut {});
311GuardsImpl!(for mut CommandPoolMut {});
312
313#[cfg(feature = "VK_KHR_maintenance1")]
314#[derive(Clone, Copy, Debug)]
315#[bitflags_newtype]
316pub struct CommandPoolTrimFlags(VkCommandPoolTrimFlagsKHR);
317#[cfg(feature = "VK_KHR_maintenance1")]
318impl CommandPoolTrimFlags {
319    pub const EMPTY: Self = Self(0);
320}
321
322#[repr(transparent)]
323#[derive(Clone)]
324pub struct CommandBufferBeginInfo<'d>(
325    VkCommandBufferBeginInfo,
326    core::marker::PhantomData<Option<&'d CommandBufferInheritanceInfo<'d>>>,
327);
328impl<'d> CommandBufferBeginInfo<'d> {
329    pub const fn new() -> Self {
330        Self(
331            VkCommandBufferBeginInfo {
332                sType: VkCommandBufferBeginInfo::TYPE,
333                pNext: core::ptr::null(),
334                flags: 0,
335                pInheritanceInfo: core::ptr::null(),
336            },
337            core::marker::PhantomData,
338        )
339    }
340
341    pub const unsafe fn from_raw(raw: VkCommandBufferBeginInfo) -> Self {
342        Self(raw, core::marker::PhantomData)
343    }
344
345    pub const fn into_raw(self) -> VkCommandBufferBeginInfo {
346        self.0
347    }
348
349    pub const fn as_raw_ref(&self) -> &VkCommandBufferBeginInfo {
350        &self.0
351    }
352
353    pub const fn onetime_submit(mut self) -> Self {
354        self.0.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
355        self
356    }
357
358    pub const fn renderpass_continue(mut self) -> Self {
359        self.0.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
360        self
361    }
362
363    pub const fn simultaneous_use(mut self) -> Self {
364        self.0.flags |= VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
365        self
366    }
367
368    pub const fn with_inheritance_info(mut self, info: &'d CommandBufferInheritanceInfo<'d>) -> Self {
369        self.0.pInheritanceInfo = info as *const _ as _;
370        self
371    }
372}
373
374#[repr(transparent)]
375#[derive(Clone)]
376pub struct CommandBufferInheritanceInfo<'d>(
377    VkCommandBufferInheritanceInfo,
378    core::marker::PhantomData<(
379        Option<&'d dyn VkHandle<Handle = VkRenderPass>>,
380        Option<&'d dyn VkHandle<Handle = VkFramebuffer>>,
381    )>,
382);
383impl<'d> CommandBufferInheritanceInfo<'d> {
384    pub const fn new() -> Self {
385        CommandBufferInheritanceInfo(
386            VkCommandBufferInheritanceInfo {
387                sType: VkCommandBufferInheritanceInfo::TYPE,
388                pNext: core::ptr::null(),
389                renderPass: VkRenderPass::NULL,
390                subpass: 0,
391                framebuffer: VkFramebuffer::NULL,
392                occlusionQueryEnable: false as _,
393                queryFlags: 0,
394                pipelineStatistics: 0,
395            },
396            core::marker::PhantomData,
397        )
398    }
399
400    #[inline]
401    pub fn of_rendering(
402        render_pass: SubpassRef<'d, impl VkHandle<Handle = VkRenderPass> + ?Sized>,
403        framebuffer: Option<&'d (impl VkHandle<Handle = VkFramebuffer> + ?Sized)>,
404    ) -> Self {
405        Self::new().rendering(render_pass, framebuffer)
406    }
407
408    #[inline]
409    pub fn rendering(
410        mut self,
411        render_pass: SubpassRef<'d, impl VkHandle<Handle = VkRenderPass> + ?Sized>,
412        framebuffer: Option<&'d (impl VkHandle<Handle = VkFramebuffer> + ?Sized)>,
413    ) -> Self {
414        self.0.renderPass = render_pass.0.native_ptr();
415        self.0.subpass = render_pass.1;
416        self.0.framebuffer = framebuffer.map_or(VkFramebuffer::NULL, VkHandle::native_ptr);
417        self
418    }
419
420    pub const fn occlusion_query(mut self, q: OcclusionQuery) -> Self {
421        self.0.occlusionQueryEnable = match q {
422            OcclusionQuery::Disable => false as _,
423            _ => true as _,
424        };
425        self.0.queryFlags = match q {
426            OcclusionQuery::Precise => VK_QUERY_CONTROL_PRECISE_BIT,
427            _ => 0,
428        };
429        self
430    }
431
432    pub const fn pipeline_statistics(mut self, stats: QueryPipelineStatisticFlags) -> Self {
433        self.0.pipelineStatistics = stats.0;
434        self
435    }
436}
437
438pub trait CommandBuffer: VkHandle<Handle = VkCommandBuffer> {}
439DerefContainerBracketImpl!(for CommandBuffer {});
440GuardsImpl!(for CommandBuffer {});
441
442pub trait CommandBufferMut: CommandBuffer + VkHandleMut {
443    /// Start recording a command buffer
444    /// # Failures
445    /// On failure, this command returns
446    ///
447    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
448    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
449    ///
450    /// # Safety
451    /// The `CommandPool` that this commandBuffer was allocated from must be externally synchronized.
452    #[implements]
453    unsafe fn begin<'d>(&'d mut self, info: &CommandBufferBeginInfo) -> crate::Result<CmdRecord<'d>> {
454        unsafe {
455            crate::vkfn::begin_command_buffer(self.native_ptr_mut(), info.as_raw_ref()).into_result()?;
456        }
457
458        Ok(CmdRecord {
459            ptr: self.as_transparent_ref_mut(),
460        })
461    }
462
463    /// Reset a command buffer to the initial state
464    /// # Failures
465    /// On failure, this command returns
466    ///
467    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
468    ///
469    /// # Safety
470    /// The `CommandPool` that this commandBuffer was allocated from must be externally synchronized.
471    #[implements]
472    #[inline]
473    unsafe fn reset(&mut self, flags: VkCommandBufferResetFlags) -> crate::Result<()> {
474        unsafe {
475            crate::vkfn::reset_command_buffer(self.native_ptr_mut(), flags)
476                .into_result()
477                .map(drop)
478        }
479    }
480
481    /// Locking CommandBuffer with CommandPool to satisfy externally synchronization restriction.
482    /// # Safety
483    /// This command buffer must be allocated from `pool`.
484    unsafe fn synchronize_with<'p, 'b: 'p>(
485        &'b mut self,
486        pool: &'p mut (impl VkHandleMut<Handle = VkCommandPool> + ?Sized),
487    ) -> SynchronizedCommandBuffer<'p, 'b> {
488        SynchronizedCommandBuffer {
489            _pool: pool.as_transparent_ref_mut(),
490            buffer: self.as_transparent_ref_mut(),
491        }
492    }
493}
494DerefContainerBracketImpl!(for mut CommandBufferMut {});
495GuardsImpl!(for mut CommandBufferMut {});
496
497pub struct SynchronizedCommandBuffer<'p, 'b: 'p> {
498    _pool: VkHandleRefMut<'p, VkCommandPool>,
499    #[cfg_attr(not(feature = "Implements"), allow(dead_code))]
500    buffer: VkHandleRefMut<'b, VkCommandBuffer>,
501}
502#[implements]
503impl<'p, 'b: 'p> SynchronizedCommandBuffer<'p, 'b> {
504    /// Constructs the synchronized binding.
505    pub const unsafe fn new_unchecked(
506        pool: VkHandleRefMut<'p, VkCommandPool>,
507        buffer: VkHandleRefMut<'b, VkCommandBuffer>,
508    ) -> Self {
509        Self { _pool: pool, buffer }
510    }
511
512    /// Start recording a command buffer
513    /// # Failures
514    /// On failure, this command returns
515    ///
516    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
517    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
518    #[inline(always)]
519    pub fn begin(&'b mut self, info: &CommandBufferBeginInfo) -> crate::Result<CmdRecord<'b>> {
520        unsafe {
521            crate::vkfn::begin_command_buffer(self.buffer.native_ptr_mut(), info.as_raw_ref()).into_result()?;
522        }
523
524        Ok(CmdRecord {
525            ptr: self.buffer.as_transparent_ref_mut(),
526        })
527    }
528
529    /// Reset a command buffer to the initial state
530    /// # Failures
531    /// On failure, this command returns
532    ///
533    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
534    #[inline(always)]
535    pub fn reset(&mut self, flags: VkCommandBufferResetFlags) -> crate::Result<()> {
536        unsafe {
537            crate::vkfn::reset_command_buffer(self.buffer.native_ptr_mut(), flags)
538                .into_result()
539                .map(drop)
540        }
541    }
542}
543
544/// The recording state of command buffers
545#[must_use = "CmdRecord must be consumed by end() (not closed automatically by drop!)"]
546pub struct CmdRecord<'d> {
547    ptr: VkHandleRefMut<'d, VkCommandBuffer>,
548}
549impl<'d> CmdRecord<'d> {
550    pub const fn new(ptr: VkHandleRefMut<'d, VkCommandBuffer>) -> Self {
551        Self { ptr }
552    }
553
554    #[inline(always)]
555    pub const fn raw_command_buffer_handle_mut(&mut self) -> &mut VkHandleRefMut<'d, VkCommandBuffer> {
556        &mut self.ptr
557    }
558}
559
560/// Common Commands: End Recording
561#[implements]
562impl<'d> CmdRecord<'d> {
563    /// Finish recording a command buffer
564    #[inline]
565    pub fn end(self) -> crate::Result<()> {
566        unsafe {
567            crate::vkfn::end_command_buffer(self.ptr.native_ptr())
568                .into_result()
569                .map(drop)
570        }
571    }
572}
573
574/// Specify how commands in the first subpass of a render pass are provided2
575#[repr(i32)]
576#[derive(Debug, Clone, Copy, PartialEq, Eq)]
577pub enum SubpassContents {
578    /// The contents of the subpass will be recorded inline the primary command buffer
579    Inline = VK_SUBPASS_CONTENTS_INLINE,
580    /// The contents are recorded in secondary command buffers that will be called from the primary command buffer
581    SecondaryCommandBuffers = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS,
582}
583
584/// Specify the bind point of a pipeline object to a command buffer
585#[repr(i32)]
586#[derive(Debug, Clone, Copy, PartialEq, Eq)]
587pub enum PipelineBindPoint {
588    /// Binding as a graphics pipeline
589    Graphics = VK_PIPELINE_BIND_POINT_GRAPHICS,
590    /// Binding as a compute pipeline
591    Compute = VK_PIPELINE_BIND_POINT_COMPUTE,
592}
593
594/// Graphics Commands: Manipulating with Render Passes
595#[implements]
596impl<'d> CmdRecord<'d> {
597    /// Begin a new render pass
598    #[inline]
599    pub fn begin_render_pass(mut self, info: &crate::RenderPassBeginInfo, contents: SubpassContents) -> Self {
600        unsafe {
601            crate::vkfn::cmd_begin_render_pass(self.ptr.native_ptr_mut(), info.as_ref(), contents as _);
602        }
603
604        self
605    }
606
607    /// Transition to the next subpass of a render pass
608    #[inline]
609    pub fn next_subpass(mut self, contents: SubpassContents) -> Self {
610        unsafe {
611            crate::vkfn::cmd_next_subpass(self.ptr.native_ptr_mut(), contents as _);
612        }
613
614        self
615    }
616
617    /// End the current render pass
618    #[inline]
619    pub fn end_render_pass(mut self) -> Self {
620        unsafe { crate::vkfn::cmd_end_render_pass(self.ptr.native_ptr_mut()) };
621
622        self
623    }
624
625    #[cfg(feature = "VK_KHR_create_renderpass2")]
626    #[inline]
627    pub fn begin_render_pass2_khr(
628        mut self,
629        fn_provider: &(impl DeviceCreateRenderPass2Extension + ?Sized),
630        begin_info: &RenderPassBeginInfo,
631        subpass_begin_info: &SubpassBeginInfo,
632    ) -> Self {
633        unsafe {
634            (fn_provider.cmd_begin_render_pass_2_khr_fn().0)(
635                self.ptr.native_ptr_mut(),
636                begin_info as *const _ as _,
637                subpass_begin_info as *const _ as _,
638            );
639        }
640
641        self
642    }
643
644    #[cfg(feature = "Allow1_2APIs")]
645    #[inline]
646    pub fn begin_render_pass2(
647        mut self,
648        begin_info: &RenderPassBeginInfo,
649        subpass_begin_info: &SubpassBeginInfo,
650    ) -> Self {
651        unsafe {
652            crate::vkfn::cmd_begin_render_pass2(
653                self.ptr.native_ptr_mut(),
654                begin_info as *const _ as _,
655                subpass_begin_info as *const _ as _,
656            );
657        }
658
659        self
660    }
661
662    #[cfg(feature = "VK_KHR_create_renderpass2")]
663    #[inline]
664    pub fn next_subpass2_khr(
665        mut self,
666        fn_provider: &(impl DeviceCreateRenderPass2Extension + ?Sized),
667        subpass_begin_info: &SubpassBeginInfo,
668        subpass_end_info: &SubpassEndInfo,
669    ) -> Self {
670        unsafe {
671            (fn_provider.cmd_next_subpass_2_khr_fn().0)(
672                self.ptr.native_ptr_mut(),
673                subpass_begin_info as *const _ as _,
674                subpass_end_info as *const _ as _,
675            );
676        }
677
678        self
679    }
680
681    #[cfg(feature = "Allow1_2APIs")]
682    #[inline]
683    pub fn next_subpass2(mut self, subpass_begin_info: &SubpassBeginInfo, subpass_end_info: &SubpassEndInfo) -> Self {
684        unsafe {
685            crate::vkfn::cmd_next_subpass2(
686                self.ptr.native_ptr_mut(),
687                subpass_begin_info as *const _ as _,
688                subpass_end_info as *const _ as _,
689            );
690        }
691
692        self
693    }
694
695    #[cfg(feature = "VK_KHR_create_renderpass2")]
696    #[inline]
697    pub fn end_render_pass2_khr(
698        mut self,
699        fn_provider: &(impl DeviceCreateRenderPass2Extension + ?Sized),
700        subpass_end_info: &SubpassEndInfo,
701    ) -> Self {
702        unsafe {
703            (fn_provider.cmd_end_render_pass_2_khr_fn().0)(
704                self.ptr.native_ptr_mut(),
705                subpass_end_info as *const _ as _,
706            );
707        }
708
709        self
710    }
711
712    #[cfg(feature = "Allow1_2APIs")]
713    #[inline]
714    pub fn end_render_pass2(mut self, subpass_end_info: &SubpassEndInfo) -> Self {
715        unsafe {
716            crate::vkfn::cmd_end_render_pass2(self.ptr.native_ptr_mut(), subpass_end_info);
717        }
718
719        self
720    }
721}
722
723/// Graphics/Compute Commands: Pipeline Setup
724#[implements]
725impl<'d> CmdRecord<'d> {
726    /// Bind a pipeline object to a command buffer
727    #[inline(always)]
728    pub fn bind_pipeline(
729        mut self,
730        bind_point: PipelineBindPoint,
731        pipeline: &(impl VkHandle<Handle = VkPipeline> + ?Sized),
732    ) -> Self {
733        unsafe {
734            crate::vkfn::cmd_bind_pipeline(self.ptr.native_ptr_mut(), bind_point as _, pipeline.native_ptr());
735        }
736        self
737    }
738
739    /// Binds descriptor sets to a command buffer
740    #[inline(always)]
741    pub fn bind_descriptor_sets(
742        mut self,
743        bind_point: PipelineBindPoint,
744        pipeline_layout: &(impl VkHandle<Handle = VkPipelineLayout> + ?Sized),
745        first: u32,
746        descriptor_sets: &[DescriptorSet],
747        dynamic_offsets: &[u32],
748    ) -> Self {
749        unsafe {
750            crate::vkfn::cmd_bind_descriptor_sets(
751                self.ptr.native_ptr_mut(),
752                bind_point as _,
753                pipeline_layout.native_ptr(),
754                first,
755                descriptor_sets.len() as _,
756                crate::ffi_helper::slice_as_ptr_empty_null(descriptor_sets) as _,
757                dynamic_offsets.len() as _,
758                crate::ffi_helper::slice_as_ptr_empty_null(dynamic_offsets),
759            );
760        }
761
762        self
763    }
764
765    /// Update the value of push constant
766    #[inline(always)]
767    pub fn push_constant<T>(
768        mut self,
769        pipeline_layout: &(impl VkHandle<Handle = VkPipelineLayout> + ?Sized),
770        stage: VkShaderStageFlags,
771        offset: u32,
772        value: &T,
773    ) -> Self {
774        unsafe {
775            crate::vkfn::cmd_push_constants(
776                self.ptr.native_ptr_mut(),
777                pipeline_layout.native_ptr(),
778                stage,
779                offset,
780                core::mem::size_of::<T>() as _,
781                value as *const T as *const _,
782            );
783        }
784        self
785    }
786
787    /// Update the values of push constant
788    #[inline(always)]
789    pub fn push_constant_slice<T>(
790        mut self,
791        pipeline_layout: &(impl VkHandle<Handle = VkPipelineLayout> + ?Sized),
792        stage: VkShaderStageFlags,
793        offset: u32,
794        values: &[T],
795    ) -> Self {
796        unsafe {
797            crate::vkfn::cmd_push_constants(
798                self.ptr.native_ptr_mut(),
799                pipeline_layout.native_ptr(),
800                stage,
801                offset,
802                (core::mem::size_of::<T>() * values.len()) as _,
803                values.as_ptr() as *const _,
804            );
805        }
806        self
807    }
808
809    /// Push descriptor updates into a command buffer
810    #[cfg(feature = "VK_KHR_push_descriptor")]
811    #[inline(always)]
812    pub unsafe fn push_descriptor_set_raw_khr(
813        mut self,
814        fn_provider: &(impl DevicePushDescriptorExtension + ?Sized),
815        bind_point: PipelineBindPoint,
816        pipeline_layout: &(impl VkHandle<Handle = VkPipelineLayout> + ?Sized),
817        set: u32,
818        writes: &[VkWriteDescriptorSet],
819    ) -> Self {
820        unsafe {
821            (fn_provider.cmd_push_descriptor_set_khr_fn().0)(
822                self.ptr.native_ptr_mut(),
823                bind_point as _,
824                pipeline_layout.native_ptr(),
825                set,
826                writes.len() as _,
827                crate::ffi_helper::slice_as_ptr_empty_null(writes),
828            );
829        }
830
831        self
832    }
833
834    /// Push descriptor updates into a command buffer
835    #[cfg(feature = "Allow1_4APIs")]
836    #[inline(always)]
837    pub unsafe fn push_descriptor_set_raw(
838        mut self,
839        bind_point: PipelineBindPoint,
840        pipeline_layout: &(impl VkHandle<Handle = VkPipelineLayout> + ?Sized),
841        set: u32,
842        writes: &[VkWriteDescriptorSet],
843    ) -> Self {
844        unsafe {
845            crate::vkfn::cmd_push_descriptor_set(
846                self.ptr.native_ptr_mut(),
847                bind_point as _,
848                pipeline_layout.native_ptr(),
849                set,
850                writes.len() as _,
851                crate::ffi_helper::slice_as_ptr_empty_null(writes),
852            );
853        }
854
855        self
856    }
857
858    /// Push descriptor updates into a command buffer
859    #[cfg(feature = "VK_KHR_push_descriptor")]
860    #[cfg(feature = "alloc")]
861    #[inline(always)]
862    pub fn push_descriptor_set_alloc_khr(
863        self,
864        fn_provider: &(impl DevicePushDescriptorExtension + ?Sized),
865        bind_point: PipelineBindPoint,
866        pipeline_layout: &(impl VkHandle<Handle = VkPipelineLayout> + ?Sized),
867        set: u32,
868        writes: &[crate::DescriptorSetWriteInfo],
869    ) -> Self {
870        unsafe {
871            self.push_descriptor_set_raw_khr(
872                fn_provider,
873                bind_point,
874                pipeline_layout,
875                set,
876                &crate::alloc::collect_vec(writes.iter().map(|x| x.make_structure())),
877            )
878        }
879    }
880
881    /// Push descriptor updates into a command buffer
882    #[cfg(feature = "Allow1_4APIs")]
883    #[cfg(feature = "alloc")]
884    #[inline]
885    pub fn push_descriptor_set_alloc(
886        self,
887        bind_point: PipelineBindPoint,
888        pipeline_layout: &(impl VkHandle<Handle = VkPipelineLayout> + ?Sized),
889        set: u32,
890        writes: &[crate::DescriptorSetWriteInfo],
891    ) -> Self {
892        unsafe {
893            self.push_descriptor_set_raw(
894                bind_point,
895                pipeline_layout,
896                set,
897                &crate::alloc::collect_vec(writes.iter().map(|x| x.make_structure())),
898            )
899        }
900    }
901}
902
903/// Graphics Commands: Updating dynamic states
904#[implements]
905impl<'d> CmdRecord<'d> {
906    /// Set the viewport on a command buffer
907    #[inline(always)]
908    pub fn set_viewport(mut self, first: u32, viewports: &[Viewport]) -> Self {
909        unsafe {
910            crate::vkfn::cmd_set_viewport(
911                self.ptr.native_ptr_mut(),
912                first,
913                viewports.len() as _,
914                crate::ffi_helper::slice_as_ptr_empty_null(viewports),
915            );
916        }
917        self
918    }
919
920    /// Set the dynamic scissor rectangles on a command buffer
921    #[inline(always)]
922    pub fn set_scissor(mut self, first: u32, scissors: &[Rect2D]) -> Self {
923        unsafe {
924            crate::vkfn::cmd_set_scissor(
925                self.ptr.native_ptr_mut(),
926                first,
927                scissors.len() as _,
928                crate::ffi_helper::slice_as_ptr_empty_null(scissors),
929            );
930        }
931        self
932    }
933
934    /// Set the dynamic line width state
935    #[inline(always)]
936    pub fn set_line_width(mut self, w: f32) -> Self {
937        unsafe {
938            crate::vkfn::cmd_set_line_width(self.ptr.native_ptr_mut(), w);
939        }
940        self
941    }
942
943    /// Set the depth bias dynamic state
944    #[inline(always)]
945    pub fn set_depth_bias(mut self, constant_factor: f32, clamp: f32, slope_factor: f32) -> Self {
946        unsafe {
947            crate::vkfn::cmd_set_depth_bias(self.ptr.native_ptr_mut(), constant_factor, clamp, slope_factor);
948        }
949        self
950    }
951
952    /// Set the values of blend constants
953    #[inline(always)]
954    pub fn set_blend_constants(mut self, blend_constants: &[f32; 4]) -> Self {
955        unsafe {
956            crate::vkfn::cmd_set_blend_constants(self.ptr.native_ptr_mut(), blend_constants.as_ptr());
957        }
958        self
959    }
960
961    /// Set the depth bounds test values for a command buffer
962    #[inline(always)]
963    pub fn set_depth_bounds(mut self, bounds: core::ops::Range<f32>) -> Self {
964        unsafe {
965            crate::vkfn::cmd_set_depth_bounds(self.ptr.native_ptr_mut(), bounds.start, bounds.end);
966        }
967        self
968    }
969
970    /// Set the stencil compare mask dynamic state
971    #[inline(always)]
972    pub fn set_stencil_compare_mask(mut self, face_mask: StencilFaceMask, compare_mask: u32) -> Self {
973        unsafe {
974            crate::vkfn::cmd_set_stencil_compare_mask(self.ptr.native_ptr_mut(), face_mask as _, compare_mask);
975        }
976        self
977    }
978
979    /// Set the stencil write mask dynamic state
980    #[inline(always)]
981    pub fn set_stencil_write_mask(mut self, face_mask: StencilFaceMask, write_mask: u32) -> Self {
982        unsafe {
983            crate::vkfn::cmd_set_stencil_write_mask(self.ptr.native_ptr_mut(), face_mask as _, write_mask);
984        }
985        self
986    }
987
988    /// Set the stencil reference dynamic state
989    #[inline(always)]
990    pub fn set_stencil_reference(mut self, face_mask: StencilFaceMask, reference: u32) -> Self {
991        unsafe {
992            crate::vkfn::cmd_set_stencil_reference(self.ptr.native_ptr_mut(), face_mask as _, reference);
993        }
994        self
995    }
996
997    /// Set the sample locations state
998    #[cfg(feature = "VK_EXT_sample_locations")]
999    #[inline]
1000    pub fn set_sample_locations(
1001        mut self,
1002        fn_provider: &(impl DeviceSampleLocationsExtension + ?Sized),
1003        info: &VkSampleLocationsInfoEXT,
1004    ) -> Self {
1005        unsafe {
1006            (fn_provider.cmd_set_sample_locations_ext_fn().0)(self.ptr.native_ptr_mut(), info);
1007        }
1008
1009        self
1010    }
1011}
1012
1013/// Graphics Commands: Binding Buffers
1014#[implements]
1015impl<'d> CmdRecord<'d> {
1016    /// Bind an index buffer to a command buffer
1017    #[inline(always)]
1018    pub fn bind_index_buffer(
1019        mut self,
1020        buffer: &(impl VkHandle<Handle = VkBuffer> + ?Sized),
1021        offset: usize,
1022        index_type: IndexType,
1023    ) -> Self {
1024        unsafe {
1025            crate::vkfn::cmd_bind_index_buffer(
1026                self.ptr.native_ptr_mut(),
1027                buffer.native_ptr(),
1028                offset as _,
1029                index_type as _,
1030            );
1031        }
1032        self
1033    }
1034
1035    /// Bind vertex buffers to a command buffer
1036    #[inline(always)]
1037    pub fn bind_vertex_buffers(
1038        mut self,
1039        first: u32,
1040        buffers: &[VkHandleRef<VkBuffer>],
1041        offsets: &[DeviceSize],
1042    ) -> Self {
1043        assert_eq!(buffers.len(), offsets.len());
1044
1045        unsafe {
1046            crate::vkfn::cmd_bind_vertex_buffers(
1047                self.ptr.native_ptr_mut(),
1048                first,
1049                buffers.len() as _,
1050                crate::ffi_helper::slice_as_ptr_empty_null(buffers) as _,
1051                crate::ffi_helper::slice_as_ptr_empty_null(offsets),
1052            );
1053        }
1054        self
1055    }
1056
1057    /// Bind vertex buffers to a command buffer
1058    #[inline(always)]
1059    pub fn bind_vertex_buffer_array<const N: usize>(
1060        mut self,
1061        first: u32,
1062        buffers: &[VkHandleRef<VkBuffer>; N],
1063        offsets: &[DeviceSize; N],
1064    ) -> Self {
1065        unsafe {
1066            crate::vkfn::cmd_bind_vertex_buffers(
1067                self.ptr.native_ptr_mut(),
1068                first,
1069                N as _,
1070                crate::ffi_helper::slice_as_ptr_empty_null(buffers) as _,
1071                crate::ffi_helper::slice_as_ptr_empty_null(offsets),
1072            );
1073        }
1074        self
1075    }
1076}
1077
1078/// Graphics Commands: Inside a Render Pass
1079#[implements]
1080impl<'d> CmdRecord<'d> {
1081    /// Draw primitives
1082    #[inline(always)]
1083    pub fn draw(mut self, vertex_count: u32, instance_count: u32, first_vertex: u32, first_instance: u32) -> Self {
1084        unsafe {
1085            crate::vkfn::cmd_draw(
1086                self.ptr.native_ptr_mut(),
1087                vertex_count,
1088                instance_count,
1089                first_vertex,
1090                first_instance,
1091            );
1092        }
1093        self
1094    }
1095
1096    /// Issue an indexed draw into a command buffer
1097    #[inline(always)]
1098    pub fn draw_indexed(
1099        mut self,
1100        index_count: u32,
1101        instance_count: u32,
1102        first_index: u32,
1103        vertex_offset: i32,
1104        first_instance: u32,
1105    ) -> Self {
1106        unsafe {
1107            crate::vkfn::cmd_draw_indexed(
1108                self.ptr.native_ptr_mut(),
1109                index_count,
1110                instance_count,
1111                first_index,
1112                vertex_offset,
1113                first_instance,
1114            );
1115        }
1116        self
1117    }
1118
1119    /// Issue an indirect draw into a command buffer
1120    #[inline(always)]
1121    pub fn draw_indirect(
1122        mut self,
1123        buffer: &(impl VkHandle<Handle = VkBuffer> + ?Sized),
1124        offset: DeviceSize,
1125        draw_count: u32,
1126        stride: u32,
1127    ) -> Self {
1128        unsafe {
1129            crate::vkfn::cmd_draw_indirect(
1130                self.ptr.native_ptr_mut(),
1131                buffer.native_ptr(),
1132                offset,
1133                draw_count,
1134                stride,
1135            );
1136        }
1137        self
1138    }
1139
1140    /// Perform an indexed indirect draw
1141    #[inline(always)]
1142    pub fn draw_indexed_indirect(
1143        mut self,
1144        buffer: &(impl VkHandle<Handle = VkBuffer> + ?Sized),
1145        offset: DeviceSize,
1146        draw_count: u32,
1147        stride: u32,
1148    ) -> Self {
1149        unsafe {
1150            crate::vkfn::cmd_draw_indexed_indirect(
1151                self.ptr.native_ptr_mut(),
1152                buffer.native_ptr(),
1153                offset,
1154                draw_count,
1155                stride,
1156            );
1157        }
1158        self
1159    }
1160}
1161
1162/// Compute Commands: Dispatching kernels
1163#[implements]
1164impl<'d> CmdRecord<'d> {
1165    /// Dispatch compute work items
1166    #[inline(always)]
1167    pub fn dispatch(mut self, group_count_x: u32, group_count_y: u32, group_count_z: u32) -> Self {
1168        unsafe {
1169            crate::vkfn::cmd_dispatch(self.ptr.native_ptr_mut(), group_count_x, group_count_y, group_count_z);
1170        }
1171        self
1172    }
1173
1174    /// Dispatch compute work items using indirect parameters
1175    #[inline(always)]
1176    pub fn dispatch_indirect(
1177        mut self,
1178        buffer: &(impl crate::VkHandle<Handle = VkBuffer> + ?Sized),
1179        offset: DeviceSize,
1180    ) -> Self {
1181        unsafe {
1182            crate::vkfn::cmd_dispatch_indirect(self.ptr.native_ptr_mut(), buffer.native_ptr(), offset);
1183        }
1184        self
1185    }
1186}
1187
1188/// Transfer Commands: Copying resources
1189#[implements]
1190impl<'d> CmdRecord<'d> {
1191    /// Copy data between buffer regions
1192    #[inline(always)]
1193    pub fn copy_buffer(
1194        mut self,
1195        src: &(impl crate::VkHandle<Handle = VkBuffer> + ?Sized),
1196        dst: &(impl crate::VkHandle<Handle = VkBuffer> + ?Sized),
1197        regions: &[BufferCopy],
1198    ) -> Self {
1199        unsafe {
1200            crate::vkfn::cmd_copy_buffer(
1201                self.ptr.native_ptr_mut(),
1202                src.native_ptr(),
1203                dst.native_ptr(),
1204                regions.len() as _,
1205                crate::ffi_helper::slice_as_ptr_empty_null(regions) as _,
1206            );
1207        }
1208        self
1209    }
1210
1211    /// Copy data between images
1212    #[inline(always)]
1213    pub fn copy_image(
1214        mut self,
1215        src: &(impl crate::VkHandle<Handle = VkImage> + ?Sized),
1216        src_layout: ImageLayout,
1217        dst: &(impl crate::VkHandle<Handle = VkImage> + ?Sized),
1218        dst_layout: ImageLayout,
1219        regions: &[ImageCopy],
1220    ) -> Self {
1221        unsafe {
1222            crate::vkfn::cmd_copy_image(
1223                self.ptr.native_ptr_mut(),
1224                src.native_ptr(),
1225                src_layout as _,
1226                dst.native_ptr(),
1227                dst_layout as _,
1228                regions.len() as _,
1229                crate::ffi_helper::slice_as_ptr_empty_null(regions),
1230            );
1231        }
1232        self
1233    }
1234
1235    /// Copy regions of an image, potentially performing format conversion
1236    #[inline(always)]
1237    pub fn blit_image(
1238        mut self,
1239        src: &(impl crate::VkHandle<Handle = VkImage> + ?Sized),
1240        src_layout: ImageLayout,
1241        dst: &(impl crate::VkHandle<Handle = VkImage> + ?Sized),
1242        dst_layout: ImageLayout,
1243        regions: &[VkImageBlit],
1244        filter: FilterMode,
1245    ) -> Self {
1246        unsafe {
1247            crate::vkfn::cmd_blit_image(
1248                self.ptr.native_ptr_mut(),
1249                src.native_ptr(),
1250                src_layout as _,
1251                dst.native_ptr(),
1252                dst_layout as _,
1253                regions.len() as _,
1254                crate::ffi_helper::slice_as_ptr_empty_null(regions),
1255                filter as _,
1256            );
1257        }
1258        self
1259    }
1260
1261    /// Copy data from a buffer into an image
1262    #[inline(always)]
1263    pub fn copy_buffer_to_image(
1264        mut self,
1265        src_buffer: &(impl crate::VkHandle<Handle = VkBuffer> + ?Sized),
1266        dst_image: &(impl crate::VkHandle<Handle = VkImage> + ?Sized),
1267        dst_layout: ImageLayout,
1268        regions: &[VkBufferImageCopy],
1269    ) -> Self {
1270        unsafe {
1271            crate::vkfn::cmd_copy_buffer_to_image(
1272                self.ptr.native_ptr_mut(),
1273                src_buffer.native_ptr(),
1274                dst_image.native_ptr(),
1275                dst_layout as _,
1276                regions.len() as _,
1277                crate::ffi_helper::slice_as_ptr_empty_null(regions),
1278            );
1279        }
1280        self
1281    }
1282
1283    /// Copy image data into a buffer
1284    #[inline(always)]
1285    pub fn copy_image_to_buffer(
1286        mut self,
1287        src_image: &(impl crate::VkHandle<Handle = VkImage> + ?Sized),
1288        src_layout: ImageLayout,
1289        dst_buffer: &(impl crate::VkHandle<Handle = VkBuffer> + ?Sized),
1290        regions: &[VkBufferImageCopy],
1291    ) -> Self {
1292        unsafe {
1293            crate::vkfn::cmd_copy_image_to_buffer(
1294                self.ptr.native_ptr_mut(),
1295                src_image.native_ptr(),
1296                src_layout as _,
1297                dst_buffer.native_ptr(),
1298                regions.len() as _,
1299                crate::ffi_helper::slice_as_ptr_empty_null(regions),
1300            );
1301        }
1302        self
1303    }
1304
1305    /// Update a buffer's contents from host memory
1306    /// # Safety
1307    /// This wrapper does not provide any checks(simply calls underlying api)
1308    #[inline(always)]
1309    pub unsafe fn update_buffer_raw(
1310        mut self,
1311        dst: &(impl crate::VkHandle<Handle = VkBuffer> + ?Sized),
1312        dst_offset: DeviceSize,
1313        size: DeviceSize,
1314        data: *const core::ffi::c_void,
1315    ) -> Self {
1316        unsafe {
1317            crate::vkfn::cmd_update_buffer(self.ptr.native_ptr_mut(), dst.native_ptr(), dst_offset, size, data);
1318        }
1319        self
1320    }
1321
1322    /// Update a buffer's contents from host memory
1323    #[inline(always)]
1324    pub fn update_buffer<T>(
1325        self,
1326        dst: &(impl crate::VkHandle<Handle = VkBuffer> + ?Sized),
1327        dst_offset: DeviceSize,
1328        size: DeviceSize,
1329        data: &T,
1330    ) -> Self {
1331        assert!(
1332            size <= size_of::<T>() as VkDeviceSize,
1333            "Updated size exceeds size of datatype"
1334        );
1335
1336        unsafe { self.update_buffer_raw(dst, dst_offset, size, data as *const _ as _) }
1337    }
1338
1339    /// Update a buffer's contents from host memory(updated entire memory that is length of data size)
1340    #[inline(always)]
1341    pub fn update_buffer_exact<T>(
1342        self,
1343        dst: &(impl crate::VkHandle<Handle = VkBuffer> + ?Sized),
1344        dst_offset: DeviceSize,
1345        data: &T,
1346    ) -> Self {
1347        unsafe { self.update_buffer_raw(dst, dst_offset, core::mem::size_of::<T>() as _, data as *const _ as _) }
1348    }
1349
1350    /// Update a buffer's contents from a slice of host memory
1351    #[inline(always)]
1352    pub fn update_buffer_slice<T>(
1353        self,
1354        dst: &(impl crate::VkHandle<Handle = VkBuffer> + ?Sized),
1355        dst_offset: DeviceSize,
1356        data: &[T],
1357    ) -> Self {
1358        unsafe {
1359            self.update_buffer_raw(
1360                dst,
1361                dst_offset,
1362                (core::mem::size_of::<T>() * data.len()) as _,
1363                data.as_ptr() as _,
1364            )
1365        }
1366    }
1367}
1368
1369/// Graphics/Compute Commands: Transfer-like(clearing/filling) commands
1370#[implements]
1371impl<'d> CmdRecord<'d> {
1372    /// Fill a region of a buffer with a fixed value.
1373    /// `size` is number of bytes to fill
1374    #[inline(always)]
1375    pub fn fill_buffer(
1376        mut self,
1377        dst: &(impl crate::VkHandle<Handle = VkBuffer> + ?Sized),
1378        dst_offset: DeviceSize,
1379        size: DeviceSize,
1380        data: u32,
1381    ) -> Self {
1382        unsafe {
1383            crate::vkfn::cmd_fill_buffer(self.ptr.native_ptr_mut(), dst.native_ptr(), dst_offset, size, data);
1384        }
1385        self
1386    }
1387
1388    /// Clear regions of a color image
1389    #[inline(always)]
1390    pub fn clear_color_image(
1391        mut self,
1392        image: &(impl crate::VkHandle<Handle = VkImage> + ?Sized),
1393        layout: ImageLayout,
1394        colors: &[ClearColorValue],
1395        ranges: &[VkImageSubresourceRange],
1396    ) -> Self {
1397        assert_eq!(colors.len(), ranges.len());
1398
1399        unsafe {
1400            crate::vkfn::cmd_clear_color_image(
1401                self.ptr.native_ptr_mut(),
1402                image.native_ptr(),
1403                layout as _,
1404                crate::ffi_helper::slice_as_ptr_empty_null(colors),
1405                ranges.len() as _,
1406                crate::ffi_helper::slice_as_ptr_empty_null(ranges),
1407            );
1408        }
1409        self
1410    }
1411
1412    /// Fill regions of a combined depth/stencil image
1413    #[inline(always)]
1414    pub fn clear_depth_stencil_image(
1415        mut self,
1416        image: &(impl crate::VkHandle<Handle = VkImage> + ?Sized),
1417        layout: ImageLayout,
1418        depth: f32,
1419        stencil: u32,
1420        ranges: &[VkImageSubresourceRange],
1421    ) -> Self {
1422        unsafe {
1423            crate::vkfn::cmd_clear_depth_stencil_image(
1424                self.ptr.native_ptr_mut(),
1425                image.native_ptr(),
1426                layout as _,
1427                &VkClearDepthStencilValue { depth, stencil },
1428                ranges.len() as _,
1429                crate::ffi_helper::slice_as_ptr_empty_null(ranges),
1430            );
1431        }
1432        self
1433    }
1434
1435    /// Clear regions within currently bound framebuffer attachments
1436    #[inline(always)]
1437    pub fn clear_attachments(mut self, attachments: &[VkClearAttachment], rects: &[VkClearRect]) -> Self {
1438        unsafe {
1439            crate::vkfn::cmd_clear_attachments(
1440                self.ptr.native_ptr_mut(),
1441                attachments.len() as _,
1442                crate::ffi_helper::slice_as_ptr_empty_null(attachments),
1443                rects.len() as _,
1444                crate::ffi_helper::slice_as_ptr_empty_null(rects),
1445            );
1446        }
1447        self
1448    }
1449}
1450
1451/// Graphics Commands: Executing Subcommands
1452#[implements]
1453impl<'d> CmdRecord<'d> {
1454    /// Execute a secondary command buffer from a primary command buffer
1455    /// # Safety
1456    ///
1457    /// Caller must be primary buffer and in the render pass when executing secondary command buffer
1458    #[inline(always)]
1459    pub unsafe fn execute_commands(mut self, buffers: &[VkHandleRef<VkCommandBuffer>]) -> Self {
1460        unsafe {
1461            crate::vkfn::cmd_execute_commands(
1462                self.ptr.native_ptr_mut(),
1463                buffers.len() as _,
1464                crate::ffi_helper::slice_as_ptr_empty_null(buffers) as _,
1465            );
1466        }
1467        self
1468    }
1469}
1470
1471/// Graphics Commands: Resolving an image to another image
1472#[implements]
1473impl<'d> CmdRecord<'d> {
1474    /// Resolve regions of an image
1475    #[inline(always)]
1476    pub fn resolve_image(
1477        mut self,
1478        src: &(impl crate::VkHandle<Handle = VkImage> + ?Sized),
1479        src_layout: ImageLayout,
1480        dst: &(impl crate::VkHandle<Handle = VkImage> + ?Sized),
1481        dst_layout: ImageLayout,
1482        regions: &[VkImageResolve],
1483    ) -> Self {
1484        unsafe {
1485            crate::vkfn::cmd_resolve_image(
1486                self.ptr.native_ptr_mut(),
1487                src.native_ptr(),
1488                src_layout as _,
1489                dst.native_ptr(),
1490                dst_layout as _,
1491                regions.len() as _,
1492                crate::ffi_helper::slice_as_ptr_empty_null(regions),
1493            )
1494        };
1495        self
1496    }
1497}
1498
1499/// Graphics/Compute Commands: Synchronization between command buffers/queues
1500#[implements]
1501impl<'d> CmdRecord<'d> {
1502    /// Set an event object to signaled state
1503    #[inline(always)]
1504    pub fn set_event(
1505        mut self,
1506        event: &(impl VkHandle<Handle = VkEvent> + ?Sized),
1507        stage_mask: PipelineStageFlags,
1508    ) -> Self {
1509        unsafe {
1510            crate::vkfn::cmd_set_event(self.ptr.native_ptr_mut(), event.native_ptr(), stage_mask.0);
1511        }
1512        self
1513    }
1514
1515    /// Reset an event object to non-signaled state
1516    #[inline(always)]
1517    pub fn reset_event(
1518        mut self,
1519        event: &(impl VkHandle<Handle = VkEvent> + ?Sized),
1520        stage_mask: PipelineStageFlags,
1521    ) -> Self {
1522        unsafe {
1523            crate::vkfn::cmd_reset_event(self.ptr.native_ptr_mut(), event.native_ptr(), stage_mask.0);
1524        }
1525        self
1526    }
1527
1528    /// Wait for one or more events and insert a set of memory
1529    #[inline(always)]
1530    pub fn wait_events(
1531        mut self,
1532        events: &[VkHandleRef<VkEvent>],
1533        src_stage_mask: PipelineStageFlags,
1534        dst_stage_mask: PipelineStageFlags,
1535        memory_barriers: &[VkMemoryBarrier],
1536        buffer_memory_barriers: &[BufferMemoryBarrier],
1537        image_memory_barriers: &[ImageMemoryBarrier],
1538    ) -> Self {
1539        unsafe {
1540            crate::vkfn::cmd_wait_events(
1541                self.ptr.native_ptr_mut(),
1542                events.len() as _,
1543                crate::ffi_helper::slice_as_ptr_empty_null(events) as _,
1544                src_stage_mask.0,
1545                dst_stage_mask.0,
1546                memory_barriers.len() as _,
1547                crate::ffi_helper::slice_as_ptr_empty_null(memory_barriers),
1548                buffer_memory_barriers.len() as _,
1549                crate::ffi_helper::slice_as_ptr_empty_null(buffer_memory_barriers) as _,
1550                image_memory_barriers.len() as _,
1551                crate::ffi_helper::slice_as_ptr_empty_null(image_memory_barriers) as _,
1552            );
1553        }
1554        self
1555    }
1556
1557    /// Insert a memory dependency
1558    #[inline(always)]
1559    pub fn pipeline_barrier(
1560        mut self,
1561        src_stage_mask: PipelineStageFlags,
1562        dst_stage_mask: PipelineStageFlags,
1563        dependency_flags: VkDependencyFlags,
1564        memory_barriers: &[VkMemoryBarrier],
1565        buffer_memory_barriers: &[BufferMemoryBarrier],
1566        image_memory_barriers: &[ImageMemoryBarrier],
1567    ) -> Self {
1568        unsafe {
1569            crate::vkfn::cmd_pipeline_barrier(
1570                self.ptr.native_ptr_mut(),
1571                src_stage_mask.0,
1572                dst_stage_mask.0,
1573                dependency_flags,
1574                memory_barriers.len() as _,
1575                crate::ffi_helper::slice_as_ptr_empty_null(memory_barriers),
1576                buffer_memory_barriers.len() as _,
1577                crate::ffi_helper::slice_as_ptr_empty_null(buffer_memory_barriers) as _,
1578                image_memory_barriers.len() as _,
1579                crate::ffi_helper::slice_as_ptr_empty_null(image_memory_barriers) as _,
1580            );
1581        }
1582        self
1583    }
1584
1585    /// Insert a memory dependency
1586    #[cfg(feature = "VK_KHR_synchronization2")]
1587    #[inline(always)]
1588    pub fn pipeline_barrier_2_khr(
1589        mut self,
1590        fn_provider: &(impl DeviceSynchronization2Extension + ?Sized),
1591        dependency_info: &crate::DependencyInfo,
1592    ) -> Self {
1593        unsafe {
1594            (fn_provider.cmd_pipeline_barrier_2_khr_fn().0)(self.ptr.native_ptr_mut(), dependency_info as *const _ as _)
1595        }
1596
1597        self
1598    }
1599
1600    /// Insert a memory dependency
1601    #[cfg(feature = "Allow1_3APIs")]
1602    #[inline(always)]
1603    pub fn pipeline_barrier_2(mut self, dependency_info: &crate::DependencyInfo) -> Self {
1604        unsafe { crate::vkfn::cmd_pipeline_barrier2(self.ptr.native_ptr_mut(), dependency_info as *const _ as _) }
1605
1606        self
1607    }
1608}
1609
1610/// Graphics/Compute Commands: Querying
1611#[implements]
1612impl<'d> CmdRecord<'d> {
1613    /// Begin a query
1614    #[inline(always)]
1615    pub fn begin_query(
1616        mut self,
1617        pool: &(impl VkHandle<Handle = VkQueryPool> + ?Sized),
1618        query: u32,
1619        flags: VkQueryControlFlags,
1620    ) -> Self {
1621        unsafe {
1622            crate::vkfn::cmd_begin_query(self.ptr.native_ptr_mut(), pool.native_ptr(), query, flags);
1623        }
1624        self
1625    }
1626
1627    /// Ends a query
1628    #[inline(always)]
1629    pub fn end_query(mut self, pool: &(impl VkHandle<Handle = VkQueryPool> + ?Sized), query: u32) -> Self {
1630        unsafe {
1631            crate::vkfn::cmd_end_query(self.ptr.native_ptr_mut(), pool.native_ptr(), query);
1632        }
1633        self
1634    }
1635
1636    /// Reset queries in a query pool
1637    #[inline(always)]
1638    pub fn reset_query_pool(
1639        mut self,
1640        pool: &(impl VkHandle<Handle = VkQueryPool> + ?Sized),
1641        range: core::ops::Range<u32>,
1642    ) -> Self {
1643        unsafe {
1644            crate::vkfn::cmd_reset_query_pool(
1645                self.ptr.native_ptr_mut(),
1646                pool.native_ptr(),
1647                range.start,
1648                range.end - range.start,
1649            );
1650        }
1651        self
1652    }
1653
1654    /// Write a device timestamp into a query object
1655    #[inline(always)]
1656    pub fn write_timestamp(
1657        mut self,
1658        stage: PipelineStageFlags,
1659        pool: &(impl VkHandle<Handle = VkQueryPool> + ?Sized),
1660        query: u32,
1661    ) -> Self {
1662        unsafe {
1663            crate::vkfn::cmd_write_timestamp(self.ptr.native_ptr_mut(), stage.0, pool.native_ptr(), query);
1664        }
1665        self
1666    }
1667
1668    /// Copy the results of queries in a query pool to a buffer object
1669    #[inline(always)]
1670    #[allow(clippy::too_many_arguments)]
1671    pub fn copy_query_pool_results(
1672        mut self,
1673        pool: &(impl VkHandle<Handle = VkQueryPool> + ?Sized),
1674        range: core::ops::Range<u32>,
1675        dst: &(impl VkHandle<Handle = VkBuffer> + ?Sized),
1676        dst_offset: DeviceSize,
1677        stride: DeviceSize,
1678        flags: QueryResultFlags,
1679    ) -> Self {
1680        unsafe {
1681            crate::vkfn::cmd_copy_query_pool_results(
1682                self.ptr.native_ptr_mut(),
1683                pool.native_ptr(),
1684                range.start,
1685                range.end - range.start,
1686                dst.native_ptr(),
1687                dst_offset,
1688                stride,
1689                flags.bits(),
1690            );
1691        }
1692        self
1693    }
1694}
1695
1696/// Graphics/Compute Commands: Miscellaneous
1697#[implements]
1698impl<'d> CmdRecord<'d> {
1699    /// Inject imperative command generation in method-chaining
1700    #[inline(always)]
1701    pub fn inject(self, op: impl FnOnce(Self) -> Self) -> Self {
1702        op(self)
1703    }
1704}
1705
1706/// A color value representation for clearing operations.
1707/// Constructable from RGBA values using `From::from`.
1708pub type ClearColorValue = VkClearColorValue;
1709impl From<[f32; 4]> for ClearColorValue {
1710    #[inline(always)]
1711    fn from(c: [f32; 4]) -> Self {
1712        VkClearColorValue { float32: c }
1713    }
1714}
1715impl From<[i32; 4]> for ClearColorValue {
1716    #[inline(always)]
1717    fn from(c: [i32; 4]) -> Self {
1718        VkClearColorValue { int32: c }
1719    }
1720}
1721impl From<[u32; 4]> for ClearColorValue {
1722    #[inline(always)]
1723    fn from(c: [u32; 4]) -> Self {
1724        VkClearColorValue { uint32: c }
1725    }
1726}
1727
1728pub type ClearValue = VkClearValue;
1729impl ClearValue {
1730    /// Constructs a `ClearValue` which represents clearing color value
1731    #[inline(always)]
1732    pub fn color(c: impl Into<ClearColorValue>) -> Self {
1733        Self { color: c.into() }
1734    }
1735
1736    /// Constructs a `ClearValue` which represents clearing color value
1737    pub const fn color_f32(c: [f32; 4]) -> Self {
1738        Self {
1739            color: VkClearColorValue { float32: c },
1740        }
1741    }
1742    /// Constructs a `ClearValue` which represents clearing color value
1743    pub const fn color_u32(c: [u32; 4]) -> Self {
1744        Self {
1745            color: VkClearColorValue { uint32: c },
1746        }
1747    }
1748    /// Constructs a `ClearValue` which represents clearing color value
1749    pub const fn color_i32(c: [i32; 4]) -> Self {
1750        Self {
1751            color: VkClearColorValue { int32: c },
1752        }
1753    }
1754    /// Constructs a `ClearValue` which represents clearing both depth and stencil values
1755    pub const fn depth_stencil(depth: f32, stencil: u32) -> Self {
1756        Self {
1757            depthStencil: VkClearDepthStencilValue { depth, stencil },
1758        }
1759    }
1760}
1761
1762/// Type of index buffer indices
1763#[repr(i32)]
1764#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1765pub enum IndexType {
1766    /// Indices are 8-bit unsigned integer values
1767    #[cfg(feature = "VK_KHR_index_type_uint8")]
1768    U8 = VK_INDEX_TYPE_UINT8_KHR,
1769    /// Indices are 16-bit unsigned integer values
1770    U16 = VK_INDEX_TYPE_UINT16,
1771    /// Indices are 32-bit unsigned integer values
1772    U32 = VK_INDEX_TYPE_UINT32,
1773}
1774
1775/// Enabling or disabling the occlusion query
1776#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1777pub enum OcclusionQuery {
1778    Disable,
1779    Enable,
1780    /// `VK_QUERY_CONTROL_PRECISE_BIT`
1781    Precise,
1782}
1783
1784/// Access Types
1785pub struct AccessFlags {
1786    pub read: VkAccessFlags,
1787    pub write: VkAccessFlags,
1788}
1789impl AccessFlags {
1790    /// Specifies read access to an indirect command structure read as part of an indirect drawing or dispatch command.
1791    pub const INDIRECT_COMMAND_READ: VkAccessFlags = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
1792    /// Specifies read access to an index buffer as part of an indexed drawing command, bound by `vkCmdBindIndexBuffer`.
1793    pub const INDEX_READ: VkAccessFlags = VK_ACCESS_INDEX_READ_BIT;
1794    /// Specifies read access to a vertex buffer as part of a drawing command, bound by `vkCmdBindVertexBuffers`.
1795    pub const VERTEX_ATTRIBUTE_READ: VkAccessFlags = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1796    /// Specifies read access to a [uniform buffer](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#descriptorsets-uniformbuffer).
1797    pub const UNIFORM_READ: VkAccessFlags = VK_ACCESS_UNIFORM_READ_BIT;
1798    /// Specifies read access to an [input attachment](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#renderpass) within a render pass during fragment shading.
1799    pub const INPUT_ATTACHMENT_READ: VkAccessFlags = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
1800    /// Specifies read/write access to a [storage buffer](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#descriptorsets-storagebuffer),
1801    /// [uniform texel buffer](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#descriptorsets-uniformtexelbuffer)(read only),
1802    /// [storage texel buffer](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#descriptorsets-storagetexelbuffer),
1803    /// [samples image](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#descriptorsets-sampledimage)(read only),
1804    /// or [storage image](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#descriptorsets-storageimage).
1805    pub const SHADER: Self = AccessFlags {
1806        read: VK_ACCESS_SHADER_READ_BIT,
1807        write: VK_ACCESS_SHADER_WRITE_BIT,
1808    };
1809    /// - `read`: Specifies read access to a [color attachment](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#renderpass),
1810    ///   such as via [blending](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#framebuffer-blending),
1811    ///   [logic operations](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#framebuffer-logicop),
1812    ///   or via certain [subpass load operations](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#framebuffer-logicop).
1813    /// - `write`: specifies write access to a [color or resolve attachment](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#renderpass)
1814    ///   during a [render pass](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#renderpass)
1815    ///   or via certain [subpass load and store operations](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#renderpass-load-store-ops).
1816    pub const COLOR_ATTACHMENT: Self = AccessFlags {
1817        read: VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
1818        write: VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1819    };
1820    /// - `read`: Specifies read access to a [depth/stencil attachment](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#renderpass),
1821    ///   via [depth or stencil operations](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#fragops-ds-state)
1822    ///   or via certain [subpass load operations](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#renderpass-load-store-ops).
1823    /// - `write`: Specifies write access to a [depth/stencil attachment](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#renderpass),
1824    ///   via [depth or stencil operations](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#fragops-ds-state)
1825    ///   or via certain [subpass load and store operations](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#renderpass-load-store-ops).
1826    pub const DEPTH_STENCIL_ATTACHMENT: Self = AccessFlags {
1827        read: VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
1828        write: VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1829    };
1830    /// Specifies read/write access to an image or buffer in a [clear](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#clears)(write only)
1831    /// or [copy](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#copies) operation.
1832    pub const TRANSFER: Self = AccessFlags {
1833        read: VK_ACCESS_TRANSFER_READ_BIT,
1834        write: VK_ACCESS_TRANSFER_WRITE_BIT,
1835    };
1836    /// Specifies read/write access by a host operation.
1837    /// Accesses of this type are not performed through a resource, but directly on memory.
1838    pub const HOST: Self = AccessFlags {
1839        read: VK_ACCESS_HOST_READ_BIT,
1840        write: VK_ACCESS_HOST_WRITE_BIT,
1841    };
1842    /// Specifies read/write access via non-specific entities.
1843    /// These entities include the Vulkan device and host, but *may* also include entities external to the Vulkan device
1844    /// or otherwise not part of the core Vulkan pipeline.
1845    ///
1846    /// - When the `write` mask included in a source access mask, all writes that are performed by entities known to the
1847    ///   Vulkan device are made available.
1848    /// - When included in a destination access mask, makes all available writes visible to all future read accesses on
1849    ///   entities known to the Vulkan device.
1850    pub const MEMORY: Self = AccessFlags {
1851        read: VK_ACCESS_MEMORY_READ_BIT,
1852        write: VK_ACCESS_MEMORY_WRITE_BIT,
1853    };
1854}
1855
1856/// Wrapper object of `VkImageMemoryBarrier`, derscribes a memory barrier of an image.
1857#[derive(Clone)]
1858#[repr(transparent)]
1859pub struct ImageMemoryBarrier(VkImageMemoryBarrier);
1860impl ImageMemoryBarrier {
1861    /// Construct a new barrier descriptor from discrete pair of resource and subresource core::ops::Range
1862    pub fn new(
1863        res: &(impl VkHandle<Handle = VkImage> + ?Sized),
1864        subres: impl Into<VkImageSubresourceRange>,
1865        trans: LayoutTransition,
1866    ) -> Self {
1867        Self(VkImageMemoryBarrier {
1868            sType: VkImageMemoryBarrier::TYPE,
1869            pNext: core::ptr::null(),
1870            image: res.native_ptr(),
1871            subresourceRange: subres.into(),
1872            oldLayout: trans.from as _,
1873            newLayout: trans.to as _,
1874            srcAccessMask: trans.from.default_access_mask(),
1875            dstAccessMask: trans.to.default_access_mask(),
1876            srcQueueFamilyIndex: VK_QUEUE_FAMILY_IGNORED,
1877            dstQueueFamilyIndex: VK_QUEUE_FAMILY_IGNORED,
1878        })
1879    }
1880
1881    /// Update the source access mask
1882    #[inline]
1883    pub fn src_access_mask(mut self, mask: VkAccessFlags) -> Self {
1884        self.0.srcAccessMask = mask;
1885        self
1886    }
1887
1888    /// Update the destination access mask
1889    #[inline]
1890    pub fn dest_access_mask(mut self, mask: VkAccessFlags) -> Self {
1891        self.0.dstAccessMask = mask;
1892        self
1893    }
1894
1895    /// Update the access mask transition
1896    #[inline]
1897    pub fn access_mask_transition(mut self, src: VkAccessFlags, dst: VkAccessFlags) -> Self {
1898        self.0.srcAccessMask = src;
1899        self.0.dstAccessMask = dst;
1900        self
1901    }
1902
1903    /// Flip access masks and image layouts
1904    #[inline]
1905    pub fn flip(mut self) -> Self {
1906        core::mem::swap(&mut self.0.srcAccessMask, &mut self.0.dstAccessMask);
1907        core::mem::swap(&mut self.0.oldLayout, &mut self.0.newLayout);
1908        self
1909    }
1910}
1911impl From<VkImageMemoryBarrier> for ImageMemoryBarrier {
1912    #[inline]
1913    fn from(v: VkImageMemoryBarrier) -> Self {
1914        Self(v)
1915    }
1916}
1917impl From<ImageMemoryBarrier> for VkImageMemoryBarrier {
1918    #[inline]
1919    fn from(v: ImageMemoryBarrier) -> Self {
1920        v.0
1921    }
1922}
1923
1924/// Wrapper object of `VkBufferMemoryBarrier`, describes a memory barrier of a buffer.
1925#[derive(Clone)]
1926#[repr(transparent)]
1927pub struct BufferMemoryBarrier(VkBufferMemoryBarrier);
1928impl BufferMemoryBarrier {
1929    /// Construct a new buffer descriptor
1930    pub fn new(
1931        buf: &(impl VkHandle<Handle = VkBuffer> + ?Sized),
1932        range: core::ops::Range<VkDeviceSize>,
1933        src_access_mask: VkAccessFlags,
1934        dst_access_mask: VkAccessFlags,
1935    ) -> Self {
1936        Self(VkBufferMemoryBarrier {
1937            sType: VkBufferMemoryBarrier::TYPE,
1938            pNext: core::ptr::null(),
1939            buffer: buf.native_ptr(),
1940            offset: range.start,
1941            size: range.end - range.start,
1942            srcAccessMask: src_access_mask,
1943            dstAccessMask: dst_access_mask,
1944            srcQueueFamilyIndex: VK_QUEUE_FAMILY_IGNORED,
1945            dstQueueFamilyIndex: VK_QUEUE_FAMILY_IGNORED,
1946        })
1947    }
1948
1949    /// Update the source access mask
1950    #[inline]
1951    pub fn src_access_mask(mut self, mask: VkAccessFlags) -> Self {
1952        self.0.srcAccessMask = mask;
1953        self
1954    }
1955
1956    /// Update the destination access mask
1957    #[inline]
1958    pub fn dest_access_mask(mut self, mask: VkAccessFlags) -> Self {
1959        self.0.dstAccessMask = mask;
1960        self
1961    }
1962
1963    /// Update the access mask transition
1964    #[inline]
1965    pub fn access_mask_transition(self, src: VkAccessFlags, dst: VkAccessFlags) -> Self {
1966        self.src_access_mask(src).dest_access_mask(dst)
1967    }
1968
1969    /// Flip access masks
1970    #[inline]
1971    pub fn flip(mut self) -> Self {
1972        core::mem::swap(&mut self.0.srcAccessMask, &mut self.0.dstAccessMask);
1973        self
1974    }
1975}
1976impl From<VkBufferMemoryBarrier> for BufferMemoryBarrier {
1977    #[inline]
1978    fn from(v: VkBufferMemoryBarrier) -> Self {
1979        BufferMemoryBarrier(v)
1980    }
1981}
1982impl From<BufferMemoryBarrier> for VkBufferMemoryBarrier {
1983    #[inline]
1984    fn from(v: BufferMemoryBarrier) -> Self {
1985        v.0
1986    }
1987}
1988
1989pub type BufferCopy = VkBufferCopy;
1990impl BufferCopy {
1991    pub const fn mirror(offset: VkDeviceSize, size: VkDeviceSize) -> Self {
1992        Self {
1993            srcOffset: offset,
1994            dstOffset: offset,
1995            size,
1996        }
1997    }
1998
1999    pub const fn mirror_data<T>(offset: VkDeviceSize) -> Self {
2000        Self::mirror(offset, core::mem::size_of::<T>() as _)
2001    }
2002
2003    pub const fn copy_data<T>(src_offset: VkDeviceSize, dst_offset: VkDeviceSize) -> Self {
2004        Self {
2005            srcOffset: src_offset,
2006            dstOffset: dst_offset,
2007            size: core::mem::size_of::<T>() as _,
2008        }
2009    }
2010}
2011
2012pub type ImageCopy = VkImageCopy;