Skip to main content

bedrock/
command.rs

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