MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
VKRenderPass.cpp
Go to the documentation of this file.
1#include "VKRenderPass.hpp"
2
4
5namespace MayaFlux::Core {
6
7bool VKRenderPass::create(vk::Device device, vk::Format color_format)
8{
9 vk::AttachmentDescription color_attachment {};
10 color_attachment.format = color_format;
11 color_attachment.samples = vk::SampleCountFlagBits::e1;
12 color_attachment.loadOp = vk::AttachmentLoadOp::eClear;
13 color_attachment.storeOp = vk::AttachmentStoreOp::eStore;
14 color_attachment.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
15 color_attachment.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
16 color_attachment.initialLayout = vk::ImageLayout::eUndefined;
17 color_attachment.finalLayout = vk::ImageLayout::ePresentSrcKHR;
18
19 vk::AttachmentReference color_attachment_ref {};
20 color_attachment_ref.attachment = 0;
21 color_attachment_ref.layout = vk::ImageLayout::eColorAttachmentOptimal;
22
23 vk::SubpassDescription subpass {};
24 subpass.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
25 subpass.colorAttachmentCount = 1;
26 subpass.pColorAttachments = &color_attachment_ref;
27
28 vk::RenderPassCreateInfo render_pass_info {};
29 render_pass_info.attachmentCount = 1;
30 render_pass_info.pAttachments = &color_attachment;
31 render_pass_info.subpassCount = 1;
32 render_pass_info.pSubpasses = &subpass;
33
34 try {
35 m_render_pass = device.createRenderPass(render_pass_info);
36 return true;
37 } catch (const vk::SystemError& e) {
38 MF_ERROR(Journal::Component::Core, Journal::Context::GraphicsBackend, "Failed to create render pass: {}", e.what());
39 return false;
40 }
41}
42
43bool VKRenderPass::create(vk::Device device, const RenderPassCreateInfo& create_info)
44{
45 if (create_info.attachments.empty()) {
47 "Cannot create render pass with no attachments");
48 return false;
49 }
50
51 if (create_info.subpasses.empty()) {
53 "Cannot create render pass with no subpasses");
54 return false;
55 }
56
57 m_attachments = create_info.attachments;
58
59 std::vector<vk::AttachmentDescription> vk_attachments;
60 vk_attachments.reserve(create_info.attachments.size());
61
62 for (const auto& attachment : create_info.attachments) {
63 vk::AttachmentDescription vk_attachment;
64 vk_attachment.format = attachment.format;
65 vk_attachment.samples = attachment.samples;
66 vk_attachment.loadOp = attachment.load_op;
67 vk_attachment.storeOp = attachment.store_op;
68 vk_attachment.stencilLoadOp = attachment.stencil_load_op;
69 vk_attachment.stencilStoreOp = attachment.stencil_store_op;
70 vk_attachment.initialLayout = attachment.initial_layout;
71 vk_attachment.finalLayout = attachment.final_layout;
72
73 vk_attachments.push_back(vk_attachment);
74 }
75
76 std::vector<vk::SubpassDescription> vk_subpasses;
77 vk_subpasses.reserve(create_info.subpasses.size());
78
79 for (const auto& subpass : create_info.subpasses) {
80 vk::SubpassDescription vk_subpass;
81 vk_subpass.pipelineBindPoint = subpass.bind_point;
82 vk_subpass.colorAttachmentCount = static_cast<uint32_t>(subpass.color_attachments.size());
83 vk_subpass.pColorAttachments = subpass.color_attachments.empty() ? nullptr : subpass.color_attachments.data();
84 vk_subpass.pDepthStencilAttachment = subpass.depth_stencil_attachment.has_value() ? &subpass.depth_stencil_attachment.value() : nullptr;
85 vk_subpass.inputAttachmentCount = static_cast<uint32_t>(subpass.input_attachments.size());
86 vk_subpass.pInputAttachments = subpass.input_attachments.empty() ? nullptr : subpass.input_attachments.data();
87 vk_subpass.pResolveAttachments = subpass.resolve_attachments.empty() ? nullptr : subpass.resolve_attachments.data();
88 vk_subpass.preserveAttachmentCount = static_cast<uint32_t>(subpass.preserve_attachments.size());
89 vk_subpass.pPreserveAttachments = subpass.preserve_attachments.empty() ? nullptr : subpass.preserve_attachments.data();
90
91 vk_subpasses.push_back(vk_subpass);
92 }
93
94 std::vector<vk::SubpassDependency> vk_dependencies;
95 vk_dependencies.reserve(create_info.dependencies.size());
96
97 for (const auto& dependency : create_info.dependencies) {
98 vk::SubpassDependency vk_dependency;
99 vk_dependency.srcSubpass = dependency.src_subpass;
100 vk_dependency.dstSubpass = dependency.dst_subpass;
101 vk_dependency.srcStageMask = dependency.src_stage_mask;
102 vk_dependency.dstStageMask = dependency.dst_stage_mask;
103 vk_dependency.srcAccessMask = dependency.src_access_mask;
104 vk_dependency.dstAccessMask = dependency.dst_access_mask;
105
106 vk_dependencies.push_back(vk_dependency);
107 }
108
109 vk::RenderPassCreateInfo render_pass_info;
110 render_pass_info.attachmentCount = static_cast<uint32_t>(vk_attachments.size());
111 render_pass_info.pAttachments = vk_attachments.data();
112 render_pass_info.subpassCount = static_cast<uint32_t>(vk_subpasses.size());
113 render_pass_info.pSubpasses = vk_subpasses.data();
114 render_pass_info.dependencyCount = static_cast<uint32_t>(vk_dependencies.size());
115 render_pass_info.pDependencies = vk_dependencies.data();
116
117 try {
118 m_render_pass = device.createRenderPass(render_pass_info);
120 "Render pass created with {} attachments, {} subpasses, {} dependencies",
121 vk_attachments.size(), vk_subpasses.size(), vk_dependencies.size());
122 return true;
123 } catch (const vk::SystemError& e) {
125 "Failed to create render pass: {}", e.what());
126 return false;
127 }
128}
129
130void VKRenderPass::cleanup(vk::Device device)
131{
132 if (m_render_pass) {
133 device.destroyRenderPass(m_render_pass);
134 m_render_pass = nullptr;
135 m_attachments.clear();
136 }
137}
138
140{
141 RenderPassCreateInfo create_info;
142
143 AttachmentDescription color_attachment;
144 color_attachment.format = color_format;
145 color_attachment.load_op = vk::AttachmentLoadOp::eClear;
146 color_attachment.store_op = vk::AttachmentStoreOp::eStore;
147 color_attachment.initial_layout = vk::ImageLayout::eUndefined;
148 color_attachment.final_layout = vk::ImageLayout::ePresentSrcKHR;
149 create_info.attachments.push_back(color_attachment);
150
151 SubpassDescription subpass;
152 subpass.color_attachments.emplace_back(0, vk::ImageLayout::eColorAttachmentOptimal);
153 create_info.subpasses.push_back(subpass);
154
155 SubpassDependency dependency;
156 dependency.src_subpass = VK_SUBPASS_EXTERNAL;
157 dependency.dst_subpass = 0;
158 dependency.src_stage_mask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
159 dependency.dst_stage_mask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
160 dependency.dst_access_mask = vk::AccessFlagBits::eColorAttachmentWrite;
161 create_info.dependencies.push_back(dependency);
162
163 return create_info;
164}
165
166RenderPassCreateInfo VKRenderPass::create_default_color_depth(vk::Format color_format, vk::Format depth_format)
167{
168 RenderPassCreateInfo create_info;
169
170 AttachmentDescription color_attachment;
171 color_attachment.format = color_format;
172 color_attachment.load_op = vk::AttachmentLoadOp::eClear;
173 color_attachment.store_op = vk::AttachmentStoreOp::eStore;
174 color_attachment.initial_layout = vk::ImageLayout::eUndefined;
175 color_attachment.final_layout = vk::ImageLayout::ePresentSrcKHR;
176 create_info.attachments.push_back(color_attachment);
177
178 AttachmentDescription depth_attachment;
179 depth_attachment.format = depth_format;
180 depth_attachment.load_op = vk::AttachmentLoadOp::eClear;
181 depth_attachment.store_op = vk::AttachmentStoreOp::eDontCare;
182 depth_attachment.stencil_load_op = vk::AttachmentLoadOp::eDontCare;
183 depth_attachment.stencil_store_op = vk::AttachmentStoreOp::eDontCare;
184 depth_attachment.initial_layout = vk::ImageLayout::eUndefined;
185 depth_attachment.final_layout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
186 create_info.attachments.push_back(depth_attachment);
187
188 SubpassDescription subpass;
189 subpass.color_attachments.emplace_back(0, vk::ImageLayout::eColorAttachmentOptimal);
190 subpass.depth_stencil_attachment = { 1, vk::ImageLayout::eDepthStencilAttachmentOptimal };
191 create_info.subpasses.push_back(subpass);
192
193 SubpassDependency dependency;
194 dependency.src_subpass = VK_SUBPASS_EXTERNAL;
195 dependency.dst_subpass = 0;
196 dependency.src_stage_mask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests;
197 dependency.dst_stage_mask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests;
198 dependency.dst_access_mask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
199 create_info.dependencies.push_back(dependency);
200
201 return create_info;
202}
203
205 vk::Format color_format,
206 vk::ImageLayout final_layout)
207{
208
209 RenderPassCreateInfo create_info;
210
211 AttachmentDescription color_attachment;
212 color_attachment.format = color_format;
213 color_attachment.load_op = vk::AttachmentLoadOp::eClear;
214 color_attachment.store_op = vk::AttachmentStoreOp::eStore;
215 color_attachment.initial_layout = vk::ImageLayout::eUndefined;
216 color_attachment.final_layout = final_layout;
217 create_info.attachments.push_back(color_attachment);
218
219 SubpassDescription subpass;
220 subpass.color_attachments.emplace_back(0, vk::ImageLayout::eColorAttachmentOptimal);
221 create_info.subpasses.push_back(subpass);
222
223 SubpassDependency dependency;
224 dependency.src_subpass = VK_SUBPASS_EXTERNAL;
225 dependency.dst_subpass = 0;
226 dependency.src_stage_mask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
227 dependency.dst_stage_mask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
228 dependency.dst_access_mask = vk::AccessFlagBits::eColorAttachmentWrite;
229 create_info.dependencies.push_back(dependency);
230
231 return create_info;
232}
233
234} // namespace MayaFlux::Core
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
bool create(vk::Device device, vk::Format color_format)
Create a simple render pass with a single color attachment.
static RenderPassCreateInfo create_default_color_depth(vk::Format color_format, vk::Format depth_format)
static RenderPassCreateInfo create_offscreen_color(vk::Format color_format, vk::ImageLayout final_layout=vk::ImageLayout::eShaderReadOnlyOptimal)
static RenderPassCreateInfo create_default_color_only(vk::Format color_format)
void cleanup(vk::Device device)
Clean up the render pass resources.
std::vector< AttachmentDescription > m_attachments
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
@ Core
Core engine, backend, subsystems.
std::vector< AttachmentDescription > attachments
std::vector< SubpassDependency > dependencies
std::vector< SubpassDescription > subpasses
vk::PipelineStageFlags src_stage_mask
vk::PipelineStageFlags dst_stage_mask
std::optional< vk::AttachmentReference > depth_stencil_attachment
std::vector< vk::AttachmentReference > color_attachments