-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrender_pass.rs
More file actions
124 lines (110 loc) · 4.12 KB
/
render_pass.rs
File metadata and controls
124 lines (110 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use ash;
use ash::vk;
/// Raw Vulkan objects used to create vk::RenderPass
pub type AttachmentDefinition = (vk::AttachmentDescription, vk::AttachmentReference);
///
/// - presentable - `true` if image is rendered to window framebuffer. `false` if it's user-created texture
pub fn create_color_attachment(
attachment_idx: u32,
image_format: vk::Format,
load_op: vk::AttachmentLoadOp,
store_op: vk::AttachmentStoreOp,
presentable: bool,
) -> AttachmentDefinition {
let final_layout = if presentable {
vk::ImageLayout::PRESENT_SRC_KHR
} else {
vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL
};
let attachment = vk::AttachmentDescription::builder()
.format(image_format)
.samples(vk::SampleCountFlags::TYPE_1) // single sampled
.load_op(load_op)
.store_op(store_op)
.initial_layout(final_layout)
.final_layout(final_layout)
.build();
let attachment_reference = vk::AttachmentReference {
attachment: attachment_idx,
layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
};
(attachment, attachment_reference)
}
pub fn create_depth_stencil_attachment(
attachment_idx: u32,
image_format: vk::Format,
depth_load_op: vk::AttachmentLoadOp,
depth_store_op: vk::AttachmentStoreOp,
stencil_load_op: vk::AttachmentLoadOp,
stencil_store_op: vk::AttachmentStoreOp,
final_layout: vk::ImageLayout,
) -> AttachmentDefinition {
let attachment = vk::AttachmentDescription::builder()
.format(image_format)
.samples(vk::SampleCountFlags::TYPE_1) // single sampled
.load_op(depth_load_op)
.store_op(depth_store_op)
.stencil_load_op(stencil_load_op)
.stencil_store_op(stencil_store_op)
.initial_layout(final_layout)
.final_layout(final_layout)
.build();
let attachment_reference = vk::AttachmentReference {
attachment: attachment_idx,
layout: final_layout,
};
(attachment, attachment_reference)
}
pub unsafe fn create_render_pass_from_attachments(
device: &ash::Device,
depth: Option<AttachmentDefinition>,
colors: &[AttachmentDefinition],
) -> vk::RenderPass {
// TODO [LOW] this fn can implicitly change layouts by itself - use instead of `cmd_transition_attachments_for_write_barrier`?
let mut all_attachment_descs = Vec::<vk::AttachmentDescription>::with_capacity(colors.len() + 1);
let mut src_stage_mask = vk::PipelineStageFlags::empty();
let mut dst_stage_mask = vk::PipelineStageFlags::empty();
let mut dst_access_mask = vk::AccessFlags::empty();
let color_refs = colors.iter().map(|a| a.1).collect::<Vec<_>>();
let mut subpass = vk::SubpassDescription::builder()
.pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS)
.color_attachments(&color_refs)
// depth added below
.build();
// depth
if let Some(a_ds) = depth {
src_stage_mask = src_stage_mask
| vk::PipelineStageFlags::EARLY_FRAGMENT_TESTS
| vk::PipelineStageFlags::LATE_FRAGMENT_TESTS;
dst_stage_mask = dst_stage_mask
| vk::PipelineStageFlags::EARLY_FRAGMENT_TESTS
| vk::PipelineStageFlags::LATE_FRAGMENT_TESTS;
dst_access_mask = dst_access_mask | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE;
all_attachment_descs.push(a_ds.0);
subpass.p_depth_stencil_attachment = &a_ds.1 as *const vk::AttachmentReference;
}
// colors
if colors.len() > 0 {
src_stage_mask = src_stage_mask | vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT;
dst_stage_mask = dst_stage_mask | vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT;
dst_access_mask = dst_access_mask | vk::AccessFlags::COLOR_ATTACHMENT_WRITE;
}
colors.iter().for_each(|a| all_attachment_descs.push(a.0));
// probably does not matter if we have only 1 subpass?
let dependencies = vk::SubpassDependency::builder()
.src_subpass(vk::SUBPASS_EXTERNAL)
.dst_subpass(0)
.src_stage_mask(src_stage_mask)
.src_access_mask(vk::AccessFlags::empty())
.dst_stage_mask(dst_stage_mask)
.dst_access_mask(dst_access_mask)
.build();
let create_info = vk::RenderPassCreateInfo::builder()
.dependencies(&[dependencies])
.attachments(&all_attachment_descs)
.subpasses(&[subpass])
.build();
device
.create_render_pass(&create_info, None)
.expect("Failed creating render pass")
}