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 16, 2024
1 parent b544ad5 commit aa96b41
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 97 deletions.
19 changes: 12 additions & 7 deletions include/inexor/vulkan-renderer/render-graph/graphics_pass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class RenderGraph;
// Using declaration
using wrapper::descriptors::DescriptorSetLayout;

// This will make our life easier
/// An attachment is just a texture paired with an optional clear value
using Attachment = std::pair<std::weak_ptr<Texture>, std::optional<VkClearValue>>;

/// A wrapper for graphics passes inside of rendergraph
Expand All @@ -40,8 +40,11 @@ class GraphicsPass {
/// NOTE: We do not have members like m_has_depth_buffer or m_has_stencil_buffer because we can simply check if the
/// std::weak_ptr<Texture> of the Attachment is expire() instead!

/// The color attachments of the graphics pass
std::vector<Attachment> m_color_attachments{};
/// The depth attachment of the graphics pass
Attachment m_depth_attachment{};
/// The stencil attachment of the graphics pass
Attachment m_stencil_attachment{};

/// The descriptor set layout of the pass (this will be created by rendergraph)
Expand All @@ -58,21 +61,23 @@ class GraphicsPass {

/// 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{};

public:
/// 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 m_color_attachment
/// @param m_depth_attachment The depth attachment of the graphics pass
/// @param m_stencil_attachment
/// @param color_attachments The color attachments of the graphics pass
/// @param depth_attachment The depth attachment of the graphics pass
/// @param stencil_attachment The stencil attachment of the graphics pass
GraphicsPass(std::string name,
std::function<void(const CommandBuffer &)> on_record_cmd_buffer,
std::vector<Attachment> m_color_attachments,
Attachment m_depth_attachment,
Attachment m_stencil_attachment);
std::vector<Attachment> color_attachments,
Attachment depth_attachment,
Attachment stencil_attachment);

GraphicsPass(const GraphicsPass &) = delete;
GraphicsPass(GraphicsPass &&other) noexcept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ using wrapper::commands::CommandBuffer;
class GraphicsPassBuilder {
private:
/// Add members which describe data related to graphics passes here
std::function<void(const CommandBuffer &)> m_on_record_cmd_buffer;
std::function<void(const CommandBuffer &)> m_on_record_cmd_buffer{};
/// The color attachments of the graphics pass
std::vector<Attachment> m_color_attachments;
std::vector<Attachment> m_color_attachments{};
/// The depth attachment of the graphics pass
Attachment m_depth_attachment;
Attachment m_depth_attachment{};
/// The stencil attachment of the graphics pass
Attachment m_stencil_attachment;
Attachment m_stencil_attachment{};

/// Reset all data of the graphics pass builder
void reset();
Expand All @@ -42,64 +42,38 @@ class GraphicsPassBuilder {
~GraphicsPassBuilder() = default;

GraphicsPassBuilder &operator=(const GraphicsPassBuilder &) = delete;
GraphicsPassBuilder &operator=(GraphicsPassBuilder &&) noexcept;
GraphicsPassBuilder &operator=(GraphicsPassBuilder &&) = delete;

/// Add a color attachment to the pass
/// @param color_attachment The color attachment
/// @param clear_color The clear color for the color attachment (``std::nullopt`` by default)
/// @param clear_value The clear value for the color attachment (``std::nullopt`` by default)
/// @return A const reference to the this pointer (allowing method calls to be chained)
[[nodiscard]] auto &add_color_attachment(std::weak_ptr<Texture> color_attachment,
std::optional<VkClearColorValue> clear_color = std::nullopt) {
if (color_attachment.expired()) {
throw std::invalid_argument(
"[GraphicsPassBuilder::add_color_attachment] Error: 'color_attachment' is expired!");
}
m_color_attachments.emplace_back(std::move(color_attachment), clear_color);
return *this;
}
[[nodiscard]] GraphicsPassBuilder &add_color_attachment(std::weak_ptr<Texture> color_attachment,
std::optional<VkClearValue> clear_value = std::nullopt);

/// Enable depth testing for the pass
/// @param depth_attachment The depth attachment
/// @param clear_value The clear value for the depth attachment (``std::nullopt`` by default)
/// @return A const reference to the this pointer (allowing method calls to be chained)
[[nodiscard]] GraphicsPassBuilder &add_depth_attachment(std::weak_ptr<Texture> depth_attachment,
std::optional<VkClearValue> clear_value = std::nullopt);

/// Add a stencil attachment to the pass
/// @param stencil_attachment The stencil attachment
/// @param clear_color The clear color value for the stencil attachment (``std::nullopt`` by default)
/// @param clear_value The clear value for the stencil attachment (``std::nullopt`` by default)
/// @return A const reference to the this pointer (allowing method calls to be chained)
[[nodiscard]] auto &add_stencil_attachment(std::weak_ptr<Texture> stencil_attachment,
std::optional<VkClearColorValue> clear_color = std::nullopt) {
if (stencil_attachment.expired()) {
throw std::invalid_argument(
"[GraphicsPassBuilder::add_stencil_attachment] Error: 'stencil_attachment' is expired!");
}
return *this;
}
[[nodiscard]] GraphicsPassBuilder &add_stencil_attachment(std::weak_ptr<Texture> stencil_attachment,
std::optional<VkClearValue> clear_value = std::nullopt);

/// Build the graphics pass
/// @param name The name of the graphics pass
/// @return The graphics pass that was just created
[[nodiscard]] auto build(std::string name) {
auto graphics_pass =
GraphicsPass(std::move(name), std::move(m_on_record_cmd_buffer), std::move(m_color_attachments),
std::move(m_depth_attachment), std::move(m_stencil_attachment));
reset();
return graphics_pass;
}

/// Enable depth testing for the pass
/// @param depth_buffer
/// @return A const reference to the this pointer (allowing method calls to be chained)
[[nodiscard]] auto &enable_depth_test(std::weak_ptr<Texture> depth_attachment) {
if (depth_attachment.expired()) {
throw std::invalid_argument("[GraphicsPassBuilder::enable_depth_test] Error: 'depth_buffer' is expired!");
}
m_depth_attachment = Attachment(std::move(depth_attachment), std::nullopt);
return *this;
}
[[nodiscard]] GraphicsPass build(std::string name);

/// Set the function which will be called when the command buffer for rendering of the pass is being recorded
/// @param on_record_cmd_buffer The command buffer recording function
/// @return A const reference to the this pointer (allowing method calls to be chained)
[[nodiscard]] auto &set_on_record(std::function<void(const CommandBuffer &)> on_record_cmd_buffer) {
on_record_cmd_buffer = std::move(on_record_cmd_buffer);
return *this;
}
[[nodiscard]] GraphicsPassBuilder &set_on_record(std::function<void(const CommandBuffer &)> on_record_cmd_buffer);
};

} // namespace inexor::vulkan_renderer::render_graph
4 changes: 1 addition & 3 deletions include/inexor/vulkan-renderer/render-graph/image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ class Image {
VmaAllocation m_alloc{VK_NULL_HANDLE};
VmaAllocationInfo m_alloc_info{};
VmaAllocationCreateInfo m_alloc_ci{};
VkImageCreateInfo m_img_ci{};
VkImageViewCreateInfo m_img_view_ci{};

/// The combined image sampler for the texture
/// This is only relevant if the texture is used as TextureUsage::NORMAL
Expand All @@ -68,7 +66,7 @@ class Image {
~Image();

Image &operator=(const Image &other) = delete;
Image &operator=(Image &&other) noexcept;
Image &operator=(Image &&other) = delete;
};

} // namespace inexor::vulkan_renderer::render_graph
7 changes: 1 addition & 6 deletions include/inexor/vulkan-renderer/render-graph/render_graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class RenderGraph {
DescriptorSetAllocator m_descriptor_set_allocator;
/// The descriptor set update builder (a builder pattern for descriptor set updates)
DescriptorSetUpdateBuilder m_descriptor_set_update_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
Expand Down Expand Up @@ -273,12 +274,6 @@ class RenderGraph {
/// @note Move semantics is used to std::move on_pass_create
void add_graphics_pass(OnCreateGraphicsPass on_pass_create);

// TODO: One thread_local GraphicsPipelineBuilder? Once graphics pipelines will be created in parallel!

// TODO: The only reason we would need graphics pipelines create functions would be if during creation it would
// reference resources which would need to be set up by rendergraph before! DESCRIPTOR SET LAYOUT!!!!!!
// DESCRIPTOR SET LAYOUT!!!!!!!!

/// Add a new graphics pipeline to the rendergraph
/// @param on_pipeline_create A function to create the graphics pipeline using GraphicsPipelineBuilder
/// @note Move semantics is used to std::move on_pipeline_create
Expand Down
20 changes: 15 additions & 5 deletions include/inexor/vulkan-renderer/render-graph/texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,19 @@ class Texture {
/// The name of the texture
std::string m_name;
/// The usage of this texture
TextureUsage m_texture_usage;
TextureUsage m_usage;
/// The format of the texture
VkFormat m_format{VK_FORMAT_UNDEFINED};
/// The width of the texture
std::uint32_t m_width{0};
/// The height of the texture
std::uint32_t m_height{0};

/// The image of the texture
std::unique_ptr<Image> m_img;

/// The sample count of the MSAA image (if MSAA is enabled)
VkSampleCountFlagBits m_sample_count;
/// This is only used internally inside of rendergraph in case this texture used as a back buffer, depth buffer, or
/// stencil buffer and MSAA is enabled.
std::unique_ptr<Image> m_msaa_img;
Expand All @@ -76,10 +84,10 @@ class Texture {
/// The descriptor image info required for descriptor updates
VkDescriptorImageInfo m_descriptor_img_info{};

///
/// Create the texture (and the MSAA texture if specified)
void create();

///
/// Destroy the texture (and the MSAA texture if specified)
void destroy();

/// Upload the data into the texture
Expand All @@ -92,12 +100,16 @@ class Texture {
/// @param name The internal debug name of the texture
/// @param usage The usage of the texture inside of rendergraph
/// @param format The format of the texture
/// @param width The width of the texture
/// @param height The height of the texture
/// @param on_init The initialization function of the texture
/// @param on_update The update function of the texture
Texture(const Device &device,
std::string name,
TextureUsage usage,
VkFormat format,
std::uint32_t width,
std::uint32_t height,
std::optional<std::function<void()>> on_init = std::nullopt,
std::optional<std::function<void()>> on_update = std::nullopt);

Expand All @@ -108,8 +120,6 @@ class Texture {
Texture &operator=(const Texture &) = delete;
Texture &operator=(Texture &&) noexcept;

// TODO: request_update with other width x height so the texture is recreated??

/// Request rendergraph to update the texture
/// @param src_texture_data A pointer to the source data
/// @param src_texture_data_size The size of the source data
Expand Down
4 changes: 2 additions & 2 deletions src/vulkan-renderer/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,8 +536,8 @@ void Application::setup_render_graph() {

using render_graph::GraphicsPassBuilder;
m_render_graph->add_graphics_pass([&](GraphicsPassBuilder &builder) {
return builder.add_color_attachment(m_back_buffer, VkClearColorValue{1.0f, 0.0f, 0.0f, 1.0f})
.enable_depth_test(m_depth_buffer)
return builder.add_color_attachment(m_back_buffer, VkClearValue{1.0f, 0.0f, 0.0f, 1.0f})
.add_depth_attachment(m_depth_buffer)
.set_on_record(std::move(on_record_cmd_buffer))
.build("Octree");
});
Expand Down
48 changes: 46 additions & 2 deletions src/vulkan-renderer/render-graph/graphics_pass_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,54 @@ GraphicsPassBuilder::GraphicsPassBuilder() {
reset();
}

GraphicsPassBuilder &GraphicsPassBuilder::add_color_attachment(std::weak_ptr<Texture> color_attachment,
std::optional<VkClearValue> clear_value) {
if (color_attachment.expired()) {
throw std::invalid_argument(
"[GraphicsPassBuilder::add_color_attachment] Error: 'color_attachment' is expired!");
}
m_color_attachments.emplace_back(std::move(color_attachment), std::move(clear_value));
return *this;
}

GraphicsPassBuilder &GraphicsPassBuilder::add_depth_attachment(std::weak_ptr<Texture> depth_attachment,
std::optional<VkClearValue> clear_value) {
if (depth_attachment.expired()) {
throw std::invalid_argument("[GraphicsPassBuilder::enable_depth_test] Error: 'depth_buffer' is expired!");
}
m_depth_attachment = Attachment(std::move(depth_attachment), std::move(clear_value));
return *this;
}

GraphicsPassBuilder &GraphicsPassBuilder::add_stencil_attachment(std::weak_ptr<Texture> stencil_attachment,
std::optional<VkClearValue> clear_value) {
if (stencil_attachment.expired()) {
throw std::invalid_argument(
"[GraphicsPassBuilder::add_stencil_attachment] Error: 'stencil_attachment' is expired!");
}
m_stencil_attachment = Attachment(std::move(stencil_attachment), std::move(clear_value));
return *this;
}

GraphicsPass GraphicsPassBuilder::build(std::string name) {
auto graphics_pass =
GraphicsPass(std::move(name), std::move(m_on_record_cmd_buffer), std::move(m_color_attachments),
std::move(m_depth_attachment), std::move(m_stencil_attachment));
reset();
return graphics_pass;
}

void GraphicsPassBuilder::reset() {
// TODO: Fix me!
m_on_record_cmd_buffer = {};
m_color_attachments = {};
m_depth_attachment = {};
m_stencil_attachment = {};
}

// TODO: Move stuff to .cpp file again. Header files should contain declarations, cpp files should contain definitions!
GraphicsPassBuilder &
GraphicsPassBuilder::set_on_record(std::function<void(const CommandBuffer &)> on_record_cmd_buffer) {
on_record_cmd_buffer = std::move(on_record_cmd_buffer);
return *this;
}

} // namespace inexor::vulkan_renderer::render_graph
20 changes: 13 additions & 7 deletions src/vulkan-renderer/render-graph/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ namespace inexor::vulkan_renderer::render_graph {

Image::Image(const Device &device) : m_device(device) {}

Image::Image(Image &&other) noexcept : m_device(other.m_device) {
// TODO: Fix me!
}

Image::~Image() {
destroy();
}

void Image::create(const VkImageCreateInfo img_ci, const VkImageViewCreateInfo img_view_ci) {
m_img_ci = img_ci;
m_img_view_ci = img_view_ci;

void Image::create(const VkImageCreateInfo img_ci, VkImageViewCreateInfo img_view_ci) {
// Create the image
if (const auto result = vmaCreateImage(m_device.allocator(), &img_ci, &m_alloc_ci, &m_img, &m_alloc, &m_alloc_info);
result != VK_SUCCESS) {
Expand All @@ -25,25 +26,30 @@ void Image::create(const VkImageCreateInfo img_ci, const VkImageViewCreateInfo i
m_device.set_debug_name(m_img, m_name);

// Set the image in the VkImageViewCreateInfo
m_img_view_ci.image = m_img;
img_view_ci.image = m_img;

// Create the image view
if (const auto result = vkCreateImageView(m_device.device(), &m_img_view_ci, nullptr, &m_img_view);
if (const auto result = vkCreateImageView(m_device.device(), &img_view_ci, nullptr, &m_img_view);
result != VK_SUCCESS) {
throw VulkanException("Error: vkCreateImageView failed for image view " + m_name + "!", result);
}
m_device.set_debug_name(m_img_view, m_name);

// TODO: Pass VkSamplerCreateInfo as parameter from Image wrapper to the Sampler wrapper
// Create a default sampler
m_sampler = std::make_unique<Sampler>(m_device, "Default");
}

void Image::destroy() {
// Destroy the image view
vkDestroyImageView(m_device.device(), m_img_view, nullptr);
m_img_view = VK_NULL_HANDLE;

// Destroy the image
vmaDestroyImage(m_device.allocator(), m_img, m_alloc);
m_img = VK_NULL_HANDLE;
m_alloc = VK_NULL_HANDLE;

// Destroy the sampler
m_sampler.reset();
m_sampler = nullptr;
}
Expand Down
Loading

0 comments on commit aa96b41

Please sign in to comment.