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 23, 2024
1 parent 691d277 commit 9392044
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 69 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 @@ -55,7 +55,7 @@ class Application {
VkDescriptorSet m_descriptor_set{VK_NULL_HANDLE};

std::shared_ptr<wrapper::pipelines::GraphicsPipeline> m_octree_pipeline;
std::shared_ptr<render_graph::GraphicsPass> m_octree_pass;
std::weak_ptr<render_graph::GraphicsPass> m_octree_pass;

struct ModelViewPerspectiveMatrices {
glm::mat4 model{1.0f};
Expand Down
15 changes: 8 additions & 7 deletions include/inexor/vulkan-renderer/render-graph/render_graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@ class RenderGraph {

/// The graphics pass builder of the rendergraph
GraphicsPassBuilder m_graphics_pass_builder{};
/// In these callback functions, the graphics passes will be created
using OnCreateGraphicsPass = std::function<std::shared_ptr<GraphicsPass>(GraphicsPassBuilder &)>;
/// The graphics pass create functions
std::vector<OnCreateGraphicsPass> m_graphics_pass_create_functions;
/// The graphics passes used in the rendergraph
std::vector<std::shared_ptr<GraphicsPass>> m_graphics_passes;

Expand Down Expand Up @@ -323,9 +319,9 @@ class RenderGraph {
RenderGraph &operator=(RenderGraph &&) = delete;

/// 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(OnCreateGraphicsPass on_pass_create);
/// @aram graphics_pass The graphics pass that was created
/// @return A std::weak_ptr to the graphics pass that was added
[[nodiscard]] std::weak_ptr<GraphicsPass> add_graphics_pass(std::shared_ptr<GraphicsPass> graphics_pass);

/// Add a new graphics pipeline to the rendergraph
/// @param on_pipeline_create A function to create the graphics pipeline using GraphicsPipelineBuilder
Expand Down Expand Up @@ -376,6 +372,11 @@ class RenderGraph {
/// Compile the rendergraph
void compile();

/// Return the rendergraph's graphics pass builder instance
GraphicsPassBuilder &get_graphics_pass_builder() {
return m_graphics_pass_builder;
}

/// Render a frame
void render();

Expand Down
2 changes: 2 additions & 0 deletions include/inexor/vulkan-renderer/renderers/imgui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class ImGuiRenderer {
std::weak_ptr<Texture> m_imgui_texture;
std::shared_ptr<GraphicsPipeline> m_imgui_pipeline;

std::weak_ptr<GraphicsPass> m_imgui_pass;

// This is the color attachment we will write to
std::weak_ptr<Swapchain> m_swapchain;
// This is the previous pass we read from
Expand Down
50 changes: 24 additions & 26 deletions src/vulkan-renderer/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,32 +518,30 @@ void Application::setup_render_graph() {
return m_octree_pipeline;
});

m_render_graph->add_graphics_pass([&](render_graph::GraphicsPassBuilder &builder) {
// NOTE: Octree pass is the first pass, so it does not declare any reads_from()
m_octree_pass = builder
// TODO: Helper function for clear values
.writes_to(m_swapchain,
VkClearValue{
.color = {1.0f, 1.0f, 1.0f, 1.0f},
})
// TODO: Helper function for clear values
.writes_to(m_depth_attachment,
VkClearValue{
.depthStencil =
VkClearDepthStencilValue{
.depth = 1.0f,
},
})
.set_on_record([&](const wrapper::commands::CommandBuffer &cmd_buf) {
cmd_buf.bind_pipeline(m_octree_pipeline)
.bind_descriptor_set(m_descriptor_set, 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()));
})
.build("Octree", render_graph::DebugLabelColor::RED);
return m_octree_pass;
});
m_octree_pass = m_render_graph->add_graphics_pass(
m_render_graph
->get_graphics_pass_builder()
// TODO: Helper function for clear values
.writes_to(m_swapchain,
VkClearValue{
.color = {1.0f, 1.0f, 1.0f, 1.0f},
})
// TODO: Helper function for clear values
.writes_to(m_depth_attachment,
VkClearValue{
.depthStencil =
VkClearDepthStencilValue{
.depth = 1.0f,
},
})
.set_on_record([&](const wrapper::commands::CommandBuffer &cmd_buf) {
cmd_buf.bind_pipeline(m_octree_pipeline)
.bind_descriptor_set(m_descriptor_set, 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()));
})
.build("Octree", render_graph::DebugLabelColor::RED));

// TODO: We don't need to recreate the imgui overlay when swapchain is recreated, use a .recreate() method instead?
// TODO: Decouple ImGuiRenderer form ImGuiLoader
Expand Down
47 changes: 19 additions & 28 deletions src/vulkan-renderer/render-graph/render_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ RenderGraph::RenderGraph(Device &device)
: m_device(device), m_graphics_pipeline_builder(device), m_descriptor_set_layout_builder(device),
m_descriptor_set_allocator(m_device), m_write_descriptor_set_builder(m_device) {}

void RenderGraph::add_graphics_pass(OnCreateGraphicsPass on_pass_create) {
m_graphics_pass_create_functions.emplace_back(std::move(on_pass_create));
std::weak_ptr<GraphicsPass> RenderGraph::add_graphics_pass(std::shared_ptr<GraphicsPass> graphics_pass) {
m_graphics_passes.emplace_back(std::move(graphics_pass));
return m_graphics_passes.back();
}

void RenderGraph::add_graphics_pipeline(OnCreateGraphicsPipeline on_pipeline_create) {
Expand Down Expand Up @@ -123,11 +124,7 @@ void RenderGraph::create_descriptor_set_layouts() {
}

void RenderGraph::create_graphics_passes() {
m_graphics_passes.clear();
m_graphics_passes.reserve(m_graphics_pass_create_functions.size());
for (const auto &create_func : m_graphics_pass_create_functions) {
m_graphics_passes.emplace_back(create_func(m_graphics_pass_builder));
}
// TODO: Implement me
}

void RenderGraph::create_graphics_pipelines() {
Expand All @@ -138,48 +135,45 @@ void RenderGraph::create_graphics_pipelines() {
}

void RenderGraph::determine_pass_order() {
std::stack<std::shared_ptr<GraphicsPass>> stack;
// Pop elements from the stack to get the correct order
std::vector<std::shared_ptr<GraphicsPass>> ordered_passes;
std::unordered_map<std::shared_ptr<GraphicsPass>, bool> visited;

// Lambda function for DFS
std::function<void(const std::shared_ptr<GraphicsPass> &)> dfs = [&](const std::shared_ptr<GraphicsPass> &pass) {
// Mark the node as visited
// If the pass has already been visited, return
if (visited[pass]) {
return;
}

// Mark the pass as visited
visited[pass] = true;
// Visit all the nodes connected by "reads"

// Visit all passes that this pass reads from
for (const auto &weak_read_pass : pass->m_graphics_pass_reads) {
if (auto read_pass = weak_read_pass.lock()) {
if (!visited[read_pass]) {
dfs(read_pass);
}
dfs(read_pass);
}
}
// Push the node onto the stack
stack.push(pass);

// All dependencies of this pass have been visited, now push this pass onto the stack
ordered_passes.push_back(pass);
};
// Initialize visited map

// Initialize visited map for all passes
for (const auto &pass : m_graphics_passes) {
visited[pass] = false;
}
// Perform DFS from each unvisited node
// Perform DFS from each pass
for (const auto &pass : m_graphics_passes) {
if (!visited[pass]) {
dfs(pass);
}
}
// Pop elements from the stack to get the order
std::vector<std::shared_ptr<GraphicsPass>> ordered_passes;
while (!stack.empty()) {
ordered_passes.push_back(stack.top());
stack.pop();
}

// Update the member variable with the sorted passes
m_graphics_passes = std::move(ordered_passes);

// Let each graphics pass know aout its next pass, except the last one which has none
// Let each graphics pass know about its next pass, except the last one which has none
for (std::size_t pass_index = 0; pass_index < m_graphics_passes.size() - 1; pass_index++) {
m_graphics_passes[pass_index]->m_next_pass = m_graphics_passes[pass_index + 1];
}
Expand Down Expand Up @@ -445,9 +439,6 @@ void RenderGraph::update_write_descriptor_sets() {
}

void RenderGraph::validate_render_graph() {
if (m_graphics_pass_create_functions.empty()) {
throw std::runtime_error("[RenderGraph::validate_render_graph] Error: No graphics passes in rendergraph!");
}
if (m_pipeline_create_functions.empty()) {
throw std::runtime_error("[RenderGraph::validate_render_graph] Error: No graphics pipelines in rendergraph!");
}
Expand Down
11 changes: 4 additions & 7 deletions src/vulkan-renderer/renderers/imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,9 @@ ImGuiRenderer::ImGuiRenderer(const Device &device,
return m_imgui_pipeline;
});

graph->add_graphics_pass([&](render_graph::GraphicsPassBuilder &builder) {
// NOTE: ImGui does not write to depth buffer and it reads from octree pass (previous pass)
// NOTE: We directly return the ImGui graphics pass and do not store it in here because it's the last pass (for
// now) and there is no reads_from function which would need it.
return builder.writes_to(m_swapchain)
m_imgui_pass = graph->add_graphics_pass(
graph->get_graphics_pass_builder()
.writes_to(m_swapchain)
.conditionally_reads_from(m_previous_pass, !m_previous_pass.expired())
.set_on_record([&](const wrapper::commands::CommandBuffer &cmd_buf) {
ImDrawData *draw_data = ImGui::GetDrawData();
Expand Down Expand Up @@ -186,8 +184,7 @@ ImGuiRenderer::ImGuiRenderer(const Device &device,
vertex_offset += cmd_list->VtxBuffer.Size;
}
})
.build("ImGui", render_graph::DebugLabelColor::BLUE);
});
.build("ImGui", render_graph::DebugLabelColor::BLUE));
}

ImGuiRenderer::ImGuiRenderer(ImGuiRenderer &&other) noexcept {
Expand Down

0 comments on commit 9392044

Please sign in to comment.