From 94d243bc2d4ab6e334200616a3c8a01a43a567ee Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Thu, 25 Dec 2025 22:45:31 +0100 Subject: [PATCH] workaround: leak Vulkan instance & device comments document why this is needed. closes #59 --- .../include/lsfg-vk-backend/lsfgvk.hpp | 7 +++++ lsfg-vk-backend/src/lsfgvk.cpp | 28 +++++++++++++++++++ lsfg-vk-layer/src/entrypoint.cpp | 4 +-- lsfg-vk-layer/src/swapchain.cpp | 2 ++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/lsfg-vk-backend/include/lsfg-vk-backend/lsfgvk.hpp b/lsfg-vk-backend/include/lsfg-vk-backend/lsfgvk.hpp index e3e3fca..919e14a 100644 --- a/lsfg-vk-backend/include/lsfg-vk-backend/lsfgvk.hpp +++ b/lsfg-vk-backend/include/lsfg-vk-backend/lsfgvk.hpp @@ -129,4 +129,11 @@ namespace lsfgvk::backend { std::vector> m_contexts; }; + /// + /// Make all lsfg-vk instances leaking. + /// This is to workaround a bug in the Vulkan loader, which + /// makes it impossible to destroy Vulkan instances and devices. + /// + void makeLeaking(); + } diff --git a/lsfg-vk-backend/src/lsfgvk.cpp b/lsfg-vk-backend/src/lsfgvk.cpp index 7be7c4c..6e97d4e 100644 --- a/lsfg-vk-backend/src/lsfgvk.cpp +++ b/lsfg-vk-backend/src/lsfgvk.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,12 @@ namespace lsfgvk::backend { /// @return the RenderDoc API [[nodiscard]] const auto& getRenderDocAPI() const { return this->renderdoc; } #endif + // Movable, non-copyable, custom destructor + InstanceImpl(const InstanceImpl&) = delete; + InstanceImpl& operator=(const InstanceImpl&) = delete; + InstanceImpl(InstanceImpl&&) = default; + InstanceImpl& operator=(InstanceImpl&&) = default; + ~InstanceImpl(); private: vk::Vulkan vk; ShaderRegistry shaders; @@ -634,3 +641,24 @@ void Instance::closeContext(const Context& context) { } Instance::~Instance() = default; + +// leaking shenanigans + +namespace { + bool leaking{false}; // NOLINT +} + +InstanceImpl::~InstanceImpl() { + if (!leaking) return; + + try { + new vk::Vulkan(std::move(this->vk)); + } catch (...) { + std::cerr << "lsfg-vk: failed to leak Vulkan instance\n"; + } + +} + +void backend::makeLeaking() { + leaking = true; +} diff --git a/lsfg-vk-layer/src/entrypoint.cpp b/lsfg-vk-layer/src/entrypoint.cpp index b8e12b2..0512732 100644 --- a/lsfg-vk-layer/src/entrypoint.cpp +++ b/lsfg-vk-layer/src/entrypoint.cpp @@ -232,8 +232,8 @@ namespace { // destroy layer info // NOTE: there's no real way of unloading the layer without a deconstructor. // multiple instances just aren't common enough to worry about it. - // NOTE2: it doesn't really matter anyways, because the myvkDestroyDevice code - // freezes the entire thing anyways. + // NOTE2: this IS a memory leak, because the VkInstance inside of root->backend + // cannot be destroyed, due to a Vulkan-Loader limitation/bug. delete layer_info; layer_info = nullptr; } diff --git a/lsfg-vk-layer/src/swapchain.cpp b/lsfg-vk-layer/src/swapchain.cpp index 9cebfe3..b3abf5c 100644 --- a/lsfg-vk-layer/src/swapchain.cpp +++ b/lsfg-vk-layer/src/swapchain.cpp @@ -104,6 +104,8 @@ Swapchain::Swapchain(const vk::Vulkan& vk, backend::Instance& backend, backend->closeContext(ctx); } ); + + backend::makeLeaking(); // don't worry about it :3 } catch (const std::exception& e) { throw ls::error("failed to create swapchain context", e); }