Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rendergraph] Refactoring, part 1 of 2 #524

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions include/inexor/vulkan-renderer/msaa_target.hpp

This file was deleted.

114 changes: 68 additions & 46 deletions include/inexor/vulkan-renderer/render_graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
#include "inexor/vulkan-renderer/wrapper/device.hpp"
#include "inexor/vulkan-renderer/wrapper/fence.hpp"
#include "inexor/vulkan-renderer/wrapper/framebuffer.hpp"
#include "inexor/vulkan-renderer/wrapper/image.hpp"
#include "inexor/vulkan-renderer/wrapper/pipeline.hpp"
#include "inexor/vulkan-renderer/wrapper/pipeline_builder.hpp"
#include "inexor/vulkan-renderer/wrapper/pipeline_layout.hpp"
#include "inexor/vulkan-renderer/wrapper/renderpass.hpp"
#include "inexor/vulkan-renderer/wrapper/semaphore.hpp"
#include "inexor/vulkan-renderer/wrapper/shader.hpp"
#include "inexor/vulkan-renderer/wrapper/swapchain.hpp"
Expand Down Expand Up @@ -89,7 +94,7 @@ class BufferResource : public RenderResource {

private:
const BufferUsage m_usage;
std::vector<VkVertexInputAttributeDescription> m_vertex_attributes;
std::vector<VkVertexInputAttributeDescription> m_vert_input_attr_descs;

// Data to upload during render graph compilation.
const void *m_data{nullptr};
Expand All @@ -100,28 +105,28 @@ class BufferResource : public RenderResource {
public:
BufferResource(std::string &&name, BufferUsage usage) : RenderResource(name), m_usage(usage) {}

/// @brief Specifies that element `offset` of this vertex buffer is of format `format`.
/// @note Calling this function is only valid on buffers of type BufferUsage::VERTEX_BUFFER.
void add_vertex_attribute(VkFormat format, std::uint32_t offset);

/// @brief Specifies the element size of the buffer upfront if data is not to be uploaded immediately.
/// @param element_size The element size in bytes
void set_element_size(std::size_t element_size) {
m_element_size = element_size;
/// Set the vertex input attribute descriptions
/// @tparam VertexDataType The vertex data type
/// @param vertex_attribute_descriptions the vertex input attribute descriptions
template <typename VertexDataType>
BufferResource *set_vertex_attributes(std::vector<VkVertexInputAttributeDescription> vert_attr_descs) {
m_vert_input_attr_descs = std::move(vert_attr_descs);
m_element_size = sizeof(VertexDataType);
return this;
}

/// @brief Specifies the data that should be uploaded to this buffer at the start of the next frame.
/// @param count The number of elements (not bytes) to upload
/// @param data A pointer to a contiguous block of memory that is at least `count * sizeof(T)` bytes long
// TODO: Use std::span when we switch to C++ 20.
template <typename T>
void upload_data(const T *data, std::size_t count);
BufferResource *upload_data(const T *data, std::size_t count);

/// @brief @copybrief upload_data(const T *, std::size_t)
/// @note This is equivalent to doing `upload_data(data.data(), data.size() * sizeof(T))`
/// @see upload_data(const T *data, std::size_t count)
template <typename T>
void upload_data(const std::vector<T> &data);
BufferResource *upload_data(const std::vector<T> &data);
};

enum class TextureUsage {
Expand All @@ -145,14 +150,8 @@ class TextureResource : public RenderResource {
VkFormat m_format{VK_FORMAT_UNDEFINED};

public:
TextureResource(std::string &&name, TextureUsage usage) : RenderResource(name), m_usage(usage) {}

/// @brief Specifies the format of this texture that is required when the physical texture is made.
/// @details For TextureUsage::BACK_BUFFER textures, using the swapchain image format is preferable in most cases.
/// For TextureUsage::DEPTH_STENCIL_BUFFER textures, a VK_FORMAT_D* must be used.
void set_format(VkFormat format) {
m_format = format;
}
TextureResource(std::string &&name, TextureUsage usage, VkFormat format)
: RenderResource(name), m_usage(usage), m_format(format) {}
};

/// @brief A single render stage in the render graph.
Expand Down Expand Up @@ -182,23 +181,30 @@ class RenderStage : public RenderGraphObject {
RenderStage &operator=(RenderStage &&) = delete;

/// @brief Specifies that this stage writes to `resource`.
void writes_to(const RenderResource *resource);
RenderStage *writes_to(const RenderResource *resource);

/// @brief Specifies that this stage reads from `resource`.
void reads_from(const RenderResource *resource);
RenderStage *reads_from(const RenderResource *resource);

/// @brief Binds a descriptor set layout to this render stage.
/// @note This function will be removed in the near future, as we are aiming for users of the API to not have to
/// deal with descriptors at all.
// TODO: Refactor descriptor management in the render graph
void add_descriptor_layout(VkDescriptorSetLayout layout) {
RenderStage *add_descriptor_layout(VkDescriptorSetLayout layout) {
m_descriptor_layouts.push_back(layout);
return this;
}

/// @brief Add a push constant range to this render stage.
/// @param range The push constant range
void add_push_constant_range(VkPushConstantRange range) {
m_push_constant_ranges.push_back(range);
/// Add a push constant range to this render stage
template <typename PushConstantDataType>
RenderStage *add_push_constant_range(const VkShaderStageFlags stage_flags = VK_SHADER_STAGE_VERTEX_BIT,
const std::uint32_t offset = 0) {
m_push_constant_ranges.push_back({
.stageFlags = stage_flags,
.offset = offset,
.size = sizeof(PushConstantDataType),
});
return this;
}

[[nodiscard]] const std::string &name() const {
Expand All @@ -208,8 +214,9 @@ class RenderStage : public RenderGraphObject {
/// @brief Specifies a function that will be called during command buffer recording for this stage
/// @details This function can be used to specify other vulkan commands during command buffer recording. The most
/// common use for this is for draw commands.
void set_on_record(std::function<void(const PhysicalStage &, const wrapper::CommandBuffer &)> on_record) {
RenderStage *set_on_record(std::function<void(const PhysicalStage &, const wrapper::CommandBuffer &)> on_record) {
m_on_record = std::move(on_record);
return this;
}
};

Expand All @@ -234,30 +241,37 @@ class GraphicsStage : public RenderStage {
GraphicsStage &operator=(GraphicsStage &&) = delete;

/// @brief Specifies that this stage should clear the screen before rendering.
void set_clears_screen(bool clears_screen) {
GraphicsStage *set_clears_screen(bool clears_screen) {
m_clears_screen = clears_screen;
return this;
}

/// @brief Specifies the depth options for this stage.
/// @param depth_test Whether depth testing should be performed
/// @param depth_write Whether depth writing should be performed
void set_depth_options(bool depth_test, bool depth_write) {
GraphicsStage *set_depth_options(bool depth_test, bool depth_write) {
m_depth_test = depth_test;
m_depth_write = depth_write;
return this;
}

/// @brief Set the blend attachment for this stage.
/// @param blend_attachment The blend attachment
void set_blend_attachment(VkPipelineColorBlendAttachmentState blend_attachment) {
GraphicsStage *set_blend_attachment(VkPipelineColorBlendAttachmentState blend_attachment) {
m_blend_attachment = blend_attachment;
return this;
}

/// @brief Specifies that `buffer` should map to `binding` in the shaders of this stage.
void bind_buffer(const BufferResource *buffer, std::uint32_t binding);
GraphicsStage *bind_buffer(const BufferResource *buffer, std::uint32_t binding);

/// @brief Specifies that `shader` should be used during the pipeline of this stage.
/// @note Binding two shaders of same type (e.g. two vertex shaders) is undefined behaviour.
void uses_shader(const wrapper::Shader &shader);
GraphicsStage *uses_shader(const wrapper::Shader &shader);

/// Specifies the shaders which will be used during the pipeline of this stage
/// @param shaders The shaders to use during the pipeline of this stage
GraphicsStage *uses_shaders(std::span<const wrapper::Shader> shaders);
};

// TODO: Add wrapper::Allocation that can be made by doing `device->make<Allocation>(...)`.
Expand Down Expand Up @@ -300,17 +314,20 @@ class PhysicalImage : public PhysicalResource {
friend RenderGraph;

private:
VkImage m_image{VK_NULL_HANDLE};
VkImageView m_image_view{VK_NULL_HANDLE};
std::unique_ptr<wrapper::Image> m_img;

public:
explicit PhysicalImage(const wrapper::Device &device) : PhysicalResource(device) {}
PhysicalImage(const PhysicalImage &) = delete;
PhysicalImage(PhysicalImage &&) = delete;
~PhysicalImage() override;
~PhysicalImage() override = default;

PhysicalImage &operator=(const PhysicalImage &) = delete;
PhysicalImage &operator=(PhysicalImage &&) = delete;

[[nodiscard]] VkImageView image_view() const {
return m_img->image_view();
}
};

class PhysicalBackBuffer : public PhysicalResource {
Expand All @@ -334,8 +351,8 @@ class PhysicalStage : public RenderGraphObject {
friend RenderGraph;

private:
VkPipeline m_pipeline{VK_NULL_HANDLE};
VkPipelineLayout m_pipeline_layout{VK_NULL_HANDLE};
std::unique_ptr<wrapper::PipelineLayout> m_pipeline_layout;
std::unique_ptr<wrapper::GraphicsPipeline> m_pipeline;

protected:
const wrapper::Device &m_device;
Expand All @@ -344,33 +361,37 @@ class PhysicalStage : public RenderGraphObject {
explicit PhysicalStage(const wrapper::Device &device) : m_device(device) {}
PhysicalStage(const PhysicalStage &) = delete;
PhysicalStage(PhysicalStage &&) = delete;
~PhysicalStage() override;
~PhysicalStage() override = default;

PhysicalStage &operator=(const PhysicalStage &) = delete;
PhysicalStage &operator=(PhysicalStage &&) = delete;

/// @brief Retrieve the pipeline layout of this physical stage.
// TODO: This can be removed once descriptors are properly implemented in the render graph.
[[nodiscard]] VkPipelineLayout pipeline_layout() const {
return m_pipeline_layout;
return m_pipeline_layout->pipeline_layout();
}
};

class PhysicalGraphicsStage : public PhysicalStage {
friend RenderGraph;

private:
VkRenderPass m_render_pass{VK_NULL_HANDLE};
std::vector<wrapper::Framebuffer> m_framebuffers;
std::unique_ptr<wrapper::RenderPass> m_render_pass;

public:
explicit PhysicalGraphicsStage(const wrapper::Device &device) : PhysicalStage(device) {}
PhysicalGraphicsStage(const PhysicalGraphicsStage &) = delete;
PhysicalGraphicsStage(PhysicalGraphicsStage &&) = delete;
~PhysicalGraphicsStage() override;
~PhysicalGraphicsStage() override = default;

PhysicalGraphicsStage &operator=(const PhysicalGraphicsStage &) = delete;
PhysicalGraphicsStage &operator=(PhysicalGraphicsStage &&) = delete;

[[nodiscard]] VkRenderPass render_pass() const noexcept {
return m_render_pass->render_pass();
}
};

class RenderGraph {
Expand All @@ -389,8 +410,7 @@ class RenderGraph {

// Functions for building resource related vulkan objects.
void build_buffer(const BufferResource &, PhysicalBuffer &) const;
void build_image(const TextureResource &, PhysicalImage &, VmaAllocationCreateInfo *) const;
void build_image_view(const TextureResource &, PhysicalImage &) const;
void build_image(const TextureResource &, PhysicalImage &) const;

// Functions for building stage related vulkan objects.
void build_pipeline_layout(const RenderStage *, PhysicalStage &) const;
Expand All @@ -408,7 +428,7 @@ class RenderGraph {
/// @brief Adds either a render resource or render stage to the render graph.
/// @return A mutable reference to the just-added resource or stage
template <typename T, typename... Args>
T *add(Args &&...args) {
T *add(Args &&... args) {
auto ptr = std::make_unique<T>(std::forward<Args>(args)...);
if constexpr (std::is_same_v<T, BufferResource>) {
return static_cast<T *>(m_buffer_resources.emplace_back(std::move(ptr)).get());
Expand Down Expand Up @@ -442,15 +462,17 @@ template <typename T>
}

template <typename T>
void BufferResource::upload_data(const T *data, std::size_t count) {
BufferResource *BufferResource::upload_data(const T *data, std::size_t count) {
m_data = data;
m_data_size = count * (m_element_size = sizeof(T));
m_data_upload_needed = true;
return this;
}

template <typename T>
void BufferResource::upload_data(const std::vector<T> &data) {
BufferResource *BufferResource::upload_data(const std::vector<T> &data) {
upload_data(data.data(), data.size());
return this;
}

} // namespace inexor::vulkan_renderer
2 changes: 0 additions & 2 deletions include/inexor/vulkan-renderer/renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "inexor/vulkan-renderer/camera.hpp"
#include "inexor/vulkan-renderer/fps_counter.hpp"
#include "inexor/vulkan-renderer/imgui.hpp"
#include "inexor/vulkan-renderer/msaa_target.hpp"
#include "inexor/vulkan-renderer/octree_gpu_vertex.hpp"
#include "inexor/vulkan-renderer/render_graph.hpp"
#include "inexor/vulkan-renderer/time_step.hpp"
Expand All @@ -17,7 +16,6 @@
#include "inexor/vulkan-renderer/wrapper/gpu_texture.hpp"
#include "inexor/vulkan-renderer/wrapper/image.hpp"
#include "inexor/vulkan-renderer/wrapper/instance.hpp"
#include "inexor/vulkan-renderer/wrapper/mesh_buffer.hpp"
#include "inexor/vulkan-renderer/wrapper/semaphore.hpp"
#include "inexor/vulkan-renderer/wrapper/shader.hpp"
#include "inexor/vulkan-renderer/wrapper/swapchain.hpp"
Expand Down
18 changes: 14 additions & 4 deletions include/inexor/vulkan-renderer/wrapper/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,21 @@ class Device {
void create_graphics_pipeline(const VkGraphicsPipelineCreateInfo &pipeline_ci, VkPipeline *pipeline,
const std::string &name) const;

/// Call vmaCreateImage (VMA wrapper)
/// @param img_ci The image create info structure
/// @param img_alloc_ci The image allocation create info
/// @param img The image to create
/// @param alloc The VMA allocation structure
/// @param alloc_info The VMA allocation info structure
/// @param name The internal debug name of the image
void create_image(const VkImageCreateInfo &img_ci, const VmaAllocationCreateInfo &img_alloc_ci, VkImage *img,
VmaAllocation *alloc, VmaAllocationInfo *alloc_info, const std::string &name) const;

/// Call vkCreateImageView
/// @param image_view_ci The image view create info structure
/// @param image_view The image view to create
/// @param name The internal debug marker name which will be assigned to this image view
void create_image_view(const VkImageViewCreateInfo &image_view_ci, VkImageView *image_view,
/// @param img_view_ci The image view create info structure
/// @param img_view The image view to create
/// @param name The internal debug name which will be assigned to this image view
void create_image_view(const VkImageViewCreateInfo &img_view_ci, VkImageView *img_view,
const std::string &name) const;

/// Call vkCreatePipelineLayout
Expand Down
Loading