From 514e7ae6a00811a0ee1f20dfc856f69404fd883c Mon Sep 17 00:00:00 2001 From: Jan200101 Date: Thu, 8 Dec 2022 23:09:14 +0100 Subject: [PATCH 1/3] fix: re-add LD_LIBARY_PATH to mangohud Upstream officially supports the use of $LIB/mangohud/ Signed-off-by: Jan200101 --- launcher/minecraft/MinecraftInstance.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index a3adb268..40d56444 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -483,8 +483,11 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment() if (settings()->get("EnableMangoHud").toBool() && APPLICATION->capabilities() & Application::SupportsMangoHud) { auto preload = env.value("LD_PRELOAD", "") + ":libMangoHud_dlsym.so:libMangoHud.so"; + // $LIB/mangohud is a supported lib path by upstream, do not remove + auto lib_path = env.value("LD_LIBRARY_PATH", "") + ":/usr/local/$LIB/mangohud/:/usr/$LIB/mangohud/"; env.insert("LD_PRELOAD", preload); + env.insert("LD_LIBRARY_PATH", lib_path); env.insert("MANGOHUD", "1"); } From 2c1e887c8d7331df6d93dadea7355c019da4185a Mon Sep 17 00:00:00 2001 From: Jan200101 Date: Sun, 11 Dec 2022 11:01:33 +0100 Subject: [PATCH 2/3] chore: replace naive mangohud detection with vulkan layer detection Signed-off-by: Jan200101 --- launcher/Application.cpp | 14 ++----- launcher/CMakeLists.txt | 9 ++++ launcher/MangoHud.cpp | 90 ++++++++++++++++++++++++++++++++++++++++ launcher/MangoHud.h | 27 ++++++++++++ 4 files changed, 129 insertions(+), 11 deletions(-) create mode 100644 launcher/MangoHud.cpp create mode 100644 launcher/MangoHud.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 4ba9eb9b..8447083c 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -125,6 +125,7 @@ #ifdef Q_OS_LINUX #include #include "gamemode_client.h" +#include "MangoHud.h" #endif @@ -1519,17 +1520,8 @@ void Application::updateCapabilities() if (gamemode_query_status() >= 0) m_capabilities |= SupportsGameMode; - { - void *dummy = dlopen("libMangoHud_dlsym.so", RTLD_LAZY); - // try normal variant as well - if (dummy == NULL) - dummy = dlopen("libMangoHud.so", RTLD_LAZY); - - if (dummy != NULL) { - dlclose(dummy); - m_capabilities |= SupportsMangoHud; - } - } + if (!MangoHud::getLibraryString().isEmpty()) + m_capabilities |= SupportsMangoHud; #endif } diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 3eb765dc..879c3157 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -90,6 +90,15 @@ set(CORE_SOURCES MMCTime.h MMCTime.cpp ) +if (UNIX AND NOT CYGWIN AND NOT APPLE) +set(CORE_SOURCES + ${CORE_SOURCES} + + # MangoHud + MangoHud.h + MangoHud.cpp + ) +endif() set(PATHMATCHER_SOURCES # Path matchers diff --git a/launcher/MangoHud.cpp b/launcher/MangoHud.cpp new file mode 100644 index 00000000..d635518e --- /dev/null +++ b/launcher/MangoHud.cpp @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PrismLauncher - Minecraft Launcher + * Copyright (C) 2022 Jan Drögehoff + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include "MangoHud.h" +#include "FileSystem.h" +#include "Json.h" + +namespace MangoHud { + +QString getLibraryString() +{ + /* + * Check for vulkan layers in this order: + * + * $VK_LAYER_PATH + * $XDG_DATA_DIRS (/usr/local/share/:/usr/share/) + * $XDG_DATA_HOME (~/.local/share) + * /etc + * $XDG_CONFIG_DIRS (/etc/xdg) + * $XDG_CONFIG_HOME (~/.config) + */ + + QStringList vkLayerList; + { + QString home = QDir::homePath(); + + QString vkLayerPath = qEnvironmentVariable("VK_LAYER_PATH"); + if (!vkLayerPath.isEmpty()) { + vkLayerList << vkLayerPath; + } + + QStringList xdgDataDirs = qEnvironmentVariable("XDG_DATA_DIRS", "/usr/local/share/:/usr/share/").split(QLatin1String(":")); + for (QString dir : xdgDataDirs) { + vkLayerList << FS::PathCombine(dir, "vulkan", "implicit_layer.d"); + } + + QString xdgDataHome = qEnvironmentVariable("XDG_DATA_HOME"); + if (xdgDataHome.isEmpty()) { + xdgDataHome = FS::PathCombine(home, ".local", "share"); + } + vkLayerList << FS::PathCombine(xdgDataHome, "vulkan", "implicit_layer.d"); + + vkLayerList << "/etc"; + + QStringList xdgConfigDirs = qEnvironmentVariable("XDG_CONFIG_DIRS", "/etc/xdg").split(QLatin1String(":")); + for (QString dir : xdgConfigDirs) { + vkLayerList << FS::PathCombine(dir, "vulkan", "implicit_layer.d"); + } + + QString xdgConfigHome = qEnvironmentVariable("XDG_CONFIG_HOME"); + if (xdgConfigHome.isEmpty()) { + xdgConfigHome = FS::PathCombine(home, ".config"); + } + vkLayerList << FS::PathCombine(xdgConfigHome, "vulkan", "implicit_layer.d"); + } + + for (QString vkLayer : vkLayerList) { + QString filePath = FS::PathCombine(vkLayer, "MangoHud.json"); + if (!QFile::exists(filePath)) + continue; + + auto conf = Json::requireDocument(filePath, vkLayer); + auto confObject = Json::requireObject(conf, vkLayer); + auto layer = Json::ensureObject(confObject, "layer"); + return Json::ensureString(layer, "library_path"); + } + + return QString(); +} +} // namespace MangoHud diff --git a/launcher/MangoHud.h b/launcher/MangoHud.h new file mode 100644 index 00000000..7b7c2849 --- /dev/null +++ b/launcher/MangoHud.h @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PrismLauncher - Minecraft Launcher + * Copyright (C) 2022 Jan Drögehoff + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +namespace MangoHud { + +QString getLibraryString(); +} From deb9c98630c8c2f2d59908b77dae1e58aad3021d Mon Sep 17 00:00:00 2001 From: Jan200101 Date: Sun, 11 Dec 2022 10:32:15 +0100 Subject: [PATCH 3/3] chore: replace naive mangohud preload with vklayer detection Signed-off-by: Jan200101 --- launcher/minecraft/MinecraftInstance.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 40d56444..1d37224a 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -88,6 +88,10 @@ #include "minecraft/gameoptions/GameOptions.h" #include "minecraft/update/FoldersTask.h" +#ifdef Q_OS_LINUX +#include "MangoHud.h" +#endif + #define IBUS "@im=ibus" // all of this because keeping things compatible with deprecated old settings @@ -482,12 +486,22 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment() #ifdef Q_OS_LINUX if (settings()->get("EnableMangoHud").toBool() && APPLICATION->capabilities() & Application::SupportsMangoHud) { - auto preload = env.value("LD_PRELOAD", "") + ":libMangoHud_dlsym.so:libMangoHud.so"; - // $LIB/mangohud is a supported lib path by upstream, do not remove - auto lib_path = env.value("LD_LIBRARY_PATH", "") + ":/usr/local/$LIB/mangohud/:/usr/$LIB/mangohud/"; - env.insert("LD_PRELOAD", preload); - env.insert("LD_LIBRARY_PATH", lib_path); + auto preloadList = env.value("LD_PRELOAD").split(QLatin1String(":")); + auto libPaths = env.value("LD_LIBRARY_PATH").split(QLatin1String(":")); + + auto mangoHudLibString = MangoHud::getLibraryString(); + if (!mangoHudLibString.isEmpty()) + { + QFileInfo mangoHudLib(mangoHudLibString); + + // dlsym variant is only needed for OpenGL and not included in the vulkan layer + preloadList << "libMangoHud_dlsym.so" << mangoHudLib.fileName(); + libPaths << mangoHudLib.absolutePath(); + } + + env.insert("LD_PRELOAD", preloadList.join(QLatin1String(":"))); + env.insert("LD_LIBRARY_PATH", libPaths.join(QLatin1String(":"))); env.insert("MANGOHUD", "1"); }