Skip to content

Commit 7d2fc47

Browse files
committed
[render-graph|renderpass] Introduce renderpass wrapper
1 parent 2e0f516 commit 7d2fc47

File tree

5 files changed

+117
-33
lines changed

5 files changed

+117
-33
lines changed

include/inexor/vulkan-renderer/render_graph.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "inexor/vulkan-renderer/wrapper/framebuffer.hpp"
88
#include "inexor/vulkan-renderer/wrapper/image.hpp"
99
#include "inexor/vulkan-renderer/wrapper/pipeline_layout.hpp"
10+
#include "inexor/vulkan-renderer/wrapper/renderpass.hpp"
1011
#include "inexor/vulkan-renderer/wrapper/semaphore.hpp"
1112
#include "inexor/vulkan-renderer/wrapper/shader.hpp"
1213
#include "inexor/vulkan-renderer/wrapper/swapchain.hpp"
@@ -374,8 +375,8 @@ class PhysicalGraphicsStage : public PhysicalStage {
374375
friend RenderGraph;
375376

376377
private:
377-
VkRenderPass m_render_pass{VK_NULL_HANDLE};
378378
std::vector<wrapper::Framebuffer> m_framebuffers;
379+
std::unique_ptr<wrapper::RenderPass> m_render_pass;
379380

380381
public:
381382
explicit PhysicalGraphicsStage(const wrapper::Device &device) : PhysicalStage(device) {}
@@ -385,6 +386,10 @@ class PhysicalGraphicsStage : public PhysicalStage {
385386

386387
PhysicalGraphicsStage &operator=(const PhysicalGraphicsStage &) = delete;
387388
PhysicalGraphicsStage &operator=(PhysicalGraphicsStage &&) = delete;
389+
390+
[[nodiscard]] VkRenderPass render_pass() const noexcept {
391+
return m_render_pass->render_pass();
392+
}
388393
};
389394

390395
class RenderGraph {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#pragma once
2+
3+
#include <vulkan/vulkan_core.h>
4+
5+
#include <string>
6+
#include <vector>
7+
8+
namespace inexor::vulkan_renderer::wrapper {
9+
10+
// Forward declaration
11+
class Device;
12+
13+
/// RAII wrapper for VkRenderPass
14+
class RenderPass {
15+
private:
16+
const Device &m_device;
17+
VkRenderPass m_render_pass{VK_NULL_HANDLE};
18+
std::string m_name;
19+
20+
public:
21+
/// Default constructor
22+
/// @param device The device wrapper
23+
/// @param render_pass_ci The render pass create info
24+
/// @param name The internal debug name of the render pass
25+
RenderPass(const Device &device, const VkRenderPassCreateInfo &render_pass_ci, std::string name);
26+
27+
/// Overloaded constructor which takes the attachment descriptions, subpass descriptions, and subpass dependencies
28+
/// @param device The device wrapper
29+
/// @param render_pass_ci The render pass create info
30+
/// @param attachments The attachment descriptions
31+
/// @param subpasses The subpass descriptions
32+
/// @param dependencies The dependencies
33+
/// @param name The internal debug name of the render pass
34+
RenderPass(const Device &device, const std::vector<VkAttachmentDescription> &attachments,
35+
const std::vector<VkSubpassDescription> &subpasses, const std::vector<VkSubpassDependency> &dependencies,
36+
std::string name);
37+
38+
RenderPass(const RenderPass &) = delete;
39+
RenderPass(RenderPass &&) noexcept;
40+
~RenderPass();
41+
42+
RenderPass &operator=(const RenderPass &) = delete;
43+
RenderPass &operator=(RenderPass &&) = delete;
44+
45+
[[nodiscard]] VkRenderPass render_pass() const noexcept {
46+
return m_render_pass;
47+
}
48+
};
49+
50+
} // namespace inexor::vulkan_renderer::wrapper

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ set(INEXOR_SOURCE_FILES
3636
vulkan-renderer/wrapper/instance.cpp
3737
vulkan-renderer/wrapper/pipeline_layout.cpp
3838
vulkan-renderer/wrapper/make_info.cpp
39+
vulkan-renderer/wrapper/renderpass.cpp
3940
vulkan-renderer/wrapper/sampler.cpp
4041
vulkan-renderer/wrapper/semaphore.cpp
4142
vulkan-renderer/wrapper/shader.cpp

src/vulkan-renderer/render_graph.cpp

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ PhysicalStage::~PhysicalStage() {
5757
vkDestroyPipeline(m_device.device(), m_pipeline, nullptr);
5858
}
5959

60-
PhysicalGraphicsStage::~PhysicalGraphicsStage() {
61-
vkDestroyRenderPass(m_device.device(), m_render_pass, nullptr);
62-
}
60+
PhysicalGraphicsStage::~PhysicalGraphicsStage() {}
6361

6462
void RenderGraph::build_buffer(const BufferResource &buffer_resource, PhysicalBuffer &physical) const {
6563
// TODO: Don't always create mapped.
@@ -159,7 +157,7 @@ void RenderGraph::record_command_buffer(const RenderStage *stage, const wrapper:
159157
}
160158

161159
cmd_buf.begin_render_pass(wrapper::make_info<VkRenderPassBeginInfo>({
162-
.renderPass = phys_graphics_stage->m_render_pass,
160+
.renderPass = phys_graphics_stage->m_render_pass->render_pass(),
163161
.framebuffer = phys_graphics_stage->m_framebuffers.at(image_index).get(),
164162
.renderArea{
165163
.extent = m_swapchain.extent(),
@@ -249,35 +247,27 @@ void RenderGraph::build_render_pass(const GraphicsStage *stage, PhysicalGraphics
249247
attachments.push_back(attachment);
250248
}
251249

252-
// Build a simple subpass that just waits for the output colour vector to be written by the fragment shader. In the
253-
// future, we may want to make use of subpasses more.
254-
const VkSubpassDependency subpass_dependency{
255-
.srcSubpass = VK_SUBPASS_EXTERNAL,
256-
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
257-
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
258-
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
250+
const std::vector<VkSubpassDescription> subpasses{
251+
{
252+
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
253+
.colorAttachmentCount = static_cast<std::uint32_t>(colour_refs.size()),
254+
.pColorAttachments = colour_refs.data(),
255+
.pDepthStencilAttachment = !depth_refs.empty() ? depth_refs.data() : nullptr,
256+
},
259257
};
260258

261-
const VkSubpassDescription subpass_description{
262-
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
263-
.colorAttachmentCount = static_cast<std::uint32_t>(colour_refs.size()),
264-
.pColorAttachments = colour_refs.data(),
265-
.pDepthStencilAttachment = !depth_refs.empty() ? depth_refs.data() : nullptr,
259+
// Build a simple subpass that just waits for the output colour vector to be written by the fragment shader
260+
const std::vector<VkSubpassDependency> dependencies{
261+
{
262+
.srcSubpass = VK_SUBPASS_EXTERNAL,
263+
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
264+
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
265+
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
266+
},
266267
};
267268

268-
const auto render_pass_ci = wrapper::make_info<VkRenderPassCreateInfo>({
269-
.attachmentCount = static_cast<std::uint32_t>(attachments.size()),
270-
.pAttachments = attachments.data(),
271-
.subpassCount = 1,
272-
.pSubpasses = &subpass_description,
273-
.dependencyCount = 1,
274-
.pDependencies = &subpass_dependency,
275-
});
276-
277-
if (const auto result = vkCreateRenderPass(m_device.device(), &render_pass_ci, nullptr, &physical.m_render_pass);
278-
result != VK_SUCCESS) {
279-
throw VulkanException("Error: vkCreateRenderPass failed for renderpass " + stage->name() + " !", result);
280-
}
269+
physical.m_render_pass =
270+
std::make_unique<wrapper::RenderPass>(m_device, attachments, subpasses, dependencies, "renderpass");
281271
}
282272

283273
void RenderGraph::build_graphics_pipeline(const GraphicsStage *stage, PhysicalGraphicsStage &physical) const {
@@ -383,7 +373,7 @@ void RenderGraph::build_graphics_pipeline(const GraphicsStage *stage, PhysicalGr
383373
.pDepthStencilState = &depth_stencil,
384374
.pColorBlendState = &blend_state,
385375
.layout = physical.pipeline_layout(),
386-
.renderPass = physical.m_render_pass,
376+
.renderPass = physical.m_render_pass->render_pass(),
387377
});
388378

389379
// TODO: Pipeline caching (basically load the render graph from a file)
@@ -489,8 +479,8 @@ void RenderGraph::compile(const RenderResource *target) {
489479
for (const auto *image : images) {
490480
image_views.push_back(image->image_view());
491481
}
492-
physical.m_framebuffers.emplace_back(m_device, physical.m_render_pass, image_views, m_swapchain,
493-
"Framebuffer");
482+
physical.m_framebuffers.emplace_back(m_device, physical.m_render_pass->render_pass(), image_views,
483+
m_swapchain, "Framebuffer");
494484
image_views.clear();
495485
}
496486
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "inexor/vulkan-renderer/wrapper/renderpass.hpp"
2+
3+
#include "inexor/vulkan-renderer/wrapper/device.hpp"
4+
#include "inexor/vulkan-renderer/wrapper/make_info.hpp"
5+
6+
#include <utility>
7+
8+
namespace inexor::vulkan_renderer::wrapper {
9+
10+
RenderPass::RenderPass(const Device &device, const VkRenderPassCreateInfo &render_pass_ci, std::string name)
11+
: m_device(device), m_name(std::move(name)) {
12+
m_device.create_render_pass(render_pass_ci, &m_render_pass, m_name);
13+
}
14+
15+
RenderPass::RenderPass(const Device &device, const std::vector<VkAttachmentDescription> &attachments,
16+
const std::vector<VkSubpassDescription> &subpasses,
17+
const std::vector<VkSubpassDependency> &dependencies, std::string name)
18+
: RenderPass(device,
19+
wrapper::make_info<VkRenderPassCreateInfo>({
20+
.attachmentCount = static_cast<std::uint32_t>(attachments.size()),
21+
.pAttachments = attachments.data(),
22+
.subpassCount = static_cast<std::uint32_t>(subpasses.size()),
23+
.pSubpasses = subpasses.data(),
24+
.dependencyCount = static_cast<std::uint32_t>(dependencies.size()),
25+
.pDependencies = dependencies.data(),
26+
}),
27+
std::move(name)) {}
28+
29+
RenderPass::RenderPass(RenderPass &&other) noexcept : m_device(other.m_device) {
30+
m_render_pass = std::exchange(other.m_render_pass, VK_NULL_HANDLE);
31+
m_name = std::move(other.m_name);
32+
}
33+
34+
RenderPass::~RenderPass() {
35+
vkDestroyRenderPass(m_device.device(), m_render_pass, nullptr);
36+
}
37+
38+
} // namespace inexor::vulkan_renderer::wrapper

0 commit comments

Comments
 (0)