diff --git a/include/inexor/vulkan-renderer/render-graph/texture.hpp b/include/inexor/vulkan-renderer/render-graph/texture.hpp index d21988d0d..6aa5e15bc 100644 --- a/include/inexor/vulkan-renderer/render-graph/texture.hpp +++ b/include/inexor/vulkan-renderer/render-graph/texture.hpp @@ -76,6 +76,9 @@ class Texture { /// By definition, if this is not std::nullopt, this is a dynamic texture std::optional> m_on_update{std::nullopt}; + VmaAllocation m_alloc{}; + VmaAllocationInfo m_alloc_info{}; + // The staging buffer for updating the texture data VkBuffer m_staging_buffer{VK_NULL_HANDLE}; VmaAllocation m_staging_buffer_alloc{VK_NULL_HANDLE}; @@ -90,6 +93,9 @@ class Texture { /// Destroy the texture (and the MSAA texture if specified) void destroy(); + /// Destroy the staging buffer used for texture updates + void destroy_staging_buffer(); + /// Upload the data into the texture /// @param cmd_buf The command buffer to record the commands into void update(const CommandBuffer &cmd_buf); @@ -118,7 +124,7 @@ class Texture { ~Texture(); Texture &operator=(const Texture &) = delete; - Texture &operator=(Texture &&) noexcept; + Texture &operator=(Texture &&) = delete; /// Request rendergraph to update the texture /// @param src_texture_data A pointer to the source data diff --git a/include/inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_builder.hpp b/include/inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_builder.hpp index 22d0863fb..5e6b7da87 100644 --- a/include/inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_builder.hpp +++ b/include/inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_builder.hpp @@ -1,5 +1,7 @@ #pragma once +#include "inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_cache.hpp" + #include #include @@ -18,9 +20,6 @@ class Device; namespace inexor::vulkan_renderer::wrapper::descriptors { -// Forward declarations -class DescriptorSetLayoutCache; - /// A builder for descriptors class DescriptorSetLayoutBuilder { friend class RenderGraph; @@ -28,7 +27,7 @@ class DescriptorSetLayoutBuilder { private: const Device &m_device; /// All instances of DescriptorSetLayoutBuilder have the same DescriptorSetLayoutCache instance! - static DescriptorSetLayoutCache m_descriptor_set_layout_cache; + DescriptorSetLayoutCache m_descriptor_set_layout_cache; std::vector m_bindings; std::uint32_t m_binding{0}; diff --git a/include/inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_cache.hpp b/include/inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_cache.hpp index f463dd7ce..e255f23c5 100644 --- a/include/inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_cache.hpp +++ b/include/inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_cache.hpp @@ -58,7 +58,7 @@ class DescriptorSetLayoutCache { public: /// Default constructor /// @param device The device wrapper - explicit DescriptorSetLayoutCache(const Device &device); + DescriptorSetLayoutCache(const Device &device); DescriptorSetLayoutCache(const DescriptorSetLayoutCache &) = delete; DescriptorSetLayoutCache(DescriptorSetLayoutCache &&) noexcept; ~DescriptorSetLayoutCache() = default; diff --git a/include/inexor/vulkan-renderer/wrapper/sampler.hpp b/include/inexor/vulkan-renderer/wrapper/sampler.hpp index 181c39a4f..0c108fafb 100644 --- a/include/inexor/vulkan-renderer/wrapper/sampler.hpp +++ b/include/inexor/vulkan-renderer/wrapper/sampler.hpp @@ -8,6 +8,7 @@ namespace inexor::vulkan_renderer::render_graph { // Forward declaration +class RenderGraph; class Texture; } // namespace inexor::vulkan_renderer::render_graph @@ -17,10 +18,12 @@ namespace inexor::vulkan_renderer::wrapper { class Device; // Using declaration +using render_graph::RenderGraph; using render_graph::Texture; /// RAII wrapper class for VkSampler class Sampler { + friend class RenderGraph; friend class Texture; private: @@ -54,10 +57,9 @@ class Sampler { .unnormalizedCoordinates = VK_FALSE, })); - ~Sampler(); - Sampler(const Sampler &) = delete; Sampler(Sampler &&) noexcept; + ~Sampler(); Sampler &operator=(const Sampler &) = delete; Sampler &operator=(Sampler &&) = delete; diff --git a/src/vulkan-renderer/render-graph/render_graph.cpp b/src/vulkan-renderer/render-graph/render_graph.cpp index af1387184..128c6d3f5 100644 --- a/src/vulkan-renderer/render-graph/render_graph.cpp +++ b/src/vulkan-renderer/render-graph/render_graph.cpp @@ -167,28 +167,12 @@ void RenderGraph::create_rendering_infos() { void RenderGraph::create_textures() { m_device.execute("[RenderGraph::create_textures]", [&](const CommandBuffer &cmd_buf) { for (const auto &texture : m_textures) { - switch (texture->m_usage) { - case TextureUsage::NORMAL: { - if (texture->m_on_init) { - std::invoke(texture->m_on_init.value()); - // TODO: Implement me! - texture->create(); - texture->update(cmd_buf); - } - break; - } - case TextureUsage::DEPTH_STENCIL_BUFFER: { - // TODO: Implement me! - break; - } - case TextureUsage::BACK_BUFFER: { - // TODO: Implement me! - break; - } - default: { - break; - } + // TODO: Check if this initializes all textures (internal ones from rendergraph and external like ImGui?) + if (texture->m_on_init) { + std::invoke(texture->m_on_init.value()); } + texture->create(); + texture->update(cmd_buf); } }); } @@ -204,8 +188,12 @@ void RenderGraph::record_command_buffer_for_pass(const CommandBuffer &cmd_buf, c cmd_buf.begin_debug_label_region(pass.m_name, {1.0f, 0.0f, 0.0f, 1.0f}); // 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 + + // 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(); // End the debug label for this graphics pass diff --git a/src/vulkan-renderer/render-graph/texture.cpp b/src/vulkan-renderer/render-graph/texture.cpp index 18286ba1c..67ccb8d76 100644 --- a/src/vulkan-renderer/render-graph/texture.cpp +++ b/src/vulkan-renderer/render-graph/texture.cpp @@ -4,6 +4,7 @@ #include "inexor/vulkan-renderer/wrapper/commands/command_buffer.hpp" #include "inexor/vulkan-renderer/wrapper/device.hpp" #include "inexor/vulkan-renderer/wrapper/make_info.hpp" +#include "inexor/vulkan-renderer/wrapper/sampler.hpp" #include #include @@ -25,6 +26,10 @@ Texture::Texture(const Device &device, } } +Texture::~Texture() { + destroy(); +} + void Texture::create() { auto img_ci = wrapper::make_info({ .imageType = VK_IMAGE_TYPE_2D, @@ -94,17 +99,21 @@ void Texture::destroy() { if (m_msaa_img) { m_msaa_img->destroy(); } + // TODO: Destroy staging buffer and other buffers +} + +void Texture::destroy_staging_buffer() { + vmaDestroyBuffer(m_device.allocator(), m_staging_buffer, m_staging_buffer_alloc); + m_staging_buffer = VK_NULL_HANDLE; + m_staging_buffer_alloc = VK_NULL_HANDLE; } void Texture::update(const CommandBuffer &cmd_buf) { -#if 0 if (m_staging_buffer != VK_NULL_HANDLE) { - vmaDestroyBuffer(m_device.allocator(), m_staging_buffer, m_staging_buffer_alloc); - m_staging_buffer = VK_NULL_HANDLE; - m_staging_buffer_alloc = VK_NULL_HANDLE; + destroy_staging_buffer(); } const auto staging_buffer_ci = wrapper::make_info({ - .size = m_texture_data_size, + .size = m_src_texture_data_size, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, }); @@ -120,20 +129,20 @@ void Texture::update(const CommandBuffer &cmd_buf) { throw VulkanException("Error: vmaCreateBuffer failed for staging buffer " + m_name + "!", result); } - cmd_buf.pipeline_image_memory_barrier_before_copy_buffer_to_image(m_img) - .copy_buffer_to_image(m_staging_buffer, m_img, + cmd_buf.pipeline_image_memory_barrier_before_copy_buffer_to_image(m_img->m_img) + .copy_buffer_to_image(m_staging_buffer, m_img->m_img, { - .width = m_img_ci.extent.width, - .height = m_img_ci.extent.height, + .width = m_width, + .height = m_height, .depth = 1, }) - .pipeline_image_memory_barrier_after_copy_buffer_to_image(m_img); + .pipeline_image_memory_barrier_after_copy_buffer_to_image(m_img->m_img); // TODO: Do we need to create sampler and image view here? or in create()? // Update the descriptor image info - m_descriptor_image_info = VkDescriptorImageInfo{ - .sampler = m_sampler->m_sampler, - .imageView = m_img_view, + m_descriptor_img_info = VkDescriptorImageInfo{ + .sampler = m_img->m_sampler->m_sampler, + .imageView = m_img->m_img_view, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, }; @@ -141,7 +150,6 @@ void Texture::update(const CommandBuffer &cmd_buf) { // It will be destroyed either in the destructor or the next time execute_update is called // Another option would have been to wrap each call to execute_update() into its own single time // command buffer, which would increase the total number of command buffer submissions though -#endif } void Texture::request_update(void *src_texture_data, const std::size_t src_texture_data_size) { diff --git a/src/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_builder.cpp b/src/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_builder.cpp index 66970e59d..84cdf639f 100644 --- a/src/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_builder.cpp +++ b/src/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_builder.cpp @@ -1,15 +1,15 @@ #include "inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_builder.hpp" -#include "inexor/vulkan-renderer/wrapper/descriptors/descriptor_set_layout_cache.hpp" #include "inexor/vulkan-renderer/wrapper/device.hpp" #include "inexor/vulkan-renderer/wrapper/make_info.hpp" namespace inexor::vulkan_renderer::wrapper::descriptors { -DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder(const Device &device) : m_device(device) {} +DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder(const Device &device) + : m_device(device), m_descriptor_set_layout_cache(device) {} DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder(DescriptorSetLayoutBuilder &&other) noexcept - : m_device(other.m_device) { + : m_device(other.m_device), m_descriptor_set_layout_cache(std::move(other.m_descriptor_set_layout_cache)) { m_bindings = std::move(other.m_bindings); m_binding = other.m_binding; }