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 20, 2024
1 parent e9370d3 commit 3c9153a
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 34 deletions.
7 changes: 3 additions & 4 deletions include/inexor/vulkan-renderer/renderers/imgui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class ImGuiRenderer {
std::weak_ptr<Buffer> m_index_buffer;
std::weak_ptr<Buffer> m_vertex_buffer;
std::weak_ptr<Texture> m_imgui_texture;
std::shared_ptr<wrapper::pipelines::GraphicsPipeline> m_imgui_pipeline;
std::shared_ptr<GraphicsPipeline> m_imgui_pipeline;

// This is the color attachment we will write to
std::weak_ptr<Swapchain> m_swapchain;
Expand Down Expand Up @@ -87,16 +87,15 @@ class ImGuiRenderer {
public:
/// Default constructor
/// @param device The device wrapper
/// @param swapchain The swapchain to render to
/// @param render_graph The rendergraph
/// @param previous_pass The previous pass
/// @param color_attachment The color attachment
/// @param swapchain The swapchain to render to
/// @param on_update_user_data The user-specified ImGui update function
ImGuiRenderer(const Device &device,
std::weak_ptr<Swapchain> swapchain,
std::weak_ptr<RenderGraph> render_graph,
std::weak_ptr<GraphicsPass> previous_pass,
//std::weak_ptr<Texture> color_attachment,
std::weak_ptr<Swapchain> swapchain,
std::function<void()> on_update_user_data);

ImGuiRenderer(const ImGuiRenderer &) = delete;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

#include "inexor/vulkan-renderer/wrapper/commands/command_buffer.hpp"

#include <cassert>

namespace inexor::vulkan_renderer::wrapper {
// Forward declaration
class Device;
Expand All @@ -22,16 +20,17 @@ class CommandPool {
std::string m_name;
const Device &m_device;
VkCommandPool m_cmd_pool{VK_NULL_HANDLE};
VkQueueFlagBits m_queue_type;

/// The command buffers which can be requested by the current thread
mutable std::vector<std::unique_ptr<CommandBuffer>> m_cmd_bufs;

public:
/// Default constructor
/// @param device The device wrapper instance
/// @param queue_family_index The queue family index of the commands pool
/// @param queue_type The queue type
/// @param name The internal debug marker name which will be assigned to this command pool
CommandPool(const Device &device, std::uint32_t queue_family_index, std::string name);
CommandPool(const Device &device, VkQueueFlagBits queue_type, std::string name);

CommandPool(const CommandPool &) = delete;
CommandPool(CommandPool &&) noexcept;
Expand All @@ -43,7 +42,7 @@ class CommandPool {
/// Request a command buffer
/// @param name The internal debug name which will be assigned to this command buffer (must not be empty)
/// @return A command buffer handle instance which allows access to the requested command buffer
[[nodiscard]] const CommandBuffer &request_command_buffer(const std::string &name) const;
[[nodiscard]] CommandBuffer &request_command_buffer(const std::string &name) const;
};

} // namespace inexor::vulkan_renderer::wrapper::commands
14 changes: 10 additions & 4 deletions include/inexor/vulkan-renderer/wrapper/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ class Device {
/// @param name the internal debug name of the Vulkan object
void set_debug_utils_object_name(VkObjectType obj_type, std::uint64_t obj_handle, const std::string &name) const;

// TODO: Maybe we can merge those three functions into one? Use a thread_local std::array<CommandPool, 3>?

/// Get the thread_local compute pool for transfer commands
/// @note This method will create a command pool for the thread if it doesn't already exist
const CommandPool &thread_local_compute_command_pool() const;
Expand Down Expand Up @@ -245,6 +247,10 @@ class Device {
return m_transfer_queue;
}

[[nodiscard]] std::uint32_t compute_queue_family_index() const {
return m_compute_queue_family_index;
}

[[nodiscard]] std::uint32_t graphics_queue_family_index() const {
return m_graphics_queue_family_index;
}
Expand All @@ -253,14 +259,14 @@ class Device {
return m_present_queue_family_index;
}

[[nodiscard]] VkPhysicalDeviceProperties physical_device_properties() const noexcept {
return m_properties;
}

[[nodiscard]] std::uint32_t transfer_queue_family_index() const {
return m_transfer_queue_family_index;
}

[[nodiscard]] VkPhysicalDeviceProperties physical_device_properties() const noexcept {
return m_properties;
}

/// Set the internal debug name of a Vulkan object
/// @tparam VulkanObjectType
/// @param vk_object
Expand Down
5 changes: 2 additions & 3 deletions src/vulkan-renderer/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,8 @@ void Application::setup_render_graph() {

// TODO: We don't need to recreate the imgui overlay when swapchain is recreated, use a .recreate() method instead?
// TODO: Decouple ImGuiRenderer form ImGuiLoader
// m_imgui_overlay = std::make_unique<renderers::ImGuiRenderer>(*m_device, m_swapchain, m_render_graph,
// m_octree_pass,
// [&]() { update_imgui_overlay(); });
m_imgui_overlay = std::make_unique<renderers::ImGuiRenderer>(*m_device, m_render_graph, m_octree_pass, m_swapchain,
[&]() { update_imgui_overlay(); });

m_render_graph->compile();
}
Expand Down
5 changes: 3 additions & 2 deletions src/vulkan-renderer/render-graph/render_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,16 +283,17 @@ void RenderGraph::record_command_buffer_for_pass(const CommandBuffer &cmd_buf, G
// NOTE: Pipeline barriers must not be placed inside of dynamic rendering instances, which means we must change the
// image layout of all swapchains we write to before we call begin_rendering and then again after we call
// end_rendering.
// ----------------------------------------------------------------------------------------------------------------

// Start dynamic rendering with the compiled rendering info
cmd_buf.begin_rendering(pass.m_rendering_info);

// Call the command buffer recording function of this graphics pass. In this function, the actual rendering takes
// place: the programmer binds pipelines, descriptor sets, buffers, and calls Vulkan commands. Note that rendergraph
// does not bind any pipelines, descriptor sets, or buffers automatically!
std::invoke(pass.m_on_record_cmd_buffer, cmd_buf);

// End dynamic rendering
cmd_buf.end_rendering();
// ----------------------------------------------------------------------------------------------------------------

// TODO: Only change image layout of swapchain if previous pass did not already do this!

Expand Down
8 changes: 3 additions & 5 deletions src/vulkan-renderer/renderers/imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
namespace inexor::vulkan_renderer::renderers {

ImGuiRenderer::ImGuiRenderer(const Device &device,
std::weak_ptr<Swapchain> swapchain,
std::weak_ptr<RenderGraph> render_graph,
std::weak_ptr<GraphicsPass> previous_pass,
// std::weak_ptr<Texture> color_attachment,
std::weak_ptr<Swapchain> swapchain,
std::function<void()> on_update_user_data)
: m_on_update_user_data(std::move(on_update_user_data)), m_previous_pass(std::move(previous_pass)),
m_swapchain(std::move(swapchain)) /*, m_color_attachment(std::move(color_attachment))*/ {
Expand Down Expand Up @@ -139,9 +138,8 @@ ImGuiRenderer::ImGuiRenderer(const Device &device,
// 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)
//.conditionally_reads_from(m_previous_pass, !m_previous_pass.expired())
return 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();
if (draw_data == nullptr || draw_data->TotalIdxCount == 0 || draw_data->TotalVtxCount == 0) {
Expand Down
34 changes: 26 additions & 8 deletions src/vulkan-renderer/wrapper/commands/command_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,33 @@

namespace inexor::vulkan_renderer::wrapper::commands {

CommandPool::CommandPool(const Device &device, std::uint32_t queue_family_index, std::string name)
: m_device(device), m_name(std::move(name)) {
CommandPool::CommandPool(const Device &device, const VkQueueFlagBits queue_type, std::string name)
: m_device(device), m_queue_type(queue_type), m_name(std::move(name)) {

auto get_queue_family_index = [&]() {
switch (queue_type) {
case VK_QUEUE_TRANSFER_BIT: {
return m_device.transfer_queue_family_index();
}
case VK_QUEUE_COMPUTE_BIT: {
return m_device.compute_queue_family_index();
}
default: {
// VK_QUEUE_GRAPHICS_BIT and rest
return m_device.graphics_queue_family_index();
}
}
};

const auto cmd_pool_ci = make_info<VkCommandPoolCreateInfo>({
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
.queueFamilyIndex = queue_family_index,
.queueFamilyIndex = get_queue_family_index(),
});

// Get the thread id as string for naming the command pool and the command buffers
const std::size_t thread_id = std::hash<std::thread::id>{}(std::this_thread::get_id());
spdlog::trace("Creating command pool for thread {}", thread_id);
std::ostringstream thread_id;
thread_id << std::this_thread::get_id();
spdlog::trace("Creating {} command pool for thread ID {}", vk_tools::as_string(queue_type), thread_id.str());

if (const auto result = vkCreateCommandPool(m_device.device(), &cmd_pool_ci, nullptr, &m_cmd_pool);
result != VK_SUCCESS) {
Expand All @@ -32,13 +49,14 @@ CommandPool::CommandPool(CommandPool &&other) noexcept : m_device(other.m_device
m_cmd_pool = std::exchange(other.m_cmd_pool, nullptr);
m_name = std::move(other.m_name);
m_cmd_bufs = std::move(other.m_cmd_bufs);
m_queue_type = other.m_queue_type;
}

CommandPool::~CommandPool() {
vkDestroyCommandPool(m_device.device(), m_cmd_pool, nullptr);
}

const commands::CommandBuffer &CommandPool::request_command_buffer(const std::string &name) const {
CommandBuffer &CommandPool::request_command_buffer(const std::string &name) const {
// Try to find a command buffer which is currently not used
for (const auto &cmd_buf : m_cmd_bufs) {
if (cmd_buf->m_cmd_buf_execution_completed->status() == VK_SUCCESS) {
Expand All @@ -50,11 +68,11 @@ const commands::CommandBuffer &CommandPool::request_command_buffer(const std::st
}
}

spdlog::trace("Creating new command buffer #{}", 1 + m_cmd_bufs.size());
spdlog::trace("Creating {} new command buffer #{}", vk_tools::as_string(m_queue_type), 1 + m_cmd_bufs.size());

// No free command buffer was found so we need to create a new one
// Note that there is currently no method for shrinking m_cmd_bufs, but this should not be a problem
m_cmd_bufs.emplace_back(std::make_unique<commands::CommandBuffer>(m_device, m_cmd_pool, name));
m_cmd_bufs.emplace_back(std::make_unique<CommandBuffer>(m_device, m_cmd_pool, name));

auto &new_cmd_buf = *m_cmd_bufs.back();
new_cmd_buf.begin_command_buffer();
Expand Down
6 changes: 3 additions & 3 deletions src/vulkan-renderer/wrapper/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ const CommandPool &Device::thread_local_compute_command_pool() const {
// NOTE: thread_graphics_pool is implicitly static!
thread_local CommandPool *compute_pool = nullptr; // NOLINT
if (compute_pool == nullptr) {
auto cmd_pool = std::make_unique<CommandPool>(*this, m_compute_queue_family_index, "Compute Command Pool");
auto cmd_pool = std::make_unique<CommandPool>(*this, VK_QUEUE_COMPUTE_BIT, "Compute Command Pool");
std::scoped_lock locker(m_mutex);
compute_pool = m_cmd_pools.emplace_back(std::move(cmd_pool)).get();
}
Expand All @@ -568,7 +568,7 @@ const CommandPool &Device::thread_local_graphics_command_pool() const {
// NOTE: thread_graphics_pool is implicitly static!
thread_local CommandPool *graphics_pool = nullptr; // NOLINT
if (graphics_pool == nullptr) {
auto cmd_pool = std::make_unique<CommandPool>(*this, m_graphics_queue_family_index, "Graphics Command Pool");
auto cmd_pool = std::make_unique<CommandPool>(*this, VK_QUEUE_GRAPHICS_BIT, "Graphics Command Pool");
std::scoped_lock locker(m_mutex);
graphics_pool = m_cmd_pools.emplace_back(std::move(cmd_pool)).get();
}
Expand All @@ -579,7 +579,7 @@ const CommandPool &Device::thread_local_transfer_command_pool() const {
// NOTE: thread_graphics_pool is implicitly static!
thread_local CommandPool *graphics_pool = nullptr; // NOLINT
if (graphics_pool == nullptr) {
auto cmd_pool = std::make_unique<CommandPool>(*this, m_transfer_queue_family_index, "Transfer Command Pool");
auto cmd_pool = std::make_unique<CommandPool>(*this, VK_QUEUE_TRANSFER_BIT, "Transfer Command Pool");
std::scoped_lock locker(m_mutex);
graphics_pool = m_cmd_pools.emplace_back(std::move(cmd_pool)).get();
}
Expand Down

0 comments on commit 3c9153a

Please sign in to comment.