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.

195 lines
5.5KB

  1. use crate::render::{Device, PipelineLayout, RenderPass, ShaderModule, Vertex};
  2. use ash::{version::DeviceV1_0, vk};
  3. use std::rc::Rc;
  4. pub struct PipelineCreateInfo {
  5. shader_data: Vec<Rc<ShaderModule>>,
  6. layout: Rc<PipelineLayout>,
  7. render_pass: Rc<RenderPass>,
  8. shader_stages: Vec<vk::PipelineShaderStageCreateInfo>,
  9. vertex_input_state: vk::PipelineVertexInputStateCreateInfo,
  10. input_assembly_state: vk::PipelineInputAssemblyStateCreateInfo,
  11. viewports: Vec<vk::Viewport>,
  12. scissors: Vec<vk::Rect2D>,
  13. rasterization_state: vk::PipelineRasterizationStateCreateInfo,
  14. multisample_state: vk::PipelineMultisampleStateCreateInfo,
  15. color_blend_attachments: Vec<vk::PipelineColorBlendAttachmentState>,
  16. }
  17. pub struct Pipeline {
  18. handle: vk::Pipeline,
  19. pub device: Rc<Device>,
  20. pub shader_data: Vec<Rc<ShaderModule>>,
  21. pub layout: Rc<PipelineLayout>,
  22. pub render_pass: Rc<RenderPass>,
  23. }
  24. impl PipelineCreateInfo {
  25. pub fn info_basic(
  26. shader_vert: Rc<ShaderModule>,
  27. shader_frag: Rc<ShaderModule>,
  28. layout: Rc<PipelineLayout>,
  29. render_pass: Rc<RenderPass>,
  30. extent: vk::Extent2D,
  31. ) -> Self {
  32. Self {
  33. layout,
  34. render_pass,
  35. shader_data: vec![shader_vert.clone(), shader_frag.clone()],
  36. shader_stages: vec![
  37. vk::PipelineShaderStageCreateInfo {
  38. stage: vk::ShaderStageFlags::VERTEX,
  39. module: **shader_vert,
  40. p_name: c_str!("main"),
  41. ..Default::default()
  42. },
  43. vk::PipelineShaderStageCreateInfo {
  44. stage: vk::ShaderStageFlags::FRAGMENT,
  45. module: **shader_frag,
  46. p_name: c_str!("main"),
  47. ..Default::default()
  48. },
  49. ],
  50. vertex_input_state: vk::PipelineVertexInputStateCreateInfo {
  51. vertex_binding_description_count: Vertex::BIND_DESC.len() as u32,
  52. p_vertex_binding_descriptions: Vertex::BIND_DESC.as_ptr(),
  53. vertex_attribute_description_count: Vertex::ATTR_DESC.len() as u32,
  54. p_vertex_attribute_descriptions: Vertex::ATTR_DESC.as_ptr(),
  55. ..Default::default()
  56. },
  57. input_assembly_state: vk::PipelineInputAssemblyStateCreateInfo {
  58. topology: vk::PrimitiveTopology::TRIANGLE_LIST,
  59. primitive_restart_enable: vk::FALSE,
  60. ..Default::default()
  61. },
  62. viewports: vec![
  63. vk::Viewport {
  64. x: 0.0,
  65. y: 0.0,
  66. width: extent.width as f32,
  67. height: extent.height as f32,
  68. min_depth: 0.0,
  69. max_depth: 1.0,
  70. }
  71. ],
  72. scissors: vec![
  73. vk::Rect2D { extent, offset: vk::Offset2D::default() }
  74. ],
  75. rasterization_state: vk::PipelineRasterizationStateCreateInfo {
  76. polygon_mode: vk::PolygonMode::FILL,
  77. line_width: 1.0,
  78. cull_mode: vk::CullModeFlags::BACK,
  79. front_face: vk::FrontFace::COUNTER_CLOCKWISE,
  80. ..Default::default()
  81. },
  82. multisample_state: vk::PipelineMultisampleStateCreateInfo {
  83. sample_shading_enable: vk::FALSE,
  84. rasterization_samples: vk::SampleCountFlags::TYPE_1,
  85. min_sample_shading: 1.0,
  86. ..Default::default()
  87. },
  88. color_blend_attachments: vec![
  89. vk::PipelineColorBlendAttachmentState {
  90. color_write_mask: vk::ColorComponentFlags::all(),
  91. ..Default::default()
  92. }
  93. ],
  94. }
  95. }
  96. }
  97. impl Pipeline {
  98. pub fn create_all(
  99. device: Rc<Device>,
  100. infos: &[PipelineCreateInfo],
  101. ) -> Result<Vec<Rc<Self>>, vk::Result> {
  102. let viewport_states = infos
  103. .iter()
  104. .map(|info| vk::PipelineViewportStateCreateInfo {
  105. viewport_count: info.viewports.len() as u32,
  106. p_viewports: info.viewports.as_ptr(),
  107. scissor_count: info.scissors.len() as u32,
  108. p_scissors: info.scissors.as_ptr(),
  109. ..Default::default()
  110. })
  111. .collect::<Vec<_>>();
  112. let color_blend_states = infos
  113. .iter()
  114. .map(|info| vk::PipelineColorBlendStateCreateInfo {
  115. attachment_count: info.color_blend_attachments.len() as u32,
  116. p_attachments: info.color_blend_attachments.as_ptr(),
  117. ..Default::default()
  118. })
  119. .collect::<Vec<_>>();
  120. let create_info = infos
  121. .iter()
  122. .zip(viewport_states.iter())
  123. .zip(color_blend_states.iter())
  124. .map(|((info, viewport_state), color_blend_state)| {
  125. vk::GraphicsPipelineCreateInfo {
  126. layout: **info.layout,
  127. render_pass: **info.render_pass,
  128. stage_count: info.shader_stages.len() as u32,
  129. p_stages: info.shader_stages.as_ptr(),
  130. p_vertex_input_state: &info.vertex_input_state,
  131. p_input_assembly_state: &info.input_assembly_state,
  132. p_viewport_state: viewport_state,
  133. p_rasterization_state: &info.rasterization_state,
  134. p_multisample_state: &info.multisample_state,
  135. p_color_blend_state: color_blend_state,
  136. ..Default::default()
  137. }
  138. })
  139. .collect::<Vec<_>>();
  140. let pipelines = unsafe {
  141. device
  142. .create_graphics_pipelines(
  143. vk::PipelineCache::null(),
  144. &create_info,
  145. None,
  146. )
  147. .or_else(|(pipelines, r)| {
  148. for pipeline in pipelines {
  149. device.destroy_pipeline(pipeline, None);
  150. }
  151. Err(r)
  152. })?
  153. .iter()
  154. .zip(infos.iter())
  155. .map(|(&handle, info)| {
  156. Rc::new(Self {
  157. handle,
  158. device: device.clone(),
  159. shader_data: info.shader_data.clone(),
  160. layout: info.layout.clone(),
  161. render_pass: info.render_pass.clone(),
  162. })
  163. })
  164. .collect()
  165. };
  166. Ok(pipelines)
  167. }
  168. }
  169. impl Drop for Pipeline {
  170. fn drop(&mut self) {
  171. unsafe {
  172. self.device.destroy_pipeline(self.handle, None);
  173. }
  174. }
  175. }
  176. impl std::ops::Deref for Pipeline {
  177. type Target = vk::Pipeline;
  178. fn deref(&self) -> &Self::Target {
  179. &self.handle
  180. }
  181. }
  182. // EOF