demo_vk/graphics/vulkan/
sync_commands.rs1use {
2 crate::{
3 graphics::vulkan::{raii, VulkanContext},
4 trace,
5 },
6 anyhow::{Context, 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 = raii::CommandPool::new(
23 "SyncCommands",
24 cxt.device.clone(),
25 &vk::CommandPoolCreateInfo {
26 flags: vk::CommandPoolCreateFlags::TRANSIENT,
27 queue_family_index: cxt.graphics_queue_family_index,
28 ..Default::default()
29 },
30 )
31 .with_context(trace!("Unable to create command pool!"))?;
32 let command_buffer = unsafe {
33 cxt.allocate_command_buffers(&vk::CommandBufferAllocateInfo {
34 command_pool: command_pool.raw,
35 level: vk::CommandBufferLevel::PRIMARY,
36 command_buffer_count: 1,
37 ..Default::default()
38 })
39 .with_context(trace!("Unable to allocate the command buffer!"))?[0]
40 };
41 let fence = raii::Fence::new(
42 "SyncCommands",
43 cxt.device.clone(),
44 &vk::FenceCreateInfo::default(),
45 )?;
46 Ok(Self {
47 command_pool,
48 command_buffer,
49 fence,
50 cxt,
51 })
52 }
53
54 pub fn submit_and_wait(
55 &self,
56 build_commands: impl FnOnce(vk::CommandBuffer) -> Result<()>,
57 ) -> Result<()> {
58 unsafe {
59 self.cxt
60 .reset_command_pool(
61 self.command_pool.raw,
62 vk::CommandPoolResetFlags::empty(),
63 )
64 .with_context(trace!("Error while resetting command pool!"))?;
65
66 self.cxt.begin_command_buffer(
67 self.command_buffer,
68 &vk::CommandBufferBeginInfo {
69 flags: vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT,
70 ..Default::default()
71 },
72 )?;
73 }
74
75 build_commands(self.command_buffer).with_context(trace!(
76 "Error while adding commands to the buffer!"
77 ))?;
78
79 unsafe {
80 self.cxt
81 .end_command_buffer(self.command_buffer)
82 .with_context(trace!("Error while ending command buffer!"))?;
83
84 self.cxt
85 .queue_submit(
86 self.cxt.graphics_queue,
87 &[vk::SubmitInfo {
88 wait_semaphore_count: 0,
89 p_wait_semaphores: std::ptr::null(),
90 p_wait_dst_stage_mask: std::ptr::null(),
91 command_buffer_count: 1,
92 p_command_buffers: &self.command_buffer,
93 signal_semaphore_count: 0,
94 p_signal_semaphores: std::ptr::null(),
95 ..Default::default()
96 }],
97 self.fence.raw,
98 )
99 .with_context(trace!("Error while submitting commands!"))?;
100
101 self.cxt
102 .wait_for_fences(&[self.fence.raw], true, u64::MAX)
103 .with_context(trace!(
104 "Error while waiting for commands to finish!"
105 ))?;
106 self.cxt
107 .reset_fences(&[self.fence.raw])
108 .with_context(trace!("Error while resetting fences!"))?;
109 }
110
111 Ok(())
112 }
113}