demo_vk/graphics/vulkan/
sync_commands.rs1use {
2 crate::{
3 graphics::vulkan::{raii, VulkanContext},
4 unwrap_here,
5 },
6 anyhow::Result,
7 ash::vk,
8 std::sync::Arc,
9};
10
11#[derive(Debug)]
13pub struct SyncCommands {
14 command_pool: raii::CommandPool,
15 command_buffer: vk::CommandBuffer,
16 fence: raii::Fence,
17 cxt: Arc<VulkanContext>,
18}
19
20impl SyncCommands {
21 pub fn new(cxt: Arc<VulkanContext>) -> Result<Self> {
22 let command_pool = unwrap_here!(
23 "Create command pool",
24 raii::CommandPool::new(
25 "SyncCommands",
26 cxt.device.clone(),
27 &vk::CommandPoolCreateInfo {
28 flags: vk::CommandPoolCreateFlags::TRANSIENT,
29 queue_family_index: cxt.graphics_queue_family_index,
30 ..Default::default()
31 },
32 )
33 );
34 let command_buffer =
35 unwrap_here!("Allocate primary command buffer", unsafe {
36 cxt.allocate_command_buffers(&vk::CommandBufferAllocateInfo {
37 command_pool: command_pool.raw,
38 level: vk::CommandBufferLevel::PRIMARY,
39 command_buffer_count: 1,
40 ..Default::default()
41 })?
42 .first()
43 .copied()
44 .context("Expected exactly one command buffer to be returned!")
45 });
46 let fence = unwrap_here!(
47 "Create command fence",
48 raii::Fence::new(
49 "SyncCommands",
50 cxt.device.clone(),
51 &vk::FenceCreateInfo::default(),
52 )
53 );
54 Ok(Self {
55 command_pool,
56 command_buffer,
57 fence,
58 cxt,
59 })
60 }
61
62 pub fn submit_and_wait(
63 &self,
64 build_commands: impl FnOnce(vk::CommandBuffer) -> Result<()>,
65 ) -> Result<()> {
66 unwrap_here!("Reset command pool", unsafe {
67 self.cxt.reset_command_pool(
68 self.command_pool.raw,
69 vk::CommandPoolResetFlags::empty(),
70 )
71 });
72
73 unwrap_here!("Begin command buffer one time submit", unsafe {
74 self.cxt.begin_command_buffer(
75 self.command_buffer,
76 &vk::CommandBufferBeginInfo {
77 flags: vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT,
78 ..Default::default()
79 },
80 )
81 });
82
83 unwrap_here!(
84 "Add commands to the buffer",
85 build_commands(self.command_buffer)
86 );
87
88 unwrap_here!("End command buffer", unsafe {
89 self.cxt.end_command_buffer(self.command_buffer)
90 });
91
92 unwrap_here!("Submit commands and signal fence", unsafe {
93 self.cxt.queue_submit(
94 self.cxt.graphics_queue,
95 &[vk::SubmitInfo {
96 wait_semaphore_count: 0,
97 p_wait_semaphores: std::ptr::null(),
98 p_wait_dst_stage_mask: std::ptr::null(),
99 command_buffer_count: 1,
100 p_command_buffers: &self.command_buffer,
101 signal_semaphore_count: 0,
102 p_signal_semaphores: std::ptr::null(),
103 ..Default::default()
104 }],
105 self.fence.raw,
106 )
107 });
108
109 unwrap_here!("Wait for submission fence", unsafe {
110 self.cxt.wait_for_fences(&[self.fence.raw], true, u64::MAX)
111 });
112
113 unwrap_here!("Reset fence after commands complete", unsafe {
114 self.cxt.reset_fences(&[self.fence.raw])
115 });
116
117 Ok(())
118 }
119}