Skip to content

Commit

Permalink
[WIP] Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
IAmNotHanni committed Jul 18, 2024
1 parent a522e17 commit e6a656b
Show file tree
Hide file tree
Showing 20 changed files with 308 additions and 229 deletions.
2 changes: 1 addition & 1 deletion include/inexor/vulkan-renderer/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Application {
std::unique_ptr<wrapper::Instance> m_instance;
std::unique_ptr<wrapper::Device> m_device;
std::unique_ptr<wrapper::WindowSurface> m_surface;
std::unique_ptr<wrapper::Swapchain> m_swapchain;
std::shared_ptr<wrapper::Swapchain> m_swapchain;
std::unique_ptr<renderers::ImGuiRenderer> m_imgui_overlay;

std::vector<OctreeGpuVertex> m_octree_vertices;
Expand Down
21 changes: 13 additions & 8 deletions include/inexor/vulkan-renderer/render-graph/buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class CommandBuffer;

namespace inexor::vulkan_renderer::wrapper::descriptors {
/// Forward declaration
class DescriptorSetUpdateBuilder;
class WriteDescriptorSetBuilder;
} // namespace inexor::vulkan_renderer::wrapper::descriptors

namespace inexor::vulkan_renderer::render_graph {
Expand All @@ -35,21 +35,23 @@ enum class BufferType {
// Forward declaration
class GraphicsPass;

using inexor::vulkan_renderer::wrapper::Device;
using inexor::vulkan_renderer::wrapper::commands::CommandBuffer;
using inexor::vulkan_renderer::wrapper::descriptors::DescriptorSetUpdateBuilder;
// Using declarations
using wrapper::Device;
using wrapper::commands::CommandBuffer;
using wrapper::descriptors::WriteDescriptorSetBuilder;

// TODO: Store const reference to rendergraph and retrieve the swapchain image index for automatic buffer tripling

/// RAII wrapper for buffer resources inside of the rendergraph
/// A buffer resource can be a vertex buffer, index buffer, or uniform buffer
class Buffer {
private:
//
friend class RenderGraph;
friend class GraphicsPass;
friend class CommandBuffer;
friend class DescriptorSetUpdateBuilder;
friend class WriteDescriptorSetBuilder;

private:
/// The device wrapper
const Device &m_device;
/// The internal debug name of the buffer resource
Expand Down Expand Up @@ -77,7 +79,7 @@ class Buffer {
/// simplicity however, we made the update function not std::optional.

// TODO: Rewrite description
std::function<void()> m_on_update;
std::function<void()> m_on_check_for_update;

/// TODO: Is this is relevant for uniform buffers only?
/// TODO: Maybe buffer updates should be done immediately, and no m_src_data should be stored!
Expand All @@ -104,8 +106,11 @@ class Buffer {
/// @param cmd_buf The command buffer
void create(const CommandBuffer &cmd_buf);

/// Call destroy_buffer and destroy_staging_buffer
void destroy_all();

/// Call vmaDestroyBuffer for the actual buffer
void destroy();
void destroy_buffer();

/// Call vmaDestroyBuffer for the staging bufffer
void destroy_staging_buffer();
Expand Down
49 changes: 31 additions & 18 deletions include/inexor/vulkan-renderer/render-graph/graphics_pass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "inexor/vulkan-renderer/render-graph/buffer.hpp"
#include "inexor/vulkan-renderer/render-graph/texture.hpp"
#include "inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout.hpp"
#include "inexor/vulkan-renderer/wrapper/swapchain.hpp"

#include <array>
#include <functional>
Expand All @@ -23,10 +24,21 @@ namespace inexor::vulkan_renderer::render_graph {
class RenderGraph;

// Using declaration
using wrapper::Swapchain;
using wrapper::descriptors::DescriptorSetLayout;

/// A rendering attachment is just a texture paired with an optional clear value
using RenderingAttachment = std::pair<std::weak_ptr<Texture>, std::optional<VkClearValue>>;
/// A universal rendering attachment structure for color, depth, stencil attachment and swapchains
struct UniversalRenderingAttachment {
// This pointer will point to either the image view of the attachment or to the image view of the current swapchain
// image. This allows us to treat all attachment types and swapchain in a unified way.
VkImageView *img_view_ptr{nullptr};
/// The extent of the attachment or the swapchain
VkExtent2D *extent_ptr{nullptr};
/// The clear value of the attachment or the swapchain
std::optional<VkClearValue> clear_value{std::nullopt};
};

// TODO: Move this to device wrapper(?)

/// The debug label colors for vkCmdBeginDebugUtilsLabelEXT
enum class DebugLabelColor {
Expand Down Expand Up @@ -56,6 +68,7 @@ enum class DebugLabelColor {

/// A wrapper for graphics passes inside of rendergraph
class GraphicsPass {
//
friend class RenderGraph;

private:
Expand All @@ -69,46 +82,46 @@ class GraphicsPass {
/// The descriptor set of the pass (this will be created by rendergraph)
VkDescriptorSet m_descriptor_set{VK_NULL_HANDLE};

/// The rendering info will be filled during rendergraph compilation so we don't have to do this while rendering
VkRenderingInfo m_rendering_info{};
/// The color of the debug label region (visible in graphics debuggers like RenderDoc)
std::array<float, 4> m_debug_label_color;

// NOTE: The rendering info will be filled during rendergraph compilation with pointers to the members below. This
// means we must make sure that the memory of the attachment infos below is still valid during rendering, which is
// why we store them as members here.

/// The graphics passes this pass reads from
std::vector<std::weak_ptr<GraphicsPass>> m_graphics_pass_reads;

/// The color attachments
std::vector<RenderingAttachment> m_color_attachments{};
/// The depth attachment (only one at maximum)
RenderingAttachment m_depth_attachment{};
/// The stencil attachment (only one at maximum)
RenderingAttachment m_stencil_attachment{};
/// The texture attachments of this pass (unified means color, depth, stencil attachment or a swapchain)
std::vector<std::weak_ptr<Texture>> m_write_attachments{};
/// The swapchains this graphics pass writes to
std::vector<std::weak_ptr<Swapchain>> m_write_swapchains{};

// All the data below will be filled and used by rendergraph only

/// The rendering info will be filled during rendergraph compilation so we don't have to do this while rendering
VkRenderingInfo m_rendering_info{};
/// The color attachments inside of m_rendering_info
std::vector<VkRenderingAttachmentInfo> m_color_attachment_infos{};
/// The depth attachment inside of m_rendering_info
VkRenderingAttachmentInfo m_depth_attachment_info{};
/// The stencil attachment inside of m_rendering_info
VkRenderingAttachmentInfo m_stencil_attachment_info{};

/// The color of the debug label region (visible in graphics debuggers like RenderDoc)
std::array<float, 4> m_debug_label_color;

public:
GraphicsPass(std::string name) : m_name(name) {}

/// Default constructor
/// @param name The name of the graphics pass
/// @param on_record_cmd_buffer The command buffer recording function of the graphics pass
/// @param graphics_pass_reads The graphics passes this graphics pass reads from
/// @param write_attachments The attachment this graphics pass writes to
/// @param color The debug label (visible in graphics debuggers like RenderDoc)
/// @param write_swapchains The swapchains this graphics pass writes to
/// @param pass_debug_label_color The debug label of the pass (visible in graphics debuggers like RenderDoc)
GraphicsPass(std::string name,
std::function<void(const CommandBuffer &)> on_record_cmd_buffer,
std::vector<std::weak_ptr<GraphicsPass>> graphics_pass_reads,
std::vector<RenderingAttachment> write_attachments,
DebugLabelColor color);
std::vector<std::weak_ptr<Texture>> write_attachments,
std::vector<std::weak_ptr<Swapchain>> write_swapchains,
DebugLabelColor pass_debug_label_color);

GraphicsPass(const GraphicsPass &) = delete;
GraphicsPass(GraphicsPass &&other) noexcept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "inexor/vulkan-renderer/render-graph/graphics_pass.hpp"
#include "inexor/vulkan-renderer/render-graph/texture.hpp"
#include "inexor/vulkan-renderer/wrapper/make_info.hpp"
#include "inexor/vulkan-renderer/wrapper/swapchain.hpp"

#include <functional>
#include <memory>
Expand All @@ -17,19 +18,22 @@ class CommandBuffer;
namespace inexor::vulkan_renderer::render_graph {

// Using declaration
using wrapper::Swapchain;
using wrapper::commands::CommandBuffer;

/// A builder class for graphics passes in the rendergraph
class GraphicsPassBuilder {
private:
/// Add members which describe data related to graphics passes here
std::function<void(const CommandBuffer &)> m_on_record_cmd_buffer{};
/// The texture resources this graphics pass writes to
std::vector<RenderingAttachment> m_write_attachments{};
/// The graphics passes which are read by this graphics pass
std::vector<std::weak_ptr<GraphicsPass>> m_graphics_pass_reads{};
/// The texture resources this graphics pass writes to
std::vector<std::weak_ptr<Texture>> m_write_attachments{};
/// The swapchain this graphics pass writes to
std::vector<std::weak_ptr<Swapchain>> m_write_swapchains{};

/// Reset all data of the graphics pass builder
/// Reset the data of the graphics pass builder
void reset();

public:
Expand All @@ -50,9 +54,11 @@ class GraphicsPassBuilder {
/// Specify that this graphics pass A reads from another graphics pass B (if the weak_ptr to B is not expired),
/// meaning B should be rendered before A. It is perfect valid for 'graphics_pass' to be an invalid pointer, in
/// which case the read is not added.
/// @param condition The condition under which the pass is read from
/// @param graphics_pass The graphics pass (can be an invalid pointer)
/// @return A const reference to the this pointer (allowing method calls to be chained)
[[nodiscard]] GraphicsPassBuilder &conditionally_reads_from(std::weak_ptr<GraphicsPass> graphics_pass);
[[nodiscard]] GraphicsPassBuilder &conditionally_reads_from(std::weak_ptr<GraphicsPass> graphics_pass,
bool condition);

/// Specify that this graphics pass A reads from another graphics pass B, meaning B should be rendered before A
/// @param graphics_pass The graphics pass which is read by this graphics pass
Expand All @@ -70,6 +76,13 @@ class GraphicsPassBuilder {
/// @return A const reference to the this pointer (allowing method calls to be chained)
[[nodiscard]] GraphicsPassBuilder &writes_to(std::weak_ptr<Texture> color_attachment,
std::optional<VkClearValue> clear_value = std::nullopt);

// TODO: Swapchain clear values?

/// Specify that this graphics pass writes to a swapchain
/// @param swapchain The swapchain this pass writes to
/// @return A const reference to the this pointer (allowing method calls to be chained)
[[nodiscard]] GraphicsPassBuilder &writes_to(std::weak_ptr<Swapchain> swapchain);
};

} // namespace inexor::vulkan_renderer::render_graph
40 changes: 25 additions & 15 deletions include/inexor/vulkan-renderer/render-graph/render_graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_allocator.hpp"
#include "inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_builder.hpp"
#include "inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_cache.hpp"
#include "inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_update_builder.hpp"
#include "inexor/vulkan-renderer/wrapper/descriptors/write_descriptor_set_builder.hpp"
#include "inexor/vulkan-renderer/wrapper/pipelines/pipeline.hpp"
#include "inexor/vulkan-renderer/wrapper/pipelines/pipeline_builder.hpp"
#include "inexor/vulkan-renderer/wrapper/pipelines/pipeline_layout.hpp"
Expand All @@ -30,13 +30,14 @@ class Swapchain;

namespace inexor::vulkan_renderer::render_graph {

// Using declarations
using wrapper::Device;
using wrapper::Swapchain;
using wrapper::commands::CommandBuffer;
using wrapper::descriptors::DescriptorSetAllocator;
using wrapper::descriptors::DescriptorSetLayoutBuilder;
using wrapper::descriptors::DescriptorSetLayoutCache;
using wrapper::descriptors::DescriptorSetUpdateBuilder;
using wrapper::descriptors::WriteDescriptorSetBuilder;
using wrapper::pipelines::GraphicsPipeline;
using wrapper::pipelines::GraphicsPipelineBuilder;
using wrapper::pipelines::PipelineLayout;
Expand All @@ -52,8 +53,6 @@ class RenderGraph {
private:
/// The device wrapper
Device &m_device;
/// The swapchain wrapper
Swapchain &m_swapchain;

// The rendergraph has its own logger
std::shared_ptr<spdlog::logger> m_log{spdlog::default_logger()->clone("render-graph")};
Expand Down Expand Up @@ -92,6 +91,13 @@ class RenderGraph {
/// The graphics passes used in the rendergraph
std::vector<std::shared_ptr<GraphicsPass>> m_graphics_passes;

/// -----------------------------------------------------------------------------------------------------------------
/// SWAPCHAINS
/// -----------------------------------------------------------------------------------------------------------------

// TODO
std::vector<std::weak_ptr<Swapchain>> m_swapchains;

/// -----------------------------------------------------------------------------------------------------------------
/// GRAPHICS PIPELINES
/// -----------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -199,25 +205,32 @@ class RenderGraph {
/// valid memory when it is used in the on_record function! The descriptor sets are allocated by rendergraph via
/// OnAllocateDescriptorSet functions using the DescriptorSetAllocator of the rendergraph. Descriptor sets are
/// updated in the OnUpdateDescriptorSet functions using the DescriptorSetUpdateBuilder of the rendergraph.
///
/// TODO: Mention batching to vkUpdateDescriptorSets...
/// -----------------------------------------------------------------------------------------------------------------

/// The descriptor set layout builder (a builder pattern for descriptor set layouts)
DescriptorSetLayoutBuilder m_descriptor_set_layout_builder;
/// The descriptor set allocator
DescriptorSetAllocator m_descriptor_set_allocator;
/// The descriptor set update builder (a builder pattern for descriptor set updates)
DescriptorSetUpdateBuilder m_descriptor_set_update_builder;
/// The write descriptor set builder (a builder pattern for write descriptor sets)
WriteDescriptorSetBuilder m_write_descriptor_set_builder;

/// A user-defined function which creates the descriptor set layout
using OnBuildDescriptorSetLayout = std::function<void(DescriptorSetLayoutBuilder &)>;
/// A user-defined function which allocates a descriptor set
using OnAllocateDescriptorSet = std::function<void(DescriptorSetAllocator &)>;
/// A user-defined function which updates a descriptor set
using OnUpdateDescriptorSet = std::function<void(DescriptorSetUpdateBuilder &)>;
/// A user-defined function which builds the descriptor set write for the pass
using OnBuildWriteDescriptorSets = std::function<std::vector<VkWriteDescriptorSet>(WriteDescriptorSetBuilder &)>;

/// Resource descriptors are managed by specifying those three functions to the rendergraph
/// Rendergraph will then call those function in the correct order during rendergraph compilation
using ResourceDescriptor = std::tuple<OnBuildDescriptorSetLayout, OnAllocateDescriptorSet, OnUpdateDescriptorSet>;
using ResourceDescriptor =
std::tuple<OnBuildDescriptorSetLayout, OnAllocateDescriptorSet, OnBuildWriteDescriptorSets>;
/// The resource descriptors of the rendergraph
std::vector<ResourceDescriptor> m_resource_descriptors;
/// All write descriptor sets will be stored in here so we can have one batched call to vkUpdateDescriptorSets
std::vector<VkWriteDescriptorSet> m_write_descriptor_sets;

/// Allocate the descriptor sets
void allocate_descriptor_sets();
Expand All @@ -239,9 +252,6 @@ class RenderGraph {
/// Create the graphics pipelines
void create_graphics_pipelines();

/// Fill the VkRenderingInfo of each graphics pass
// void create_rendering_infos();

/// Create the textures
void create_textures();

Expand Down Expand Up @@ -284,10 +294,10 @@ class RenderGraph {
/// Default constructor
/// @note device and swapchain are not taken as a const reference because rendergraph needs to modify both
/// @param device The device wrapper
/// @param swapchain The swapchain wrapper
RenderGraph(Device &device, Swapchain &swapchain);
RenderGraph(Device &device);

RenderGraph(const RenderGraph &) = delete;
// TODO: Implement me!
RenderGraph(RenderGraph &&) noexcept;
~RenderGraph() = default;

Expand Down Expand Up @@ -323,7 +333,7 @@ class RenderGraph {
/// @param on_update_descriptor_set The descriptor set update function
void add_resource_descriptor(OnBuildDescriptorSetLayout on_build_descriptor_set_layout,
OnAllocateDescriptorSet on_allocate_descriptor_set,
OnUpdateDescriptorSet on_update_descriptor_set);
OnBuildWriteDescriptorSets on_update_descriptor_set);

/// Add a texture which will be initialized externally (not inside of rendergraph)
/// @param texture_name The name of the texture
Expand Down
Loading

0 comments on commit e6a656b

Please sign in to comment.