1use crate::low::vkstate::VulkanState;
2
3use crate::ash::version::DeviceV1_0;
4use ash::vk;
5
6pub struct VkCmdPool<'a> {
7 pub cmd_pool: vk::CommandPool,
8 pub cmd_buffers: Vec<vk::CommandBuffer>,
9 state: &'a VulkanState,
10}
11
12impl<'a> VkCmdPool<'a> {
13 pub fn new(state: &'a VulkanState) -> VkCmdPool {
14 let command_pool_create_info = vk::CommandPoolCreateInfo::builder()
15 .queue_family_index(state.queue_family_index)
16 .build();
17 let command_pool = unsafe {
18 state
19 .device
20 .create_command_pool(&command_pool_create_info, None)
21 .expect("[ERR] Could not create command pool.")
22 };
23 VkCmdPool {
24 cmd_pool: command_pool,
25 cmd_buffers: Vec::new(),
26 state,
27 }
28 }
29
30 pub fn create_cmd_buffer(&mut self, level: vk::CommandBufferLevel) -> usize {
31 let command_buffer_allocate_info = vk::CommandBufferAllocateInfo::builder()
32 .command_pool(self.cmd_pool)
33 .command_buffer_count(1)
34 .level(level);
35 let command_buffer = unsafe {
36 self.state
37 .device
38 .allocate_command_buffers(&command_buffer_allocate_info)
39 .expect("[ERR] Could not create command buffer")[0]
40 };
41 self.cmd_buffers.push(command_buffer);
42 self.cmd_buffers.len() - 1
43 }
44
45 pub fn begin_cmd(&self, usage: vk::CommandBufferUsageFlags, cmd_buffer_index: usize) {
46 let command_buffer_begin_info = vk::CommandBufferBeginInfo::builder().flags(usage);
47
48 unsafe {
49 self.state
50 .device
51 .begin_command_buffer(
52 self.cmd_buffers[cmd_buffer_index],
53 &command_buffer_begin_info,
54 )
55 .expect("[ERR] Could not begin command buffer.")
56 };
57 }
58
59 pub fn end_cmd(&self, cmd_buffer_index: usize) {
60 unsafe {
61 self.state
62 .device
63 .end_command_buffer(self.cmd_buffers[cmd_buffer_index])
64 .expect("[ERR] Could not end command buffer.");
65 };
66 }
67
68 pub fn bind_pipeline(
69 &self,
70 pipeline: vk::Pipeline,
71 pipeline_type: vk::PipelineBindPoint,
72 cmd_buffer_index: usize,
73 ) {
74 unsafe {
75 self.state.device.cmd_bind_pipeline(
76 self.cmd_buffers[cmd_buffer_index],
77 pipeline_type,
78 pipeline,
79 )
80 };
81 }
82
83 pub fn bind_descriptor(
84 &self,
85 layout: vk::PipelineLayout,
86 pipeline_type: vk::PipelineBindPoint,
87 descriptor_sets: &[vk::DescriptorSet],
88 cmd_buffer_index: usize,
89 ) {
90 unsafe {
91 self.state.device.cmd_bind_descriptor_sets(
92 self.cmd_buffers[cmd_buffer_index],
93 pipeline_type,
94 layout,
95 0,
96 descriptor_sets,
97 &[],
98 )
99 };
100 }
101
102 pub fn dispatch(&self, x: u32, y: u32, z: u32, cmd_buffer_index: usize) {
103 unsafe {
104 self.state
105 .device
106 .cmd_dispatch(self.cmd_buffers[cmd_buffer_index], x, y, z);
107 };
108 }
109
110 pub fn submit(&self, queue: vk::Queue) {
111 let submit_info = vk::SubmitInfo::builder().command_buffers(&self.cmd_buffers);
112 unsafe {
113 self.state
114 .device
115 .queue_submit(queue, &[submit_info.build()], vk::Fence::null())
116 .expect("[ERR] Could not submit queue.")
117 };
118 }
119}
120
121impl<'a> Drop for VkCmdPool<'a> {
122 fn drop(&mut self) {
123 unsafe {
124 self.state
125 .device
126 .free_command_buffers(self.cmd_pool, &self.cmd_buffers);
127 self.state.device.destroy_command_pool(self.cmd_pool, None);
128 }
129 }
130}