rotex_vulkan/backend/vulkan/
pass.rs1use ash::vk;
2
3use super::device::Device;
4
5#[derive(Debug, Clone)]
6pub struct SubpassBlueprint {
7 pub color_attachments: Vec<u32>,
8 pub depth_attachment: Option<u32>,
9}
10
11pub struct RenderPass {
12 pub(crate) render_pass: vk::RenderPass,
13 attachments: Vec<vk::AttachmentDescription>,
14}
15
16impl RenderPass {
17 pub fn handle(&self) -> vk::RenderPass {
18 self.render_pass
19 }
20
21 pub fn attachments(&self) -> &[vk::AttachmentDescription] {
22 &self.attachments
23 }
24
25 pub fn destroy(&self, device: &Device) {
26 unsafe {
27 device
28 .logical_device()
29 .destroy_render_pass(self.render_pass, None);
30 }
31 }
32}
33
34pub struct RenderPassBuilder {
35 attachments: Vec<vk::AttachmentDescription>,
36 subpasses: Vec<SubpassBlueprint>,
37 dependencies: Vec<vk::SubpassDependency>,
38}
39
40impl RenderPassBuilder {
41 pub fn new() -> Self {
42 Self {
43 attachments: Vec::new(),
44 subpasses: Vec::new(),
45 dependencies: Vec::new(),
46 }
47 }
48
49 pub fn with_attachment(mut self, attachment: vk::AttachmentDescription) -> Self {
50 self.attachments.push(attachment);
51 self
52 }
53
54 pub fn with_subpass(mut self, subpass: SubpassBlueprint) -> Self {
55 self.subpasses.push(subpass);
56 self
57 }
58
59 pub fn with_dependency(mut self, dependency: vk::SubpassDependency) -> Self {
60 self.dependencies.push(dependency);
61 self
62 }
63
64 pub fn build(self, device: &Device) -> Result<RenderPass, vk::Result> {
65 let mut all_color_refs: Vec<Vec<vk::AttachmentReference>> =
66 Vec::with_capacity(self.subpasses.len());
67 let mut all_depth_refs: Vec<Option<vk::AttachmentReference>> =
68 Vec::with_capacity(self.subpasses.len());
69
70 for blueprint in &self.subpasses {
71 let color_refs: Vec<vk::AttachmentReference> = blueprint
72 .color_attachments
73 .iter()
74 .map(|&idx| {
75 vk::AttachmentReference::default()
76 .attachment(idx)
77 .layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
78 })
79 .collect();
80 all_color_refs.push(color_refs);
81
82 let depth_ref = blueprint.depth_attachment.map(|idx| {
83 vk::AttachmentReference::default()
84 .attachment(idx)
85 .layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
86 });
87 all_depth_refs.push(depth_ref);
88 }
89
90 let mut vk_subpasses: Vec<vk::SubpassDescription> = Vec::with_capacity(self.subpasses.len());
91
92 for i in 0..self.subpasses.len() {
93 let mut subpass_desc = vk::SubpassDescription::default()
94 .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS)
95 .color_attachments(&all_color_refs[i]);
96
97 if let Some(depth_ref) = &all_depth_refs[i] {
98 subpass_desc = subpass_desc.depth_stencil_attachment(depth_ref);
99 }
100
101 vk_subpasses.push(subpass_desc);
102 }
103
104 let render_pass_info = vk::RenderPassCreateInfo::default()
105 .attachments(&self.attachments)
106 .subpasses(&vk_subpasses)
107 .dependencies(&self.dependencies);
108
109 let render_pass = unsafe {
110 device
111 .logical_device()
112 .create_render_pass(&render_pass_info, None)?
113 };
114 Ok(RenderPass {
115 render_pass,
116 attachments: self.attachments,
117 })
118 }
119}