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 Jun 24, 2024
1 parent a47e478 commit c0c27ac
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 86 deletions.
10 changes: 5 additions & 5 deletions include/inexor/vulkan-renderer/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ class Application {

float m_time_passed{0.0f};

std::uint32_t m_window_width{0};
std::uint32_t m_window_height{0};
std::string m_window_title;
wrapper::Window::Mode m_window_mode{wrapper::Window::Mode::WINDOWED};
bool m_window_resized{false};
std::uint32_t m_wnd_width{0};
std::uint32_t m_wnd_height{0};
std::string m_wnd_title;
bool m_wnd_resized{false};
wrapper::Window::Mode m_wnd_mode{wrapper::Window::Mode::WINDOWED};

std::vector<std::string> m_gltf_model_files;
std::unique_ptr<input::KeyboardMouseInputData> m_input_data;
Expand Down
8 changes: 6 additions & 2 deletions include/inexor/vulkan-renderer/render-graph/buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ enum class BufferType {
// TODO: Add more buffer types here and implement support for them
};

using wrapper::Device;

// 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
Expand All @@ -34,7 +36,7 @@ class Buffer {
friend class RenderGraph;

/// The device wrapper
const wrapper::Device &m_device;
const Device &m_device;
/// The internal name of this buffer resource inside of the rendergraph
std::string m_name;
/// The buffer type
Expand All @@ -48,6 +50,8 @@ class Buffer {
VkBufferUsageFlags m_buffer_usage;
VmaMemoryUsage m_mem_usage;

// TODO: Maybe buffer updates should be done immediately, and no m_src_data should be stored!

/// It's the responsibility of the programmer to make sure the data m_src_data points to is still valid when
/// update_buffer() is called!
void *m_src_data{nullptr};
Expand All @@ -66,7 +70,7 @@ class Buffer {
/// @param usage The internal usage of the buffer in the rendergraph
/// @note The update frequency of a buffer will only be respected when grouping uniform buffers into descriptor sets
/// @param on_update An optional update function (``std::nullopt`` by default, meaning no updates to this buffer)
Buffer(const wrapper::Device &device, std::string name, BufferType type,
Buffer(const Device &device, std::string name, BufferType type,
std::optional<std::function<void()>> on_update = std::nullopt);

Buffer(const Buffer &) = delete;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <volk.h>

#include <functional>

namespace inexor::vulkan_renderer::render_graph {

// Forward declaration
class RenderGraph;

/// A wrapper class for push constant ranges in the rendergraph
class PushConstantRange {
friend RenderGraph;

private:
VkPushConstantRange m_push_constant;
std::function<void()> m_on_update{[]() {}};
const void *m_push_constant_data{nullptr};

/// Default constructor
/// @param push_constant The push constant
/// @param push_constant_data The data of the push constant
/// @param on_update The update function of the push constant
PushConstantRange(VkPushConstantRange push_constant, const void *push_constant_data,
std::function<void()> on_update);

public:
PushConstantRange(const PushConstantRange &) = delete;
PushConstantRange(PushConstantRange &&other) noexcept;
~PushConstantRange() = default;

PushConstantRange &operator=(const PushConstantRange &) = delete;
PushConstantRange &operator=(PushConstantRange &&) = delete;
};

} // namespace inexor::vulkan_renderer::render_graph

This file was deleted.

6 changes: 4 additions & 2 deletions include/inexor/vulkan-renderer/render-graph/render_graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "inexor/vulkan-renderer/render-graph/buffer.hpp"
#include "inexor/vulkan-renderer/render-graph/graphics_pass.hpp"
#include "inexor/vulkan-renderer/render-graph/graphics_pass_builder.hpp"
#include "inexor/vulkan-renderer/render-graph/push_constant_range_resource.hpp"
#include "inexor/vulkan-renderer/render-graph/push_constant_range.hpp"
#include "inexor/vulkan-renderer/render-graph/texture.hpp"
#include "inexor/vulkan-renderer/wrapper/pipelines/pipeline.hpp"
#include "inexor/vulkan-renderer/wrapper/pipelines/pipeline_builder.hpp"
Expand Down Expand Up @@ -100,7 +100,7 @@ class RenderGraph {
/// The push constant resources of the rendergraph
// TODO: Remember we need to squash all VkPushConstantRange of a pass into one std::vector in order to bind it!
// TODO: Should push constant ranges be per graphics pipeline?
std::vector<std::shared_ptr<PushConstantRangeResource>> m_push_constant_ranges;
std::vector<std::shared_ptr<PushConstantRange>> m_push_constant_ranges;

/// The texture resources of the rendergraph
std::vector<std::shared_ptr<Texture>> m_textures;
Expand Down Expand Up @@ -187,10 +187,12 @@ class RenderGraph {

/// Add a new graphics pass to the rendergraph
/// @param on_pass_create A callable to create the graphics pass using GraphicsPassBuilder
/// @note Move semantics is used to std::move on_pass_create
void add_graphics_pass(GraphicsPassCreateCallable on_pass_create);

/// Add a new graphics pipeline to the rendergraph
/// @param on_pipeline_create A callable to create the graphics pipeline using GraphicsPipelineBuilder
/// @note Move semantics is used to std::move on_pipeline_create
void add_graphics_pipeline(GraphicsPipelineCreateCallable on_pipeline_create);

/// Add a push constant range resource to the rendergraph
Expand Down
2 changes: 1 addition & 1 deletion include/inexor/vulkan-renderer/vk_tools/representation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ template <typename VulkanObjectType>
/// @note We have to specify a specialization for every Vulkan object type!
/// As far as we know, there is no other easy way to do this in C++.
/// @tparam VulkanObjectType The Vulkan object type as template parameter, for examplke VkFence
/// @return The VkObjectType of the template parameter, in our example ``VK_OBJECT_TYPE_FENCE``
/// @return The VkObjectType of the template parameter, for the above mentioned example ``VK_OBJECT_TYPE_FENCE``
template <typename VulkanObjectType>
[[nodiscard]] constexpr VkObjectType get_vulkan_object_type(VulkanObjectType);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ class GraphicsPipelineBuilder {
}

/// Set the vertex input attribute descriptions manually
/// @note As of C++23, there is no mechanism to do so called reflection in C++, meaning we can't get any information
/// about the members of a struct, which would allow us to determine vertex input attributes automatically
/// @param descriptions The vertex input attribute descriptions
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
[[nodiscard]] auto &
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ set(INEXOR_SOURCE_FILES
vulkan-renderer/render-graph/buffer.cpp
vulkan-renderer/render-graph/graphics_pass.cpp
vulkan-renderer/render-graph/graphics_pass_builder.cpp
vulkan-renderer/render-graph/push_constant_range_resource.cpp
vulkan-renderer/render-graph/push_constant_range.cpp
vulkan-renderer/render-graph/render_graph.cpp
vulkan-renderer/render-graph/texture.cpp

Expand Down
54 changes: 25 additions & 29 deletions src/vulkan-renderer/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ Application::Application(int argc, char **argv) {
spdlog::trace("Application version: {}.{}.{}", APP_VERSION[0], APP_VERSION[1], APP_VERSION[2]);
spdlog::trace("Engine version: {}.{}.{}", ENGINE_VERSION[0], ENGINE_VERSION[1], ENGINE_VERSION[2]);

// Load the configuration from the TOML file.
load_toml_configuration_file("configuration/renderer.toml");

// If the user specified command line argument "--no-validation", the Khronos validation instance layer will be
Expand All @@ -62,8 +61,7 @@ Application::Application(int argc, char **argv) {
m_enable_validation_layers = false;
}

m_window =
std::make_unique<wrapper::Window>(m_window_title, m_window_width, m_window_height, true, true, m_window_mode);
m_window = std::make_unique<wrapper::Window>(m_wnd_title, m_wnd_width, m_wnd_height, true, true, m_wnd_mode);

spdlog::trace("Creating Vulkan instance");

Expand Down Expand Up @@ -172,16 +170,23 @@ Application::Application(int argc, char **argv) {
std::make_unique<wrapper::Device>(*m_instance, m_surface->get(), use_distinct_data_transfer_queue,
physical_device, required_extensions, required_features, optional_features);

// TODO: Replace ->get() methods with private fields and friend class declaration!
m_swapchain = std::make_unique<wrapper::Swapchain>(*m_device, m_surface->get(), m_window->width(),
m_window->height(), m_vsync_enabled);

load_octree_geometry(true);
generate_octree_indices();

m_vertex_shader = std::make_unique<wrapper::Shader>(*m_device, VK_SHADER_STAGE_VERTEX_BIT, "Shader Octree",
"shaders/main.vert.spv");
m_fragment_shader = std::make_unique<wrapper::Shader>(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, "Shader Octree",
"shaders/main.frag.spv");
m_vertex_shader =
std::make_unique<wrapper::Shader>(*m_device, VK_SHADER_STAGE_VERTEX_BIT, "Octree", "shaders/main.vert.spv");
m_fragment_shader =
std::make_unique<wrapper::Shader>(*m_device, VK_SHADER_STAGE_FRAGMENT_BIT, "Octree", "shaders/main.frag.spv");

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

m_camera->set_movement_speed(5.0f);
m_camera->set_rotation_speed(0.5f);

m_window->show();
recreate_swapchain();
Expand Down Expand Up @@ -274,20 +279,20 @@ void Application::load_toml_configuration_file(const std::string &file_name) {
using WindowMode = ::inexor::vulkan_renderer::wrapper::Window::Mode;
const auto &wmodestr = toml::find<std::string>(renderer_configuration, "application", "window", "mode");
if (wmodestr == "windowed") {
m_window_mode = WindowMode::WINDOWED;
m_wnd_mode = WindowMode::WINDOWED;
} else if (wmodestr == "windowed_fullscreen") {
m_window_mode = WindowMode::WINDOWED_FULLSCREEN;
m_wnd_mode = WindowMode::WINDOWED_FULLSCREEN;
} else if (wmodestr == "fullscreen") {
m_window_mode = WindowMode::FULLSCREEN;
m_wnd_mode = WindowMode::FULLSCREEN;
} else {
spdlog::warn("Invalid application window mode: {}", wmodestr);
m_window_mode = WindowMode::WINDOWED;
m_wnd_mode = WindowMode::WINDOWED;
}

m_window_width = toml::find<int>(renderer_configuration, "application", "window", "width");
m_window_height = toml::find<int>(renderer_configuration, "application", "window", "height");
m_window_title = toml::find<std::string>(renderer_configuration, "application", "window", "name");
spdlog::trace("Window: {}, {} x {}", m_window_title, m_window_width, m_window_height);
m_wnd_width = toml::find<int>(renderer_configuration, "application", "window", "width");
m_wnd_height = toml::find<int>(renderer_configuration, "application", "window", "height");
m_wnd_title = toml::find<std::string>(renderer_configuration, "application", "window", "name");
spdlog::trace("Window: {}, {} x {}", m_wnd_title, m_wnd_width, m_wnd_height);

m_gltf_model_files = toml::find<std::vector<std::string>>(renderer_configuration, "glTFmodels", "files");

Expand Down Expand Up @@ -377,13 +382,6 @@ void Application::recreate_swapchain() {
m_render_graph = std::make_unique<render_graph::RenderGraph>(*m_device, *m_swapchain);
setup_render_graph();

// TODO: Do we really have to recreate the camera every time we recreate swapchain?
m_camera = std::make_unique<Camera>(glm::vec3(6.0f, 10.0f, 2.0f), 180.0f, 0.0f,
static_cast<float>(m_window->width()), static_cast<float>(m_window->height()));

m_camera->set_movement_speed(5.0f);
m_camera->set_rotation_speed(0.5f);

// TODO: We don't need to recreate the imgui overlay when swapchain is recreated, use a .recreate() method instead?
m_imgui_overlay = std::make_unique<renderers::ImGuiRenderer>(*m_device, *m_render_graph.get(), m_back_buffer,
m_msaa_color, [&]() { update_imgui_overlay(); });
Expand All @@ -392,8 +390,8 @@ void Application::recreate_swapchain() {
}

void Application::render_frame() {
if (m_window_resized) {
m_window_resized = false;
if (m_wnd_resized) {
m_wnd_resized = false;
recreate_swapchain();
return;
}
Expand Down Expand Up @@ -446,8 +444,7 @@ void Application::setup_render_graph() {
if (m_input_data->was_key_pressed_once(GLFW_KEY_N)) {
load_octree_geometry(false);
generate_octree_indices();
// We update the vertex buffer together with the index buffer
// to keep data consistent across frames
// Update the vertex buffer together with the index buffer to keep data consistent across frames
m_vertex_buffer.lock()->request_update(m_octree_vertices);
m_index_buffer.lock()->request_update(m_octree_indices);
}
Expand Down Expand Up @@ -520,8 +517,7 @@ void Application::setup_render_graph() {
})
.set_depth_test(true)
.set_on_record([&](const CommandBuffer &cmd_buf) {
cmd_buf
.bind_pipeline(*m_octree_pipeline)
cmd_buf.bind_pipeline(*m_octree_pipeline)
.bind_vertex_buffer(m_vertex_buffer)
.bind_index_buffer(m_index_buffer)
.draw_indexed(static_cast<std::uint32_t>(m_octree_indices.size()));
Expand Down Expand Up @@ -556,7 +552,7 @@ void Application::setup_window_and_input_callbacks() {
auto lambda_frame_buffer_resize_callback = [](GLFWwindow *window, int width, int height) {
auto *app = static_cast<Application *>(glfwGetWindowUserPointer(window));
spdlog::trace("Frame buffer resize callback called. window width: {}, height: {}", width, height);
app->m_window_resized = true;
app->m_wnd_resized = true;
};

m_window->set_resize_callback(lambda_frame_buffer_resize_callback);
Expand Down
10 changes: 7 additions & 3 deletions src/vulkan-renderer/render-graph/buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace inexor::vulkan_renderer::render_graph {

Buffer::Buffer(const wrapper::Device &device, std::string name, const BufferType type,
Buffer::Buffer(const Device &device, std::string name, const BufferType type,
std::optional<std::function<void()>> on_update)
: m_device(device), m_name(std::move(name)), m_buffer_type(type), m_on_update(std::move(on_update)) {
// TODO: Set VMA memory usage and Vulkan buffer usage flags
Expand Down Expand Up @@ -67,13 +67,17 @@ void Buffer::update_buffer() {
}
case BufferType::VERTEX_BUFFER:
case BufferType::INDEX_BUFFER: {
// Vertex and index buffers are updated through a staging buffer
// Vertex and index buffers are updated through a buffer copy command using a staging buffer
// This itself requires another instance of the Buffer wrapper class
// Note that staging buffers are managed inside of device wrapper, not rendergraph

// TODO: Batching of pipeline memory barriers for staging buffer through rendergraph?
break;
}
case BufferType::STAGING_BUFFER: {
// A staging buffer does not require updates, as it itself is used to update other buffers
// Note that we currently do not re-use staging buffers
// Note that staging buffers are managed inside of device wrapper, not rendergraph, and we currently do not
// re-use staging buffers
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#include "inexor/vulkan-renderer/render-graph/push_constant_range_resource.hpp"
#include "inexor/vulkan-renderer/render-graph/push_constant_range.hpp"

namespace inexor::vulkan_renderer::render_graph {

PushConstantRangeResource::PushConstantRangeResource(const VkPushConstantRange push_constant,
const void *push_constant_data, std::function<void()> on_update)
PushConstantRange::PushConstantRange(const VkPushConstantRange push_constant, const void *push_constant_data,
std::function<void()> on_update)
: m_push_constant(push_constant), m_push_constant_data(push_constant_data), m_on_update(std::move(on_update)) {}

PushConstantRangeResource::PushConstantRangeResource(PushConstantRangeResource &&other) noexcept {
PushConstantRange::PushConstantRange(PushConstantRange &&other) noexcept {
m_push_constant = std::move(other.m_push_constant);
m_on_update = std::move(other.m_on_update);
m_push_constant_data = std::exchange(other.m_push_constant_data, nullptr);
Expand Down
2 changes: 1 addition & 1 deletion src/vulkan-renderer/render-graph/render_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "inexor/vulkan-renderer/exception.hpp"
#include "inexor/vulkan-renderer/render-graph/graphics_pass.hpp"
#include "inexor/vulkan-renderer/render-graph/graphics_pass_builder.hpp"
#include "inexor/vulkan-renderer/render-graph/push_constant_range_resource.hpp"
#include "inexor/vulkan-renderer/render-graph/push_constant_range.hpp"
#include "inexor/vulkan-renderer/wrapper/device.hpp"
#include "inexor/vulkan-renderer/wrapper/pipelines/pipeline_builder.hpp"
#include "inexor/vulkan-renderer/wrapper/swapchain.hpp"
Expand Down
1 change: 0 additions & 1 deletion src/vulkan-renderer/renderers/imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ ImGuiRenderer::ImGuiRenderer(const wrapper::Device &device, render_graph::Render
.writes_to_texture(depth_buffer)
.add_push_constant_range(VK_SHADER_STAGE_VERTEX_BIT, &m_push_const_block,
[&]() {
// Update lambda for ImGui push constant range
const ImGuiIO &io = ImGui::GetIO();
m_push_const_block.scale =
glm::vec2(2.0f / io.DisplaySize.x, 2.0f / io.DisplaySize.y);
Expand Down

0 comments on commit c0c27ac

Please sign in to comment.