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