Skip to content

Commit 36ede71

Browse files
committed
[*] Add wrapper code for descriptors and textures for rendergraph2
1 parent d3edccb commit 36ede71

27 files changed

+1248
-10
lines changed

example-app/application.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,8 @@ ExampleApp::ExampleApp(int argc, char **argv) {
382382
m_device = std::make_unique<Device>(*m_instance, m_surface->surface(), physical_device, required_features,
383383
required_extensions);
384384

385-
m_swapchain = std::make_unique<Swapchain>(*m_device, m_surface->surface(), m_window->width(), m_window->height(),
386-
m_vsync_enabled);
385+
m_swapchain = std::make_unique<Swapchain>(*m_device, "Default Swapchain", m_surface->surface(), m_window->width(),
386+
m_window->height(), m_vsync_enabled);
387387

388388
m_camera = std::make_unique<Camera>(glm::vec3(6.0f, 10.0f, 2.0f), 180.0f, 0.0f,
389389
static_cast<float>(m_window->width()), static_cast<float>(m_window->height()));

example-app/renderer.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class RenderGraph;
5555
// Using declarations
5656
using inexor::vulkan_renderer::BufferResource;
5757
using inexor::vulkan_renderer::BufferUsage;
58-
using inexor::vulkan_renderer ::GraphicsStage;
58+
using inexor::vulkan_renderer::GraphicsStage;
5959
using inexor::vulkan_renderer::ImGUIOverlay;
6060
using inexor::vulkan_renderer::PhysicalStage;
6161
using inexor::vulkan_renderer::RenderGraph;

include/inexor/vulkan-renderer/render-graph/buffer.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class Buffer {
4444

4545
// TODO: Add methods create(), destroy_buffer(), destroy_staging_buffer(), destroy_all()
4646

47+
/// The descriptor buffer info (required for uniform buffers)
48+
VkDescriptorBufferInfo m_descriptor_buffer_info;
49+
4750
public:
4851
/// Default constructor
4952
/// @param device The device wrapper
@@ -57,6 +60,10 @@ class Buffer {
5760

5861
Buffer &operator=(const Buffer &) = delete;
5962
Buffer &operator=(Buffer &&) = delete;
63+
64+
[[nodiscard]] const auto *descriptor_buffer_info() const {
65+
return &m_descriptor_buffer_info;
66+
}
6067
};
6168

6269
} // namespace inexor::vulkan_renderer::render_graph
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#pragma once
2+
3+
#include <volk.h>
4+
5+
#include "inexor/vulkan-renderer/render-graph/buffer.hpp"
6+
#include "inexor/vulkan-renderer/render-graph/texture.hpp"
7+
#include "inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout.hpp"
8+
#include "inexor/vulkan-renderer/wrapper/device.hpp"
9+
#include "inexor/vulkan-renderer/wrapper/swapchains/swapchain.hpp"
10+
11+
#include <array>
12+
#include <functional>
13+
#include <memory>
14+
#include <optional>
15+
#include <string>
16+
17+
namespace inexor::vulkan_renderer::wrapper::commands {
18+
// Forward declaration
19+
class CommandBuffer;
20+
} // namespace inexor::vulkan_renderer::wrapper::commands
21+
22+
namespace inexor::vulkan_renderer::render_graph {
23+
24+
// Forward declaration
25+
class RenderGraph;
26+
27+
// Using declarations
28+
using wrapper::CommandBuffer;
29+
using wrapper::descriptors::DescriptorSetLayout;
30+
using wrapper::swapchains::Swapchain;
31+
32+
/// Using declaration
33+
using OnRecordCommandBufferForPass = std::function<void(const CommandBuffer &)>;
34+
35+
/// A wrapper for graphics passes inside of rendergraph
36+
class GraphicsPass {
37+
friend class RenderGraph;
38+
39+
private:
40+
/// The name of the graphics pass
41+
std::string m_name;
42+
/// The command buffer recording function of the graphics pass
43+
OnRecordCommandBufferForPass m_on_record_cmd_buffer{[](auto &) {}};
44+
/// The descriptor set layout of the pass (this will be created by rendergraph)
45+
std::unique_ptr<DescriptorSetLayout> m_descriptor_set_layout;
46+
/// The descriptor set of the pass (this will be created by rendergraph)
47+
VkDescriptorSet m_descriptor_set{VK_NULL_HANDLE};
48+
/// The color of the debug label region (visible in graphics debuggers like RenderDoc)
49+
std::array<float, 4> m_debug_label_color;
50+
/// The extent
51+
VkExtent2D m_extent{0, 0};
52+
/// The graphics passes this pass reads from
53+
std::vector<std::weak_ptr<GraphicsPass>> m_graphics_pass_reads;
54+
/// TODO: Do we need this?
55+
/// A weak pointer to the previous graphics pass
56+
std::weak_ptr<GraphicsPass> m_previous_pass{};
57+
/// A weak pointer to the next graphics pass
58+
std::weak_ptr<GraphicsPass> m_next_pass{};
59+
/// The texture attachments of this pass (unified means color, depth, stencil attachment or a swapchain)
60+
std::vector<std::pair<std::weak_ptr<Texture>, std::optional<VkClearValue>>> m_write_attachments{};
61+
/// The swapchains this graphics pass writes to
62+
std::vector<std::pair<std::weak_ptr<Swapchain>, std::optional<VkClearValue>>> m_write_swapchains{};
63+
64+
// All the data below will be filled and used by rendergraph only
65+
66+
/// The rendering info will be filled during rendergraph compilation so we don't have to do this while rendering.
67+
/// This means we must make sure that the memory of the attachment infos below is still valid during rendering,
68+
/// which is why we store them as members here.
69+
VkRenderingInfo m_rendering_info{};
70+
/// The color attachments inside of m_rendering_info
71+
std::vector<VkRenderingAttachmentInfo> m_color_attachments{};
72+
/// Does this graphics pass have any depth attachment?
73+
bool m_has_depth_attachment{false};
74+
/// The depth attachment inside of m_rendering_info
75+
VkRenderingAttachmentInfo m_depth_attachment{};
76+
/// Does this graphics pass have any stencil attachment?
77+
bool m_has_stencil_attachment{false};
78+
/// The stencil attachment inside of m_rendering_info
79+
VkRenderingAttachmentInfo m_stencil_attachment{};
80+
81+
/// Reset the rendering info
82+
void reset_rendering_info();
83+
84+
public:
85+
/// Default constructor
86+
/// @param name The name of the graphics pass
87+
/// @param on_record_cmd_buffer The command buffer recording function of the graphics pass
88+
/// @param graphics_pass_reads The graphics passes this graphics pass reads from
89+
/// @param write_attachments The attachment this graphics pass writes to
90+
/// @param write_swapchains The swapchains this graphics pass writes to
91+
/// @param pass_debug_label_color The debug label of the pass (visible in graphics debuggers like RenderDoc)
92+
GraphicsPass(std::string name, OnRecordCommandBufferForPass on_record_cmd_buffer,
93+
std::vector<std::weak_ptr<GraphicsPass>> graphics_pass_reads,
94+
std::vector<std::pair<std::weak_ptr<Texture>, std::optional<VkClearValue>>> write_attachments,
95+
std::vector<std::pair<std::weak_ptr<Swapchain>, std::optional<VkClearValue>>> write_swapchains,
96+
wrapper::DebugLabelColor pass_debug_label_color);
97+
98+
GraphicsPass(const GraphicsPass &) = delete;
99+
GraphicsPass(GraphicsPass &&other) noexcept;
100+
~GraphicsPass() = default;
101+
102+
GraphicsPass &operator=(const GraphicsPass &) = delete;
103+
GraphicsPass &operator=(GraphicsPass &&) = delete;
104+
};
105+
106+
} // namespace inexor::vulkan_renderer::render_graph

include/inexor/vulkan-renderer/render-graph/render_graph.hpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "inexor/vulkan-renderer/render-graph/buffer.hpp"
4+
#include "inexor/vulkan-renderer/render-graph/graphics_pass.hpp"
45
#include "inexor/vulkan-renderer/render-graph/texture.hpp"
56

67
#include <memory>
@@ -24,9 +25,11 @@ class RenderGraph {
2425
const Device &m_device;
2526

2627
/// The buffers (vertex buffers, index buffers, uniform buffers...)
27-
std::vector<std::shared_ptr<render_graph::Buffer>> m_buffers;
28+
std::vector<std::shared_ptr<Buffer>> m_buffers;
2829
/// The textures (back buffers, depth buffers, textures...)
29-
std::vector<std::shared_ptr<render_graph::Texture>> m_textures;
30+
std::vector<std::shared_ptr<Texture>> m_textures;
31+
/// The graphics passes
32+
std::vector<std::shared_ptr<GraphicsPass>> m_graphics_passes;
3033

3134
public:
3235
/// Default constructor
@@ -40,6 +43,13 @@ class RenderGraph {
4043
/// @return A weak pointer to the buffer resource which was created
4144
std::weak_ptr<Buffer> add_buffer(std::string name, BufferType type, std::function<void()> on_update);
4245

46+
///
47+
///
48+
///
49+
///
50+
///
51+
std::weak_ptr<GraphicsPass> add_graphics_pass();
52+
4353
// @TODO How to handle optional texture update depending on texture type?
4454

4555
/// Add a texture to the rendergraph
@@ -50,6 +60,12 @@ class RenderGraph {
5060
std::weak_ptr<Texture> add_texture(std::string name, TextureType type,
5161
std::optional<std::function<void()>> on_update = std::nullopt);
5262

63+
/// Compile the rendergraph
64+
void compile();
65+
66+
/// Render the rendergraph
67+
void render();
68+
5369
/// Reset the entire rendergraph
5470
void reset();
5571
};

include/inexor/vulkan-renderer/render-graph/texture.hpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
#pragma once
22

3+
#include "inexor/vulkan-renderer/wrapper/image.hpp"
4+
#include "inexor/vulkan-renderer/wrapper/sampler.hpp"
5+
36
#include <functional>
7+
#include <memory>
48
#include <optional>
59
#include <string>
610

711
namespace inexor::vulkan_renderer::wrapper {
812
// Forward declaration
913
class Device;
14+
class Image;
15+
class Sampler;
1016
} // namespace inexor::vulkan_renderer::wrapper
1117

1218
namespace inexor::vulkan_renderer::render_graph {
1319

1420
// Using declaration
1521
using wrapper::Device;
22+
using wrapper::Image;
23+
using wrapper::Sampler;
1624

1725
/// Specifies the use of the texture
1826
enum class TextureType {
@@ -33,6 +41,44 @@ class Texture {
3341
// The texture update function
3442
std::optional<std::function<void()>> m_on_update;
3543

44+
/// The format of the texture
45+
VkFormat m_format{VK_FORMAT_UNDEFINED};
46+
/// The width of the texture
47+
std::uint32_t m_width{0};
48+
/// The height of the texture
49+
std::uint32_t m_height{0};
50+
/// The channel count of the texture (4 by default)
51+
// TODO: Can we determine the number of channels based on the given format?
52+
std::uint32_t m_channels{4};
53+
/// The sample count of the MSAA image (if MSAA is enabled)
54+
VkSampleCountFlagBits m_samples{VK_SAMPLE_COUNT_1_BIT};
55+
56+
std::unique_ptr<Sampler> m_default_sampler;
57+
58+
/// The image of the texture
59+
std::shared_ptr<Image> m_image;
60+
61+
// TODO: MSAA support?
62+
63+
// This is used for initializing textures and for updating dynamic textures
64+
bool m_update_requested{true};
65+
void *m_src_texture_data{nullptr};
66+
std::size_t m_src_texture_data_size{0};
67+
68+
/// By definition, if this is not std::nullopt, this is a dynamic texture
69+
std::function<void()> m_on_check_for_updates;
70+
71+
// The staging buffer for updating the texture data
72+
VkBuffer m_staging_buffer{VK_NULL_HANDLE};
73+
VmaAllocation m_staging_buffer_alloc{VK_NULL_HANDLE};
74+
VmaAllocationInfo m_staging_buffer_alloc_info{};
75+
76+
/// This part of the image wrapper is for external use outside of rendergraph
77+
/// The descriptor image info required for descriptor updates
78+
VkDescriptorImageInfo m_descriptor_img_info{};
79+
80+
// @TODO: create(), destroy() destroy_staging_buffer(), update()
81+
3682
public:
3783
/// Default constructor
3884
/// @param device The device wrapper
@@ -41,11 +87,54 @@ class Texture {
4187
/// @param on_update The texture update function
4288
Texture(const Device &device, std::string name, TextureType type, std::optional<std::function<void()>> on_update);
4389

90+
/*
91+
/// Default constructor
92+
/// @param device The device wrapper
93+
/// @param name The internal debug name of the texture
94+
/// @param usage The usage of the texture inside of rendergraph
95+
/// @param format The format of the texture
96+
/// @param width The width of the texture
97+
/// @param height The height of the texture
98+
/// @param channels The channel count of the texture
99+
/// @param samples The sample count of the texture
100+
/// @param on_check_for_updates The update function of the texture
101+
Texture(const Device &device,
102+
std::string name,
103+
TextureUsage usage,
104+
VkFormat format,
105+
std::uint32_t width,
106+
std::uint32_t height,
107+
std::uint32_t channels,
108+
VkSampleCountFlagBits samples,
109+
std::function<void()> on_check_for_updates);
110+
*/
111+
44112
Texture(const Texture &) = delete;
45113
Texture(Texture &&) noexcept;
46114

47115
Texture &operator=(const Texture &) = delete;
48116
Texture &operator=(Texture &&) = delete;
117+
118+
[[nodiscard]] const auto *descriptor_image_info() const {
119+
return &m_descriptor_img_info;
120+
}
121+
122+
[[nodiscard]] VkExtent2D extent() const {
123+
return {
124+
.width = m_width,
125+
.height = m_height,
126+
};
127+
}
128+
129+
[[nodiscard]] VkFormat format() const {
130+
return m_format;
131+
}
132+
133+
[[nodiscard]] const auto &name() const {
134+
return m_name;
135+
}
136+
137+
// TODO: Request update method!
49138
};
50139

51140
} // namespace inexor::vulkan_renderer::render_graph
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#pragma once
2+
3+
#include <volk.h>
4+
5+
#include <cstdint>
6+
#include <string>
7+
#include <vector>
8+
9+
namespace inexor::vulkan_renderer::wrapper {
10+
// Forward declaration
11+
class Device;
12+
} // namespace inexor::vulkan_renderer::wrapper
13+
14+
namespace inexor::vulkan_renderer::wrapper::descriptors {
15+
16+
// Forward declaration
17+
class DescriptorPoolAllocator;
18+
19+
/// RAII wrapper for VkDescriptorPool
20+
/// For internal use inside of rendergraph only!
21+
class DescriptorPool {
22+
private:
23+
const Device &m_device;
24+
VkDescriptorPool m_descriptor_pool{VK_NULL_HANDLE};
25+
std::vector<VkDescriptorPoolSize> m_pool_sizes;
26+
std::string m_name;
27+
28+
public:
29+
/// Default constructor is private so only DescriptorPoolAllocator can access it
30+
/// @param device The device wrapper
31+
/// @param pool_sizes The descriptor pool sizes (must not be empty!)
32+
/// @param max_sets The max descriptor set count
33+
/// @param name The internal debug name of this descriptor pool (must not be empty!)
34+
/// @exception std::invalid_argument Internal debug name for descriptor pool must not be empty
35+
/// @exception std::invalid_argument Descriptor pool sizes must not be empty
36+
/// @exception VulkanException vkCreateDescriptorPool call failed
37+
DescriptorPool(const Device &device, std::vector<VkDescriptorPoolSize> pool_sizes, std::uint32_t max_sets,
38+
std::string name);
39+
40+
DescriptorPool(const DescriptorPool &) = delete;
41+
DescriptorPool(DescriptorPool &&) noexcept;
42+
43+
/// Call vkDestroyDescriptorPool
44+
~DescriptorPool();
45+
46+
DescriptorPool &operator=(const DescriptorPool &) = delete;
47+
DescriptorPool &operator=(DescriptorPool &&) = delete;
48+
49+
[[nodiscard]] auto descriptor_pool() const noexcept {
50+
return m_descriptor_pool;
51+
}
52+
};
53+
54+
} // namespace inexor::vulkan_renderer::wrapper::descriptors

0 commit comments

Comments
 (0)