1use 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 pub const unsafe fn manage(handle: brvk::VkCommandPool, parent: Device) -> Self {
49 Self(handle, parent)
50 }
51
52 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 #[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 #[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#[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 #[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 #[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 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 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#[derive(Debug, Clone, Copy, PartialEq, Eq)]
207#[bitflags_newtype]
208pub struct CommandPoolResetFlags(brvk::VkCommandPoolResetFlags);
209impl CommandPoolResetFlags {
210 pub const EMPTY: Self = Self(0);
212
213 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 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 #[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 #[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 #[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 #[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 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 #[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 #[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 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 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 #[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 #[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#[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#[implements]
601impl<'d> CmdRecord<'d> {
602 #[inline(always)]
604 pub fn end(self) -> crate::Result<()> {
605 unsafe { crate::vkfn_wrapper::end_command_buffer(self.ptr) }
606 }
607}
608
609#[repr(i32)]
611#[derive(Debug, Clone, Copy, PartialEq, Eq)]
612pub enum SubpassContents {
613 Inline = brvk::VK_SUBPASS_CONTENTS_INLINE,
615 SecondaryCommandBuffers = brvk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS,
617}
618
619#[repr(i32)]
621#[derive(Debug, Clone, Copy, PartialEq, Eq)]
622pub enum PipelineBindPoint {
623 Graphics = brvk::VK_PIPELINE_BIND_POINT_GRAPHICS,
625 Compute = brvk::VK_PIPELINE_BIND_POINT_COMPUTE,
627}
628
629#[implements]
631impl<'d> CmdRecord<'d> {
632 #[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 #[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 #[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#[implements]
749impl<'d> CmdRecord<'d> {
750 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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#[implements]
937impl<'d> CmdRecord<'d> {
938 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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#[implements]
1047impl<'d> CmdRecord<'d> {
1048 #[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 #[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 #[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#[implements]
1112impl<'d> CmdRecord<'d> {
1113 #[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 #[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 #[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 #[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#[implements]
1196impl<'d> CmdRecord<'d> {
1197 #[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 #[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#[implements]
1222impl<'d> CmdRecord<'d> {
1223 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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#[implements]
1403impl<'d> CmdRecord<'d> {
1404 #[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 #[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 #[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 #[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#[implements]
1489impl<'d> CmdRecord<'d> {
1490 #[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#[implements]
1509impl<'d> CmdRecord<'d> {
1510 #[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#[implements]
1537impl<'d> CmdRecord<'d> {
1538 #[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 #[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 #[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 #[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 #[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 #[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#[implements]
1648impl<'d> CmdRecord<'d> {
1649 #[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 #[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 #[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 #[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 #[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#[implements]
1734impl<'d> CmdRecord<'d> {
1735 #[inline(always)]
1737 pub fn inject(self, op: impl FnOnce(Self) -> Self) -> Self {
1738 op(self)
1739 }
1740}
1741
1742#[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 #[inline(always)]
1770 pub fn color(c: impl Into<ClearColorValue>) -> Self {
1771 Self(brvk::VkClearValue { color: c.into().0 })
1772 }
1773
1774 pub const fn color_f32(c: [f32; 4]) -> Self {
1776 Self(brvk::VkClearValue {
1777 color: brvk::VkClearColorValue { float32: c },
1778 })
1779 }
1780 pub const fn color_u32(c: [u32; 4]) -> Self {
1782 Self(brvk::VkClearValue {
1783 color: brvk::VkClearColorValue { uint32: c },
1784 })
1785 }
1786 pub const fn color_i32(c: [i32; 4]) -> Self {
1788 Self(brvk::VkClearValue {
1789 color: brvk::VkClearColorValue { int32: c },
1790 })
1791 }
1792 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#[repr(i32)]
1802#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1803pub enum IndexType {
1804 #[cfg(feature = "VK_KHR_index_type_uint8")]
1806 U8 = brvk::VK_INDEX_TYPE_UINT8_KHR,
1807 U16 = brvk::VK_INDEX_TYPE_UINT16,
1809 U32 = brvk::VK_INDEX_TYPE_UINT32,
1811}
1812
1813#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1815pub enum OcclusionQuery {
1816 Disable,
1817 Enable,
1818 Precise,
1820}
1821
1822pub struct AccessFlags {
1824 pub read: brvk::VkAccessFlags,
1825 pub write: brvk::VkAccessFlags,
1826}
1827impl AccessFlags {
1828 pub const INDIRECT_COMMAND_READ: brvk::VkAccessFlags = brvk::VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
1830 pub const INDEX_READ: brvk::VkAccessFlags = brvk::VK_ACCESS_INDEX_READ_BIT;
1832 pub const VERTEX_ATTRIBUTE_READ: brvk::VkAccessFlags = brvk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1834 pub const UNIFORM_READ: brvk::VkAccessFlags = brvk::VK_ACCESS_UNIFORM_READ_BIT;
1836 pub const INPUT_ATTACHMENT_READ: brvk::VkAccessFlags = brvk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
1838 pub const SHADER: Self = AccessFlags {
1844 read: brvk::VK_ACCESS_SHADER_READ_BIT,
1845 write: brvk::VK_ACCESS_SHADER_WRITE_BIT,
1846 };
1847 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 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 pub const TRANSFER: Self = AccessFlags {
1871 read: brvk::VK_ACCESS_TRANSFER_READ_BIT,
1872 write: brvk::VK_ACCESS_TRANSFER_WRITE_BIT,
1873 };
1874 pub const HOST: Self = AccessFlags {
1877 read: brvk::VK_ACCESS_HOST_READ_BIT,
1878 write: brvk::VK_ACCESS_HOST_WRITE_BIT,
1879 };
1880 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#[derive(Clone)]
1896#[repr(transparent)]
1897pub struct ImageMemoryBarrier(brvk::VkImageMemoryBarrier);
1898impl ImageMemoryBarrier {
1899 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 #[inline]
1921 pub fn src_access_mask(mut self, mask: brvk::VkAccessFlags) -> Self {
1922 self.0.srcAccessMask = mask;
1923 self
1924 }
1925
1926 #[inline]
1928 pub fn dest_access_mask(mut self, mask: brvk::VkAccessFlags) -> Self {
1929 self.0.dstAccessMask = mask;
1930 self
1931 }
1932
1933 #[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 #[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#[derive(Clone)]
1964#[repr(transparent)]
1965pub struct BufferMemoryBarrier(brvk::VkBufferMemoryBarrier);
1966impl BufferMemoryBarrier {
1967 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 #[inline]
1989 pub fn src_access_mask(mut self, mask: brvk::VkAccessFlags) -> Self {
1990 self.0.srcAccessMask = mask;
1991 self
1992 }
1993
1994 #[inline]
1996 pub fn dest_access_mask(mut self, mask: brvk::VkAccessFlags) -> Self {
1997 self.0.dstAccessMask = mask;
1998 self
1999 }
2000
2001 #[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 #[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);