workaround: leak Vulkan instance & device
Some checks are pending
(CI) lsfg-vk / build (push) Waiting to run
(CI/Flatpak) lsfg-vk / flatpak-extensions (24.08) (push) Waiting to run
(CI/Flatpak) lsfg-vk / flatpak-extensions (25.08) (push) Waiting to run
(CI/Flatpak) lsfg-vk / flatpak-ui (push) Waiting to run
(CI/Flatpak) lsfg-vk / flatpak-extensions (23.08) (push) Waiting to run

comments document why this is needed. closes #59
This commit is contained in:
PancakeTAS 2025-12-25 22:45:31 +01:00
parent ceff118e8a
commit 94d243bc2d
No known key found for this signature in database
4 changed files with 39 additions and 2 deletions

View file

@ -129,4 +129,11 @@ namespace lsfgvk::backend {
std::vector<std::unique_ptr<Context>> 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();
}

View file

@ -32,6 +32,7 @@
#include <exception>
#include <filesystem>
#include <functional>
#include <iostream>
#include <memory>
#include <optional>
#include <stdexcept>
@ -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;
}

View file

@ -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;
}

View file

@ -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);
}