diff --git a/lsfg-vk-common/src/configuration/config.cpp b/lsfg-vk-common/src/configuration/config.cpp index a3c44e8..f9c380e 100644 --- a/lsfg-vk-common/src/configuration/config.cpp +++ b/lsfg-vk-common/src/configuration/config.cpp @@ -287,9 +287,9 @@ bool WatchedConfig::update() { const auto now = std::filesystem::last_write_time(this->path); if (now == this->last_timestamp) return false; + this->last_timestamp = now; ConfigFile new_config{this->path}; - this->last_timestamp = now; this->configFile = std::move(new_config); return true; } diff --git a/lsfg-vk-layer/src/entrypoint.cpp b/lsfg-vk-layer/src/entrypoint.cpp index abc852a..8d9a51c 100644 --- a/lsfg-vk-layer/src/entrypoint.cpp +++ b/lsfg-vk-layer/src/entrypoint.cpp @@ -2,6 +2,7 @@ #include "lsfg-vk-common/helpers/errors.hpp" #include "lsfg-vk-common/helpers/pointers.hpp" #include "lsfg-vk-common/vulkan/vulkan.hpp" +#include "swapchain.hpp" #include #include @@ -33,6 +34,7 @@ namespace { std::unordered_map devices; std::unordered_map> swapchains; + std::unordered_map swapchainInfos; }* instance_info; // create instance @@ -314,14 +316,16 @@ namespace { if (res != VK_SUCCESS) throw ls::vulkan_error(res, "vkGetSwapchainImagesKHR() failed"); - // create lsfg-vk swapchain - layer_info->root.createSwapchainContext(it->second, *swapchain, { + auto& info = instance_info->swapchainInfos.emplace(*swapchain, SwapchainInfo { .images = std::move(swapchainImages), .format = newInfo.imageFormat, .colorSpace = newInfo.imageColorSpace, .extent = newInfo.imageExtent, .presentMode = newInfo.presentMode - }); + }).first->second; + + // create lsfg-vk swapchain + layer_info->root.createSwapchainContext(it->second, *swapchain, info); instance_info->swapchains.emplace(*swapchain, ls::R(it->second)); @@ -343,6 +347,30 @@ namespace { #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" VkResult result = VK_SUCCESS; + // ensure layer config is up to date + bool reload{}; + try { + reload = layer_info->root.update(); + } catch (const std::exception&) { + reload = false; // ignore parse errors + } + + if (reload) { + try { + for (const auto& [swapchain, vk] : instance_info->swapchains) { + auto& info = instance_info->swapchainInfos.at(swapchain); + + layer_info->root.removeSwapchainContext(swapchain); + layer_info->root.createSwapchainContext(vk, swapchain, info); + } + + std::cerr << "lsfg-vk: updated lsfg-vk configuration\n"; + } catch (const std::exception& e) { + std::cerr << "lsfg-vk: something went wrong during lsfg-vk configuration update:\n"; + std::cerr << "- " << e.what() << '\n'; + } + } + // present each swapchain for (size_t i = 0; i < info->swapchainCount; i++) { const auto& swapchain = info->pSwapchains[i]; // NOLINT (array index) diff --git a/lsfg-vk-layer/src/instance.cpp b/lsfg-vk-layer/src/instance.cpp index 3a3c5cb..c22d630 100644 --- a/lsfg-vk-layer/src/instance.cpp +++ b/lsfg-vk-layer/src/instance.cpp @@ -107,8 +107,17 @@ Root::Root() { } } -void Root::update() { - this->config.update(); +bool Root::update() { + if (!this->config.update()) + return false; + + const auto& profile = findProfile(this->config.get(), ls::identify()); + if (profile.has_value()) + this->active_profile = profile->second; + else + this->active_profile = std::nullopt; + + return true; } void Root::modifyInstanceCreateInfo(VkInstanceCreateInfo& createInfo, diff --git a/lsfg-vk-layer/src/instance.hpp b/lsfg-vk-layer/src/instance.hpp index 0c2ed00..72eb7a6 100644 --- a/lsfg-vk-layer/src/instance.hpp +++ b/lsfg-vk-layer/src/instance.hpp @@ -26,7 +26,8 @@ namespace lsfgvk::layer { [[nodiscard]] bool active() const { return this->active_profile.has_value(); } /// ensure the layer is up-to-date - void update(); + /// @return true if the configuration was updated + bool update(); /// modify instance create info /// @param createInfo original create info