diff --git a/flake.nix b/flake.nix index f9fc6c9..24e482a 100644 --- a/flake.nix +++ b/flake.nix @@ -45,6 +45,7 @@ with pkgs; [ llvmPackages_21.clang-tools + llvmPackages_21.bintools lldb codespell doxygen diff --git a/meson.build b/meson.build index 1aa80ce..1fff1b6 100644 --- a/meson.build +++ b/meson.build @@ -82,6 +82,8 @@ add_project_arguments( '-Wno-macro-redefined', '-DVULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE', '-DVULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1', + # Thanks forityf source + '-Wno-#warnings' ], language : 'cpp' ) diff --git a/src/DescriptorAllocatorGrowable.cpp b/src/DescriptorAllocatorGrowable.cpp index 8ed0085..fac259e 100644 --- a/src/DescriptorAllocatorGrowable.cpp +++ b/src/DescriptorAllocatorGrowable.cpp @@ -1,5 +1,7 @@ #include "DescriptorAllocatorGrowable.h" +#include + #include "Logger.h" #include "Util.h" @@ -9,6 +11,10 @@ auto DescriptorAllocatorGrowable::init(VkDevice dev, uint32_t max_sets, std::span pool_ratios) -> void { m_ratios.clear(); + m_current_pool = VK_NULL_HANDLE; + m_full_pools.clear(); + m_used_pools.clear(); + m_ready_pools.clear(); m_ratios.insert(m_ratios.begin(), pool_ratios.begin(), pool_ratios.end()); @@ -23,25 +29,50 @@ auto DescriptorAllocatorGrowable::init(VkDevice dev, uint32_t max_sets, auto DescriptorAllocatorGrowable::clear_pools(VkDevice dev) -> void { - for (auto const p : m_ready_pools) + std::vector all_pools; + all_pools.reserve( + m_ready_pools.size() + m_used_pools.size() + m_full_pools.size()); + all_pools.insert( + all_pools.end(), m_ready_pools.begin(), m_ready_pools.end()); + all_pools.insert(all_pools.end(), m_used_pools.begin(), m_used_pools.end()); + all_pools.insert(all_pools.end(), m_full_pools.begin(), m_full_pools.end()); + + std::sort(all_pools.begin(), all_pools.end()); + all_pools.erase( + std::unique(all_pools.begin(), all_pools.end()), all_pools.end()); + + for (auto const p : all_pools) { vkResetDescriptorPool(dev, p, 0); - for (auto const p : m_full_pools) { - vkResetDescriptorPool(dev, p, 0); - m_ready_pools.emplace_back(p); } + + m_ready_pools = std::move(all_pools); + m_used_pools.clear(); m_full_pools.clear(); + m_current_pool = VK_NULL_HANDLE; } auto DescriptorAllocatorGrowable::destroy_pools(VkDevice dev) -> void { - for (auto const p : m_ready_pools) { + std::vector all_pools; + all_pools.reserve( + m_ready_pools.size() + m_used_pools.size() + m_full_pools.size()); + all_pools.insert( + all_pools.end(), m_ready_pools.begin(), m_ready_pools.end()); + all_pools.insert(all_pools.end(), m_used_pools.begin(), m_used_pools.end()); + all_pools.insert(all_pools.end(), m_full_pools.begin(), m_full_pools.end()); + + std::sort(all_pools.begin(), all_pools.end()); + all_pools.erase( + std::unique(all_pools.begin(), all_pools.end()), all_pools.end()); + + for (auto const p : all_pools) { vkDestroyDescriptorPool(dev, p, nullptr); } + m_ready_pools.clear(); - for (auto const p : m_full_pools) { - vkDestroyDescriptorPool(dev, p, nullptr); - } + m_used_pools.clear(); m_full_pools.clear(); + m_current_pool = VK_NULL_HANDLE; } auto DescriptorAllocatorGrowable::allocate(Logger &logger, VkDevice dev, @@ -60,31 +91,36 @@ auto DescriptorAllocatorGrowable::allocate(Logger &logger, VkDevice dev, auto const res = vkAllocateDescriptorSets(dev, &alloci, &ds); if (res == VK_ERROR_OUT_OF_POOL_MEMORY || res == VK_ERROR_FRAGMENTED_POOL) { m_full_pools.emplace_back(pool_to_use); + if (m_current_pool == pool_to_use) { + m_current_pool = VK_NULL_HANDLE; + } pool_to_use = get_pool(dev); alloci.descriptorPool = pool_to_use; VK_CHECK(logger, vkAllocateDescriptorSets(dev, &alloci, &ds)); } - m_ready_pools.emplace_back(pool_to_use); return ds; } auto DescriptorAllocatorGrowable::get_pool(VkDevice dev) -> VkDescriptorPool { - VkDescriptorPool new_pool; + if (m_current_pool != VK_NULL_HANDLE) { + return m_current_pool; + } - if (m_ready_pools.empty()) { - new_pool = create_pool(dev, m_sets_per_pool, m_ratios); + if (!m_ready_pools.empty()) { + m_current_pool = m_ready_pools.back(); + m_ready_pools.pop_back(); + } else { + m_current_pool = create_pool(dev, m_sets_per_pool, m_ratios); m_sets_per_pool = static_cast(m_sets_per_pool * 1.5); if (m_sets_per_pool > 4092) m_sets_per_pool = 4092; - } else { - new_pool = m_ready_pools.back(); - m_ready_pools.pop_back(); } - return new_pool; + m_used_pools.emplace_back(m_current_pool); + return m_current_pool; } auto DescriptorAllocatorGrowable::create_pool(VkDevice dev, uint32_t set_count, diff --git a/src/DescriptorAllocatorGrowable.h b/src/DescriptorAllocatorGrowable.h index b93591a..151ad25 100644 --- a/src/DescriptorAllocatorGrowable.h +++ b/src/DescriptorAllocatorGrowable.h @@ -30,7 +30,9 @@ private: std::span pool_ratios) -> VkDescriptorPool; std::vector m_ratios; + VkDescriptorPool m_current_pool { VK_NULL_HANDLE }; std::vector m_full_pools; + std::vector m_used_pools; std::vector m_ready_pools; uint32_t m_sets_per_pool; }; diff --git a/src/VulkanRenderer.cpp b/src/VulkanRenderer.cpp index 087f338..f8d86ed 100644 --- a/src/VulkanRenderer.cpp +++ b/src/VulkanRenderer.cpp @@ -1155,15 +1155,17 @@ auto VulkanRenderer::render(std::function const &record) -> void return; } + auto &frame = m_vk.get_current_frame(); VK_CHECK(m_logger, - m_device.waitForFences( - m_vk.get_current_frame().render_fence.get(), true, 1'000'000'000)); - auto raw_fence - = static_cast(m_vk.get_current_frame().render_fence.get()); + m_device.waitForFences(frame.render_fence.get(), true, 1'000'000'000)); + frame.deletion_queue.flush(); + frame.frame_descriptors.clear_pools(m_vkb.dev.device); + + auto raw_fence = static_cast(frame.render_fence.get()); VK_CHECK(m_logger, vkResetFences(m_vkb.dev.device, 1, &raw_fence)); - auto const acquire_result = m_device.acquireNextImageKHR(m_vk.swapchain, - 1'000'000'000, m_vk.get_current_frame().swapchain_semaphore.get(), {}); + auto const acquire_result = m_device.acquireNextImageKHR( + m_vk.swapchain, 1'000'000'000, frame.swapchain_semaphore.get(), {}); if (acquire_result.result == vk::Result::eErrorOutOfDateKHR || acquire_result.result == vk::Result::eSuboptimalKHR) { int width {}, height {}; @@ -1175,7 +1177,7 @@ auto VulkanRenderer::render(std::function const &record) -> void VK_CHECK(m_logger, acquire_result.result); uint32_t const swapchain_image_idx { acquire_result.value }; - auto cmd { m_vk.get_current_frame().main_command_buffer.get() }; + auto cmd { frame.main_command_buffer.get() }; cmd.reset(); m_vk.draw_extent.width = m_vk.draw_image.extent.width;