You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

333 lines
6.9KB

  1. use crate::render::{
  2. Buffer, DescriptorPool, Device, Framebuffer, Pipeline, PipelineLayout,
  3. RenderPass,
  4. };
  5. use ash::{version::DeviceV1_0, vk};
  6. use std::rc::Rc;
  7. #[allow(dead_code)]
  8. pub struct CommandPool {
  9. handle: vk::CommandPool,
  10. buf_handles: Vec<vk::CommandBuffer>,
  11. buffers: Vec<CommandBuffer>,
  12. pub device: Rc<Device>,
  13. }
  14. #[allow(dead_code)]
  15. pub struct CommandBuffer {
  16. handle: vk::CommandBuffer,
  17. device: Rc<Device>,
  18. render_pass: Option<Rc<RenderPass>>,
  19. framebuffer: Option<Rc<Framebuffer>>,
  20. pipeline: Option<Rc<Pipeline>>,
  21. vertex_buffer: Option<Rc<Buffer>>,
  22. index_buffer: Option<Rc<Buffer>>,
  23. descriptor_pool: Option<Rc<DescriptorPool>>,
  24. }
  25. impl CommandPool {
  26. pub fn create_graphics(
  27. device: Rc<Device>,
  28. index: u32,
  29. framebuffers: &[Rc<Framebuffer>],
  30. render_pass: Rc<RenderPass>,
  31. extent: vk::Extent2D,
  32. f: impl Fn(&mut CommandBuffer, usize) + Copy,
  33. ) -> Result<Rc<Self>, vk::Result> {
  34. let (handle, buffers) = unsafe {
  35. Self::create_inner(
  36. &device,
  37. index,
  38. vk::CommandPoolCreateFlags::empty(),
  39. framebuffers.len(),
  40. )?
  41. };
  42. let buffers =
  43. buffers
  44. .iter()
  45. .zip(framebuffers.iter())
  46. .enumerate()
  47. .map(|(framebuffer_num, (&handle, framebuffer))| {
  48. Ok(CommandBuffer::create_graphics(
  49. handle,
  50. device.clone(),
  51. render_pass.clone(),
  52. framebuffer.clone(),
  53. extent,
  54. |cmd| f(cmd, framebuffer_num),
  55. )?)
  56. })
  57. .collect::<Result<Vec<_>, vk::Result>>()?;
  58. let buf_handles = buffers.iter().map(|cmd_buf| **cmd_buf).collect();
  59. Ok(Rc::new(Self { handle, buf_handles, buffers, device }))
  60. }
  61. pub fn create_transfer(
  62. device: Rc<Device>,
  63. index: u32,
  64. f: impl Fn(&mut CommandBuffer) + Copy,
  65. ) -> Result<Rc<Self>, vk::Result> {
  66. let (handle, buffers) = unsafe {
  67. Self::create_inner(
  68. &device,
  69. index,
  70. vk::CommandPoolCreateFlags::TRANSIENT,
  71. 1,
  72. )?
  73. };
  74. let buffers =
  75. buffers
  76. .iter()
  77. .map(|&handle| {
  78. Ok(CommandBuffer::create_transfer(
  79. handle,
  80. device.clone(),
  81. f,
  82. )?)
  83. })
  84. .collect::<Result<Vec<_>, vk::Result>>()?;
  85. let buf_handles = buffers.iter().map(|cmd_buf| **cmd_buf).collect();
  86. Ok(Rc::new(Self { handle, buf_handles, buffers, device }))
  87. }
  88. #[allow(dead_code)]
  89. pub fn buffers(&self) -> &[CommandBuffer] {
  90. &self.buffers
  91. }
  92. pub fn buf_handles(&self) -> &[vk::CommandBuffer] {
  93. &self.buf_handles
  94. }
  95. unsafe fn create_inner(
  96. device: &Device,
  97. index: u32,
  98. flags: vk::CommandPoolCreateFlags,
  99. buf_num: usize,
  100. ) -> Result<(vk::CommandPool, Vec<vk::CommandBuffer>), vk::Result> {
  101. let create_info = vk::CommandPoolCreateInfo {
  102. flags,
  103. queue_family_index: index,
  104. ..Default::default()
  105. };
  106. let handle = device.create_command_pool(&create_info, None)?;
  107. let alloc_info = vk::CommandBufferAllocateInfo {
  108. command_pool: handle,
  109. level: vk::CommandBufferLevel::PRIMARY,
  110. command_buffer_count: buf_num as u32,
  111. ..Default::default()
  112. };
  113. let buffers = device.allocate_command_buffers(&alloc_info)?;
  114. Ok((handle, buffers))
  115. }
  116. }
  117. impl CommandBuffer {
  118. pub fn bind_pipeline(&mut self, pipeline: Rc<Pipeline>) {
  119. unsafe {
  120. self.device.cmd_bind_pipeline(
  121. self.handle,
  122. vk::PipelineBindPoint::GRAPHICS,
  123. **pipeline,
  124. );
  125. self.pipeline = Some(pipeline);
  126. }
  127. }
  128. pub fn bind_vertex_buffer(&mut self, buffer: Rc<Buffer>) {
  129. unsafe {
  130. self.device.cmd_bind_vertex_buffers(
  131. self.handle,
  132. 0,
  133. &[ **buffer ],
  134. &[ 0 ],
  135. );
  136. self.vertex_buffer = Some(buffer);
  137. }
  138. }
  139. pub fn bind_index_buffer(&mut self, buffer: Rc<Buffer>) {
  140. let ty = vk::IndexType::UINT16;
  141. unsafe {
  142. self.device.cmd_bind_index_buffer(self.handle, **buffer, 0, ty);
  143. self.index_buffer = Some(buffer);
  144. }
  145. }
  146. pub fn bind_descriptor_pool(
  147. &mut self,
  148. descriptor_pool: Rc<DescriptorPool>,
  149. pipeline_layout: Rc<PipelineLayout>,
  150. which: usize,
  151. ) {
  152. unsafe {
  153. self.device.cmd_bind_descriptor_sets(
  154. self.handle,
  155. vk::PipelineBindPoint::GRAPHICS,
  156. **pipeline_layout,
  157. 0,
  158. &[*descriptor_pool.sets[which]],
  159. &[],
  160. );
  161. self.descriptor_pool = Some(descriptor_pool);
  162. }
  163. }
  164. pub fn draw(&self, num: usize) {
  165. unsafe {
  166. self.device.cmd_draw_indexed(self.handle, num as u32, 1, 0, 0, 0);
  167. }
  168. }
  169. pub fn transfer(
  170. &mut self,
  171. src: vk::Buffer,
  172. dst: vk::Buffer,
  173. size: vk::DeviceSize
  174. ) {
  175. let copy = [
  176. vk::BufferCopy {
  177. size,
  178. ..Default::default()
  179. }
  180. ];
  181. unsafe {
  182. self.device.cmd_copy_buffer(self.handle, src, dst, &copy);
  183. }
  184. }
  185. fn create_graphics(
  186. handle: vk::CommandBuffer,
  187. device: Rc<Device>,
  188. render_pass: Rc<RenderPass>,
  189. framebuffer: Rc<Framebuffer>,
  190. extent: vk::Extent2D,
  191. f: impl Fn(&mut Self),
  192. ) -> Result<Self, vk::Result> {
  193. let cmd_begin_info = vk::CommandBufferBeginInfo::default();
  194. let clear_values = [
  195. vk::ClearValue {
  196. color: vk::ClearColorValue { float32: [0.086, 0.098, 0.149, 1.0] }
  197. }
  198. ];
  199. let ren_begin_info = vk::RenderPassBeginInfo {
  200. render_pass: **render_pass,
  201. framebuffer: **framebuffer,
  202. render_area: vk::Rect2D {
  203. extent,
  204. offset: vk::Offset2D::default(),
  205. },
  206. clear_value_count: clear_values.len() as u32,
  207. p_clear_values: clear_values.as_ptr(),
  208. ..Default::default()
  209. };
  210. let mut this = Self {
  211. handle,
  212. device,
  213. render_pass: Some(render_pass),
  214. framebuffer: Some(framebuffer),
  215. pipeline: None,
  216. vertex_buffer: None,
  217. index_buffer: None,
  218. descriptor_pool: None,
  219. };
  220. unsafe {
  221. this.device.begin_command_buffer(this.handle, &cmd_begin_info)?;
  222. this.device.cmd_begin_render_pass(
  223. this.handle,
  224. &ren_begin_info,
  225. vk::SubpassContents::INLINE,
  226. );
  227. f(&mut this);
  228. this.device.cmd_end_render_pass(this.handle);
  229. this.device.end_command_buffer(this.handle)?;
  230. }
  231. Ok(this)
  232. }
  233. fn create_transfer(
  234. handle: vk::CommandBuffer,
  235. device: Rc<Device>,
  236. f: impl Fn(&mut Self),
  237. ) -> Result<Self, vk::Result> {
  238. let cmd_begin_info = vk::CommandBufferBeginInfo {
  239. flags: vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT,
  240. ..Default::default()
  241. };
  242. let mut this = Self {
  243. handle,
  244. device,
  245. render_pass: None,
  246. framebuffer: None,
  247. pipeline: None,
  248. vertex_buffer: None,
  249. index_buffer: None,
  250. descriptor_pool: None,
  251. };
  252. unsafe {
  253. this.device.begin_command_buffer(this.handle, &cmd_begin_info)?;
  254. f(&mut this);
  255. this.device.end_command_buffer(this.handle)?;
  256. }
  257. Ok(this)
  258. }
  259. }
  260. impl Drop for CommandPool {
  261. fn drop(&mut self) {
  262. unsafe {
  263. self.device.free_command_buffers(self.handle, &self.buf_handles);
  264. self.device.destroy_command_pool(self.handle, None);
  265. }
  266. }
  267. }
  268. impl std::ops::Deref for CommandPool {
  269. type Target = vk::CommandPool;
  270. fn deref(&self) -> &Self::Target {
  271. &self.handle
  272. }
  273. }
  274. impl std::ops::Deref for CommandBuffer {
  275. type Target = vk::CommandBuffer;
  276. fn deref(&self) -> &Self::Target {
  277. &self.handle
  278. }
  279. }
  280. // EOF