From 44dcc2b7d0fe9027c064c50ebd5fecd8a2a409ee Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Thu, 25 Dec 2025 05:55:54 +0100 Subject: [PATCH] feat: mangohud integration --- CMakeLists.txt | 4 ++++ lsfg-vk-layer/src/swapchain.cpp | 34 +++++++++++++++++++++++++++++++++ lsfg-vk-layer/src/swapchain.hpp | 8 ++++++++ 3 files changed, 46 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c0b7f95..7b5a6b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ option(LSFGVK_BUILD_CLI "Build the command line interface" ON) option(LSFGVK_INSTALL_DEVELOP "Install development libraries and headers" OFF) option(LSFGVK_INSTALL_XDG_FILES "Install the application icon and desktop files" OFF) set(LSFGVK_LAYER_LIBRARY_PATH liblsfg-vk-layer.so CACHE STRING "Change where Vulkan searches for the layer library") +option(LSFGVK_LAYER_MANGOHUD "Enable MangoHud support in the Vulkan layer" ON) option(LSFGVK_TESTING_RENDERDOC "Enable RenderDoc integration for testing purposes" OFF) # === READ HERE FOR BUILD OPTIONS === @@ -44,6 +45,9 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") endif() endif() +if(LSFGVK_LAYER_MANGOHUD) + add_compile_definitions(LSFGVK_LAYER_MANGOHUD) +endif() if(LSFGVK_TESTING_RENDERDOC) add_compile_definitions(LSFGVK_TESTING_RENDERDOC) endif() diff --git a/lsfg-vk-layer/src/swapchain.cpp b/lsfg-vk-layer/src/swapchain.cpp index 1c50226..f5bf754 100644 --- a/lsfg-vk-layer/src/swapchain.cpp +++ b/lsfg-vk-layer/src/swapchain.cpp @@ -21,10 +21,15 @@ #include +#ifdef LSFGVK_LAYER_MANGOHUD +#include +#endif + using namespace lsfgvk; using namespace lsfgvk::layer; namespace { + /// helper to create an image memory barrier VkImageMemoryBarrier barrierHelper(VkImage handle, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, @@ -48,6 +53,21 @@ namespace { } }; } +#ifdef LSFGVK_LAYER_MANGOHUD + /// load MangoHud integration + PFN_MangoHud_notify loadMangoHudIntegration() { + void* module = dlopen("libMangoHud.so", RTLD_NOW | RTLD_NOLOAD); + if (!module) + return nullptr; + + auto func = reinterpret_cast( + dlsym(module, "notify_extra_frame")); + if (!func) + return nullptr; + + return func; + } +#endif } void layer::context_ModifySwapchainCreateInfo(const ls::GameConf& profile, uint32_t maxImages, @@ -124,6 +144,10 @@ Swapchain::Swapchain(const vk::Vulkan& vk, backend::Instance& backend, vk::Semaphore(vk) ); } + +#ifdef LSFGVK_LAYER_MANGOHUD + this->mangohud_notify = loadMangoHudIntegration(); +#endif } VkResult Swapchain::present(const vk::Vulkan& vk, @@ -281,6 +305,11 @@ VkResult Swapchain::present(const vk::Vulkan& vk, if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) throw ls::vulkan_error(res, "vkQueuePresentKHR() failed"); +#ifdef LSFGVK_LAYER_MANGOHUD + if (this->mangohud_notify) + this->mangohud_notify(this->fidx, swapchain, true); +#endif + this->idx++; } @@ -298,6 +327,11 @@ VkResult Swapchain::present(const vk::Vulkan& vk, if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) throw ls::vulkan_error(res, "vkQueuePresentKHR() failed"); +#ifdef LSFGVK_LAYER_MANGOHUD + if (this->mangohud_notify) + this->mangohud_notify(this->fidx, swapchain, false); +#endif + this->fidx++; return res; } diff --git a/lsfg-vk-layer/src/swapchain.hpp b/lsfg-vk-layer/src/swapchain.hpp index 3c711a0..b510119 100644 --- a/lsfg-vk-layer/src/swapchain.hpp +++ b/lsfg-vk-layer/src/swapchain.hpp @@ -36,6 +36,10 @@ namespace lsfgvk::layer { void context_ModifySwapchainCreateInfo(const ls::GameConf& profile, uint32_t maxImages, VkSwapchainCreateInfoKHR& createInfo); +#ifdef LSFGVK_LAYER_MANGOHUD + using PFN_MangoHud_notify = void(*)(uint64_t, VkSwapchainKHR, bool); +#endif + /// swapchain context for a layer instance class Swapchain { public: @@ -79,6 +83,10 @@ namespace lsfgvk::layer { ls::GameConf profile; SwapchainInfo info; + +#ifdef LSFGVK_LAYER_MANGOHUD + PFN_MangoHud_notify mangohud_notify{nullptr}; +#endif }; }