diff --git a/include/inexor/vulkan-renderer/imgui.hpp b/include/inexor/vulkan-renderer/imgui.hpp index 4da63aa53..dfb6cc709 100644 --- a/include/inexor/vulkan-renderer/imgui.hpp +++ b/include/inexor/vulkan-renderer/imgui.hpp @@ -9,12 +9,17 @@ #include #include -// Forward declarations namespace inexor::vulkan_renderer::wrapper { +// Forward declarations class Device; class Shader; } // namespace inexor::vulkan_renderer::wrapper +namespace inexor::vulkan_renderer::render_graph { +// Forward declaration +class RenderGraph; +} // namespace inexor::vulkan_renderer::render_graph + namespace inexor::vulkan_renderer { /// A wrapper for an ImGui implementation diff --git a/include/inexor/vulkan-renderer/render-graph/buffer.hpp b/include/inexor/vulkan-renderer/render-graph/buffer.hpp index 153278e39..eb1eabf75 100644 --- a/include/inexor/vulkan-renderer/render-graph/buffer.hpp +++ b/include/inexor/vulkan-renderer/render-graph/buffer.hpp @@ -30,8 +30,6 @@ enum class BufferType { class Buffer { private: friend class RenderGraph; - friend class GraphicsPass; - friend class wrapper::CommandBuffer; /// The device wrapper const wrapper::Device &m_device; @@ -40,7 +38,7 @@ class Buffer { /// The buffer type BufferType m_type; /// An optional update function to update the data of the buffer resource - std::function m_on_update{[]() {}}; + std::optional> m_on_update{std::nullopt}; /// If this is true, an update can only be carried out with the use of staging buffers bool m_requires_staging_buffer_update{false}; @@ -63,15 +61,15 @@ class Buffer { /// @param new_buffer_size The new size of the buffer void recreate_buffer(VkDeviceSize new_buffer_size); +public: /// Default constructor /// @param device The device wrapper /// @param name The internal debug name of the buffer (must not be empty) /// @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, std::function on_update); - -public: + Buffer(const wrapper::Device &device, std::string name, BufferType type, + std::optional> on_update); Buffer(const Buffer &) = delete; Buffer(Buffer &&other) noexcept; ~Buffer(); @@ -117,6 +115,18 @@ class Buffer { void request_update(std::vector &data) { return request_update(data.data(), sizeof(data) * data.size()); } + + [[nodiscard]] auto &buffer() const { + return m_buffer; + } + + [[nodiscard]] auto &name() const { + return m_name; + } + + [[nodiscard]] auto type() const { + return m_type; + } }; } // namespace inexor::vulkan_renderer::render_graph diff --git a/include/inexor/vulkan-renderer/render-graph/render_graph.hpp b/include/inexor/vulkan-renderer/render-graph/render_graph.hpp index 87b9274be..cc708b635 100644 --- a/include/inexor/vulkan-renderer/render-graph/render_graph.hpp +++ b/include/inexor/vulkan-renderer/render-graph/render_graph.hpp @@ -31,6 +31,9 @@ namespace inexor::vulkan_renderer::render_graph { enum class BufferType; class PushConstantRangeResource; +// Namespaces +using namespace wrapper::pipelines; + /// A rendergraph is a generic solution for rendering architecture /// This is based on Yuriy O'Donnell's talk "FrameGraph: Extensible Rendering Architecture in Frostbite" from GDC 2017 /// Also check out Hans-Kristian Arntzen's blog post "Render graphs and Vulkan - a deep dive" (2017) and @@ -69,17 +72,17 @@ class RenderGraph { wrapper::pipelines::GraphicsPipelineBuilder m_graphics_pipeline_builder; /// The callables which create the graphics pipelines used in the rendergraph - using GraphicsPipelineCreateCallable = std::function( + using GraphicsPipelineCreateCallable = std::function( wrapper::pipelines::GraphicsPipelineBuilder &, const VkPipelineLayout)>; /// The callables to create the graphics pipelines used in the rendergraph std::vector m_on_graphics_pipeline_create_callables; - std::vector> m_graphics_pipeline_layouts; + std::vector> m_graphics_pipeline_layouts; /// The graphics pipelines used in the rendergraph /// This will be populated using m_on_graphics_pipeline_create_callables - std::vector> m_graphics_pipelines; + std::vector> m_graphics_pipelines; // TODO: Support compute pipelines and compute passes @@ -145,6 +148,9 @@ class RenderGraph { /// @note If a uniform buffer has been updated, an update of the associated descriptor set will be performed void update_buffers(); + /// Update dynamic textures + void update_textures(); + /// Update the descriptor sets void update_descriptor_sets(); @@ -171,18 +177,17 @@ class RenderGraph { /// Add a buffer (vertex, index, or uniform buffer) resource to the rendergraph /// @param name The internal name of the buffer resource (must not be empty) /// @param type The internal buffer usage of the buffer - /// @param category The estimated descriptor set category depending on the update frequency of the buffer - /// @note The update frequency of a buffer will be respected when grouping uniform buffers into descriptor sets - /// @param on_update A buffer resource update function + /// @param on_update An optional buffer resource update function (``std::nullopt`` by default) + /// @note Not every buffer must have an update function because index buffers should be updated with vertex buffers /// @exception std::runtime_error Internal debug name is empty /// @return A weak pointer to the buffer resource that was just created - [[nodiscard]] std::weak_ptr add_buffer(std::string name, BufferType type, std::function on_update); + [[nodiscard]] std::weak_ptr add_buffer(std::string name, BufferType type, + std::optional> on_update = std::nullopt); /// Add a new graphics pass to the rendergraph /// @param on_pass_create A callable to create the graphics pass using GraphicsPassBuilder void add_graphics_pass(GraphicsPassCreateCallable on_pass_create) { - // TODO: Can this be emplace_back? - m_on_graphics_pass_create_callables.push_back(std::move(on_pass_create)); + m_on_graphics_pass_create_callables.emplace_back(std::move(on_pass_create)); } /// Add a new graphics pipeline to the rendergraph diff --git a/include/inexor/vulkan-renderer/render-graph/texture.hpp b/include/inexor/vulkan-renderer/render-graph/texture.hpp index 453a051f2..9bca0a7a6 100644 --- a/include/inexor/vulkan-renderer/render-graph/texture.hpp +++ b/include/inexor/vulkan-renderer/render-graph/texture.hpp @@ -11,10 +11,6 @@ namespace inexor::vulkan_renderer::render_graph { -// Forward declaration -class RenderGraph; -enum class DescriptorSetUpdateFrequencyGroup; - /// Specifies the use of the texture inside of the rendergraph enum class TextureUsage { /// Specifies that this texture is the output of the render graph @@ -27,13 +23,14 @@ enum class TextureUsage { NORMAL, }; -// TODO: Implement texture updates and use DescriptorSetUpdateFrequencyGroup +// Forward declaration +class RenderGraph; /// Wrapper for texture resources in the rendergraph class Texture { +private: friend RenderGraph; -private: std::string m_name; TextureUsage m_usage; VkFormat m_format{VK_FORMAT_UNDEFINED}; @@ -45,15 +42,19 @@ class Texture { std::uint32_t m_height{0}; std::uint32_t m_channels{0}; std::uint32_t m_mip_levels{0}; - std::optional> m_on_update{[]() {}}; + + std::optional> m_on_init{std::nullopt}; + std::optional> m_on_update{std::nullopt}; public: /// Default constructor /// @param name The internal denug name of the texture inside of the rendergraph (must not be empty) /// @param usage The internal usage of the texture inside of the rendergraph /// @param format The format of the texture + /// @param on_init The init function of the texture /// @param on_update An optional update function (``std::nullopt`` by default, meaning no updates to this buffer) - Texture(std::string name, TextureUsage usage, VkFormat format, std::optional> on_update); + Texture(std::string name, TextureUsage usage, VkFormat format, std::optional> on_init, + std::optional> on_update); Texture(const Texture &) = delete; Texture(Texture &&other) noexcept; diff --git a/include/inexor/vulkan-renderer/wrapper/command_buffer.hpp b/include/inexor/vulkan-renderer/wrapper/command_buffer.hpp index 9a6074f79..938cd9f81 100644 --- a/include/inexor/vulkan-renderer/wrapper/command_buffer.hpp +++ b/include/inexor/vulkan-renderer/wrapper/command_buffer.hpp @@ -341,7 +341,7 @@ class CommandBuffer { /// Call vkCmdInsertDebugUtilsLabelEXT /// @param name The name of the debug label to insert /// @return A const reference to the dereferenced ``this`` pointer (allowing for method calls to be chained) - const CommandBuffer &insert_debug_label(std::string name, float color[4]) const; + const CommandBuffer &insert_debug_label(std::string name, std::array color) const; /// Call vkCmdPushConstants /// @param layout The pipeline layout diff --git a/include/inexor/vulkan-renderer/wrapper/pipelines/pipeline.hpp b/include/inexor/vulkan-renderer/wrapper/pipelines/pipeline.hpp index 29c1ba7aa..d4ad2bb2a 100644 --- a/include/inexor/vulkan-renderer/wrapper/pipelines/pipeline.hpp +++ b/include/inexor/vulkan-renderer/wrapper/pipelines/pipeline.hpp @@ -11,6 +11,11 @@ class CommandBuffer; class Device; } // namespace inexor::vulkan_renderer::wrapper +namespace inexor::vulkan_renderer::render_graph { +// Forward declaration +class RenderGraph; +} // namespace inexor::vulkan_renderer::render_graph + namespace inexor::vulkan_renderer::wrapper::pipelines { /// RAII wrapper for VkPipeline @@ -18,6 +23,7 @@ namespace inexor::vulkan_renderer::wrapper::pipelines { class GraphicsPipeline { // The CommandBuffer wrapper needs to access m_pipeline friend CommandBuffer; + friend render_graph::RenderGraph; private: const Device &m_device; diff --git a/src/vulkan-renderer/application.cpp b/src/vulkan-renderer/application.cpp index aa14c7c12..92b384d7e 100644 --- a/src/vulkan-renderer/application.cpp +++ b/src/vulkan-renderer/application.cpp @@ -454,8 +454,7 @@ void Application::setup_render_graph() { }); // Note that the index buffer is updated together with the vertex buffer to keep data consistent - // TODO: FIX ME! - m_index_buffer = m_render_graph->add_buffer("Octree", BufferType::INDEX_BUFFER, [] {}); + m_index_buffer = m_render_graph->add_buffer("Octree", BufferType::INDEX_BUFFER); // Update the vertex buffer and index buffer at initialization // Note that we update the vertex buffer together with the index buffer to keep data consistent @@ -463,7 +462,7 @@ void Application::setup_render_graph() { m_index_buffer.lock()->request_update(m_octree_indices); m_uniform_buffer = m_render_graph->add_buffer("Matrices", BufferType::UNIFORM_BUFFER, [&]() { - // The m_mvp_matrices.model matrix doesn't need to be updated + // The model matrix is constant and doesn't need to be updated m_mvp_matrices.view = m_camera->view_matrix(); m_mvp_matrices.proj = m_camera->perspective_matrix(); m_mvp_matrices.proj[1][1] *= -1; @@ -516,7 +515,6 @@ void Application::setup_render_graph() { }) .set_depth_test(true) .set_on_record([&](const wrapper::CommandBuffer &cmd_buf) { - // Render octree cmd_buf.bind_pipeline(*m_octree_pipeline) .bind_vertex_buffer(m_vertex_buffer) .bind_index_buffer(m_index_buffer) @@ -533,6 +531,18 @@ void Application::setup_render_graph() { } void Application::setup_window_and_input_callbacks() { + // The following code requires some explanation + // Because glfw is a C-style API, we can't use a pointer to non-static class methods as window or input callbacks. + // For example, we can't use Application::key_callback in glfwSetKeyCallback as key callback directly. + // A good explanation can be found on Stack Overflow: + // https://stackoverflow.com/questions/7676971/pointing-to-a-function-that-is-a-class-member-glfw-setkeycallback + // In order to fix this, we can pass a lambda to glfwSetKeyCallback, which calls Application::key_callback + // internally. But there is another problem: Inside of the template, we need to call Application::Key_callback. In + // order to do so, we need to have access to the this-pointer. Unfortunately, the this-pointer can't be captured + // in the lambda capture like [this](){}, because the glfw would not accept the lambda then. To work around this + // problem, we store the this pointer using glfwSetWindowUserPointer. Inside of these lambdas, we then cast the + // pointer to Application* again, allowing us to finally use the callbacks. + m_window->set_user_ptr(this); spdlog::trace("Setting up window callback:"); diff --git a/src/vulkan-renderer/render-graph/buffer.cpp b/src/vulkan-renderer/render-graph/buffer.cpp index 97675662a..42d1029ad 100644 --- a/src/vulkan-renderer/render-graph/buffer.cpp +++ b/src/vulkan-renderer/render-graph/buffer.cpp @@ -8,7 +8,8 @@ namespace inexor::vulkan_renderer::render_graph { -Buffer::Buffer(const wrapper::Device &device, std::string name, const BufferType type, std::function on_update) +Buffer::Buffer(const wrapper::Device &device, std::string name, const BufferType type, + std::optional> on_update) : m_device(device), m_name(std::move(name)), m_type(type), m_on_update(std::move(on_update)) { // Uniform buffer can be updated by std::memcpy, other types of memory require staging buffer updates m_requires_staging_buffer_update = (type != BufferType::UNIFORM_BUFFER); @@ -47,13 +48,14 @@ void Buffer::create_buffer(const VkDeviceSize buffer_size, const VkBufferUsageFl throw VulkanException("Error: vmaCreateBuffer failed for buffer " + m_name + " !", result); } + // We are basically storing things duplicately here, but whatever m_buf_usage = buffer_usage; m_mem_usage = memory_usage; // Set the buffer's internal debug name in Vulkan Memory Allocator (VMA) vmaSetAllocationName(m_device.allocator(), m_alloc, m_name.c_str()); - // Set the buffer's internal denug name through Vulkan debug utils + // Set the buffer's internal debug name through Vulkan debug utils m_device.set_debug_name(m_buffer, m_name); } @@ -66,6 +68,7 @@ void Buffer::destroy_buffer() { void Buffer::recreate_buffer(const VkDeviceSize new_buffer_size) { destroy_buffer(); + // We are basically storing things duplicately here, but whatever create_buffer(new_buffer_size, m_buf_usage, m_mem_usage); } diff --git a/src/vulkan-renderer/render-graph/graphics_pass.cpp b/src/vulkan-renderer/render-graph/graphics_pass.cpp index 7f144f252..cfe950c50 100644 --- a/src/vulkan-renderer/render-graph/graphics_pass.cpp +++ b/src/vulkan-renderer/render-graph/graphics_pass.cpp @@ -15,7 +15,7 @@ GraphicsPass::GraphicsPass(std::string name, BufferReads buffer_reads, TextureRe bool index_buffer_present = false; for (const auto buffer : m_buffer_reads) { // Is this buffer resource an index buffer? - if (buffer.first.lock()->m_type == BufferType::INDEX_BUFFER) { + if (buffer.first.lock()->type() == BufferType::INDEX_BUFFER) { // Is an index buffer already specified? if (index_buffer_present) { throw std::runtime_error("Error: More than one index buffer in graphics pass " + m_name + "!"); diff --git a/src/vulkan-renderer/render-graph/graphics_pass_builder.cpp b/src/vulkan-renderer/render-graph/graphics_pass_builder.cpp index f14d62df6..a71c3f221 100644 --- a/src/vulkan-renderer/render-graph/graphics_pass_builder.cpp +++ b/src/vulkan-renderer/render-graph/graphics_pass_builder.cpp @@ -12,12 +12,6 @@ std::shared_ptr GraphicsPassBuilder::build(std::string name) { std::move(m_clear_value)); } -/* - GraphicsPass(std::string name, BufferReads buffer_reads, TextureReads texture_reads, TextureWrites texture_writes, - std::function on_record, - std::optional clear_values); -*/ - void GraphicsPassBuilder::reset() { m_clear_value = std::nullopt; m_on_record = [](auto &) {}; diff --git a/src/vulkan-renderer/render-graph/render_graph.cpp b/src/vulkan-renderer/render-graph/render_graph.cpp index c23c8700a..e6af9e17b 100644 --- a/src/vulkan-renderer/render-graph/render_graph.cpp +++ b/src/vulkan-renderer/render-graph/render_graph.cpp @@ -16,13 +16,14 @@ RenderGraph::RenderGraph(wrapper::Device &device, wrapper::Swapchain &swapchain) : m_device(device), m_swapchain(swapchain), m_graphics_pipeline_builder(device) {} std::weak_ptr RenderGraph::add_buffer(std::string name, const BufferType type, - std::function on_update) { + std::optional> on_update) { if (name.empty()) { throw std::invalid_argument("Error: Buffer name must not be empty!"); } - // Add the buffer resource to the rendergraph - // m_buffers.emplace_back(std::make_unique(m_device, std::move(name), type, std::move(on_update))); - // Return a weak pointer to the buffer resource that was just created + m_buffers.emplace_back(std::make_shared(m_device, // + std::move(name), // + type, // + std::move(on_update))); return m_buffers.back(); } @@ -32,14 +33,16 @@ std::weak_ptr RenderGraph::add_texture(std::string name, const TextureU if (name.empty()) { throw std::invalid_argument("Error: Texture name must not be empty!"); } - // Add the texture resource to the rendergraph - m_textures.emplace_back(std::make_shared(std::move(name), usage, format, std::move(on_update))); - // Return a weak pointer to the texture resource that was just created + m_textures.emplace_back(std::make_shared(std::move(name), // + usage, // + format, // + std::move(on_init), // + std::move(on_update))); return m_textures.back(); } void RenderGraph::check_for_cycles() { - abort(); + m_log->warn("Implement RenderGraph::check_for_cycles()!"); } void RenderGraph::compile() { @@ -56,14 +59,17 @@ void RenderGraph::compile() { } void RenderGraph::create_buffers() { - for (const auto &pass : m_graphics_passes) { + // Do not call the buffers via passes, but through rendergraph directly? + + for (const auto &graphics_pass : m_graphics_passes) { // Create the vertex buffers of the pass // Note that each pass must have at least one vertex buffer - for (auto &vertex_buffer : pass->m_vertex_buffers) { + for (const auto &vertex_buffer : graphics_pass->m_vertex_buffers) { // } - // TODO: Create index buffer if required + // TODO: Create index buffers + // TOOD: Create uniform buffers } #if 0 @@ -106,7 +112,6 @@ void RenderGraph::create_buffers() { void RenderGraph::create_descriptor_sets() { m_log->trace("Creating descriptor sets"); - spdlog::warn("And to this day, Hanni was too lazy too implement create_descriptor_sets()"); } void RenderGraph::create_graphics_passes() { @@ -135,12 +140,13 @@ void RenderGraph::create_graphics_pipeline_layouts() { m_graphics_pipeline_layouts.reserve(m_graphics_pipelines.size()); for (const auto &pipeline : m_graphics_pipelines) { - // TODO: How to associate pipelines with passes? - /* m_graphics_pipeline_layouts.emplace_back(m_device, // - pipeline->descriptor_set_layouts(), // - pipeline->push_constant_ranges(), // - pipeline->name()); - */ +// TODO: How to associate pipelines with passes? +#if 0 + m_graphics_pipeline_layouts.emplace_back(std::make_unique(m_device, // + pipeline->descriptor_set_layouts(), // + pipeline->push_constant_ranges(), // + pipeline->name())); +#endif } } @@ -164,10 +170,10 @@ void RenderGraph::create_graphics_pipelines() { } void RenderGraph::create_textures() { - spdlog::warn("And to this day, Hanni was too lazy too implement create_textures()"); - // Loop through all texture resources and create them - for (auto &texture : m_textures) { - // TODO: Update texture here? + m_log->trace("Creating {} textures", m_textures.size()); + for (const auto &texture : m_textures) { + // Call the optional init lambda of the texture + std::invoke(texture->m_on_init.value()); } } @@ -179,8 +185,8 @@ void RenderGraph::record_command_buffer_for_pass(const wrapper::CommandBuffer &c const bool is_first_pass, const bool is_last_pass, const std::uint32_t img_index) { // Start a new debug label for this graphics pass - // This is for debugging in RenderDoc only - // TODO: make constexpr std::array<> for color codes! + // These debug labels are visible in RenderDoc + // TODO: Generate color gradient depending on the number of passes? (Interpolate e.g. in 12 steps for 12 passes) cmd_buf.begin_debug_label_region(pass.m_name, {1.0f, 0.0f, 0.0f, 1.0f}); // If this is the first graphics pass, we need to transform the swapchain image, which comes back in undefined @@ -265,14 +271,15 @@ void RenderGraph::record_command_buffer_for_pass(const wrapper::CommandBuffer &c // End dynamic rendering cmd_buf.end_rendering(); - // If this is the last pass, transform the back buffer for presenting + // If this is the last pass, transition the image layout the back buffer for presenting if (is_last_pass) { - // cmd_buf.change_image_layout(m_swapchain.image(img_index), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); + cmd_buf.change_image_layout(m_swapchain.image(img_index), // + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); } - // End the debug label for the graphics pass - // This is for debugging in RenderDoc only + // End the debug label for this graphics pass + // These debug labels are visible in RenderDoc cmd_buf.end_debug_label_region(); } @@ -307,8 +314,20 @@ void RenderGraph::render() { void RenderGraph::update_buffers() { for (const auto &buffer : m_buffers) { - // Call the update lambda of the buffer - std::invoke(buffer->m_on_update); + // Call the update lambda of the buffer, if specified + if (buffer->m_on_update) { + std::invoke(buffer->m_on_update.value()); + } + } + // TODO: Batch barriers for updates which require staging buffer +} + +void RenderGraph::update_textures() { + for (const auto &texture : m_textures) { + if (texture->m_on_update) { + // Call the update lambda of the texture + std::invoke(texture->m_on_update.value()); + } } // TODO: Batch barriers for updates which require staging buffer } @@ -324,7 +343,7 @@ void RenderGraph::update_descriptor_sets() { void RenderGraph::update_push_constant_ranges() { for (const auto &push_constant : m_push_constant_ranges) { // Call the update lambda of the push constant range - push_constant->m_on_update(); + std::invoke(push_constant->m_on_update); } } diff --git a/src/vulkan-renderer/render-graph/texture.cpp b/src/vulkan-renderer/render-graph/texture.cpp index 77bed8cfa..d082f7500 100644 --- a/src/vulkan-renderer/render-graph/texture.cpp +++ b/src/vulkan-renderer/render-graph/texture.cpp @@ -7,8 +7,9 @@ namespace inexor::vulkan_renderer::render_graph { Texture::Texture(std::string name, const TextureUsage usage, const VkFormat format, - std::optional> on_update) - : m_name(std::move(name)), m_usage(usage), m_format(format), m_on_update(std::move(on_update)) {} + std::optional> on_init, std::optional> on_update) + : m_name(std::move(name)), m_usage(usage), m_format(format), m_on_init(std::move(on_init)), + m_on_update(std::move(on_update)) {} Texture::Texture(Texture &&other) noexcept { m_name = std::move(other.m_name); @@ -21,6 +22,7 @@ Texture::Texture(Texture &&other) noexcept { m_height = other.m_height; m_channels = other.m_channels; m_mip_levels = other.m_mip_levels; + m_on_init = std::move(other.m_on_init); m_on_update = std::move(other.m_on_update); } diff --git a/src/vulkan-renderer/wrapper/command_buffer.cpp b/src/vulkan-renderer/wrapper/command_buffer.cpp index c43d59519..04bff5855 100644 --- a/src/vulkan-renderer/wrapper/command_buffer.cpp +++ b/src/vulkan-renderer/wrapper/command_buffer.cpp @@ -87,29 +87,26 @@ const CommandBuffer &CommandBuffer::bind_descriptor_set(const VkDescriptorSet de const CommandBuffer &CommandBuffer::bind_index_buffer(const std::weak_ptr buffer, const VkIndexType index_type, const VkDeviceSize offset) const { - if (buffer.lock()->m_type != render_graph::BufferType::INDEX_BUFFER) { - throw std::invalid_argument("Error: Rendergraph buffer resource " + buffer.lock()->m_name + + if (buffer.lock()->type() != render_graph::BufferType::INDEX_BUFFER) { + throw std::invalid_argument("Error: Rendergraph buffer resource " + buffer.lock()->name() + " is not an index buffer!"); } - // CommandBuffer is a friend class of BufferResource and is thus allowed to access m_buffer - vkCmdBindIndexBuffer(m_cmd_buf, buffer.lock()->m_buffer, offset, index_type); + vkCmdBindIndexBuffer(m_cmd_buf, buffer.lock()->buffer(), offset, index_type); return *this; } const CommandBuffer &CommandBuffer::bind_pipeline(const pipelines::GraphicsPipeline &pipeline, const VkPipelineBindPoint bind_point) const { - // CommandBuffer is a friend class of GraphicsPipeline and is thus allowed to access m_pipeline vkCmdBindPipeline(m_cmd_buf, bind_point, pipeline.m_pipeline); return *this; } const CommandBuffer &CommandBuffer::bind_vertex_buffer(const std::weak_ptr buffer) const { - if (buffer.lock()->m_type != render_graph::BufferType::VERTEX_BUFFER) { - throw std::invalid_argument("Error: Rendergraph buffer resource " + buffer.lock()->m_name + + if (buffer.lock()->type() != render_graph::BufferType::VERTEX_BUFFER) { + throw std::invalid_argument("Error: Rendergraph buffer resource " + buffer.lock()->name() + " is not a vertex buffer!"); } - // CommandBuffer is a friend class of BufferResource and wrapper::Buffer and is thus allowed to access m_buffer - vkCmdBindVertexBuffers(m_cmd_buf, 0, 1, &buffer.lock()->m_buffer, 0); + vkCmdBindVertexBuffers(m_cmd_buf, 0, 1, &buffer.lock()->buffer(), 0); return *this; } @@ -302,16 +299,11 @@ const CommandBuffer &CommandBuffer::full_barrier() const { })); } -const CommandBuffer &CommandBuffer::insert_debug_label(std::string name, float color[4]) const { +const CommandBuffer &CommandBuffer::insert_debug_label(std::string name, std::array color) const { auto label = make_info({ .pLabelName = name.c_str(), + .color = {color[0], color[1], color[2], color[3]}, }); - // TODO: Fix me :( - label.color[0] = color[0]; - label.color[1] = color[1]; - label.color[2] = color[2]; - label.color[3] = color[3]; - vkCmdBeginDebugUtilsLabelEXT(m_cmd_buf, &label); return *this; }