From 7ff632fa004dec3186f631d49236a613732b1c88 Mon Sep 17 00:00:00 2001 From: loathingKernel <142770+loathingKernel@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:32:23 +0200 Subject: [PATCH] Settings: add configuration widget for DXVK_CONFIG env variable --- .../tabs/library/details/settings.py | 29 +++- rare/components/tabs/settings/settings.py | 21 ++- .../tabs/settings/widgets/env_vars_model.py | 1 + rare/components/tabs/settings/widgets/game.py | 15 +- .../tabs/settings/widgets/overlay.py | 135 ++++++++++++------ 5 files changed, 137 insertions(+), 64 deletions(-) diff --git a/rare/components/tabs/library/details/settings.py b/rare/components/tabs/library/details/settings.py index e1da4814e..6f04d54d3 100644 --- a/rare/components/tabs/library/details/settings.py +++ b/rare/components/tabs/library/details/settings.py @@ -11,7 +11,7 @@ from rare.components.tabs.settings.widgets.env_vars import EnvVars from rare.components.tabs.settings.widgets.game import GameSettingsBase from rare.components.tabs.settings.widgets.launch import LaunchSettingsBase -from rare.components.tabs.settings.widgets.overlay import DxvkSettings +from rare.components.tabs.settings.widgets.overlay import DxvkOverlaySettings, DxvkConfigSettings from rare.components.tabs.settings.widgets.wrappers import WrapperSettings from rare.models.game import RareGame from rare.utils import config_helper as config @@ -157,10 +157,13 @@ def load_settings(self, app_name: str): self.app_name = app_name -class GameDxvkSettings(DxvkSettings): +class GameDxvkOverlaySettings(DxvkOverlaySettings): def load_settings(self, app_name: str): self.app_name = app_name +class GameDxvkConfigSettings(DxvkConfigSettings): + def load_settings(self, app_name: str): + self.app_name = app_name class GameEnvVars(EnvVars): def load_settings(self, app_name): @@ -172,19 +175,30 @@ def __init__(self, parent=None): if pf.system() != "Windows": if pf.system() in {"Linux", "FreeBSD"}: super(GameSettings, self).__init__( - GameLaunchSettings, GameDxvkSettings, GameEnvVars, - GameWineSettings, GameProtonSettings, GameMangoHudSettings, + GameLaunchSettings, + GameDxvkOverlaySettings, + GameDxvkConfigSettings, + GameEnvVars, + GameWineSettings, + GameProtonSettings, + GameMangoHudSettings, parent=parent ) else: super(GameSettings, self).__init__( - GameLaunchSettings, GameDxvkSettings, GameEnvVars, + GameLaunchSettings, + GameDxvkOverlaySettings, + GameDxvkConfigSettings, + GameEnvVars, GameWineSettings, parent=parent ) else: super(GameSettings, self).__init__( - GameLaunchSettings, GameDxvkSettings, GameEnvVars, + GameLaunchSettings, + GameDxvkOverlaySettings, + GameDxvkConfigSettings, + GameEnvVars, parent=parent ) @@ -197,5 +211,6 @@ def load_settings(self, rgame: RareGame): if pf.system() in {"Linux", "FreeBSD"}: self.proton_tool.load_settings(rgame.app_name) self.mangohud.load_settings(rgame.app_name) - self.dxvk.load_settings(rgame.app_name) + self.dxvk_overlay.load_settings(rgame.app_name) + self.dxvk_config.load_settings(rgame.app_name) self.env_vars.load_settings(rgame.app_name) diff --git a/rare/components/tabs/settings/settings.py b/rare/components/tabs/settings/settings.py index 020f4eecd..463330e7c 100644 --- a/rare/components/tabs/settings/settings.py +++ b/rare/components/tabs/settings/settings.py @@ -4,7 +4,7 @@ from .widgets.env_vars import EnvVars from .widgets.game import GameSettingsBase from .widgets.launch import LaunchSettingsBase -from .widgets.overlay import DxvkSettings +from .widgets.overlay import DxvkOverlaySettings, DxvkConfigSettings from .widgets.wrappers import WrapperSettings if pf.system() != "Windows": @@ -26,18 +26,29 @@ def __init__(self, parent=None): if pf.system() != "Windows": if pf.system() in {"Linux", "FreeBSD"}: super(GameSettings, self).__init__( - LaunchSettings, DxvkSettings, EnvVars, - WineSettings, ProtonSettings, MangoHudSettings, + LaunchSettings, + DxvkOverlaySettings, + DxvkConfigSettings, + EnvVars, + WineSettings, + ProtonSettings, + MangoHudSettings, parent=parent ) else: super(GameSettings, self).__init__( - LaunchSettings, DxvkSettings, EnvVars, + LaunchSettings, + DxvkOverlaySettings, + DxvkConfigSettings, + EnvVars, WineSettings, parent=parent ) else: super(GameSettings, self).__init__( - LaunchSettings, DxvkSettings, EnvVars, + LaunchSettings, + DxvkOverlaySettings, + DxvkConfigSettings, + EnvVars, parent=parent ) diff --git a/rare/components/tabs/settings/widgets/env_vars_model.py b/rare/components/tabs/settings/widgets/env_vars_model.py index 8826fe37d..f63cc624a 100644 --- a/rare/components/tabs/settings/widgets/env_vars_model.py +++ b/rare/components/tabs/settings/widgets/env_vars_model.py @@ -30,6 +30,7 @@ def __init__(self, core: LegendaryCore, parent=None): self.__readonly = { "DXVK_HUD", + "DXVK_CONFIG", "MANGOHUD", "MANGOHUD_CONFIG", } diff --git a/rare/components/tabs/settings/widgets/game.py b/rare/components/tabs/settings/widgets/game.py index f3b28b17d..3fb939dc2 100644 --- a/rare/components/tabs/settings/widgets/game.py +++ b/rare/components/tabs/settings/widgets/game.py @@ -18,7 +18,7 @@ from rare.widgets.side_tab import SideTabContents from .env_vars import EnvVars from .launch import LaunchSettingsType -from .overlay import DxvkSettings +from .overlay import DxvkOverlaySettings, DxvkConfigSettings if pf.system() != "Windows": from .wine import WineSettings @@ -33,7 +33,8 @@ class GameSettingsBase(QWidget, SideTabContents): def __init__( self, launch_widget: Type[LaunchSettingsType], - dxvk_widget: Type[DxvkSettings], + dxvk_hud_widget: Type[DxvkOverlaySettings], + dxvk_config_widget: Type[DxvkConfigSettings], envvar_widget: Type[EnvVars], wine_widget: Type['WineSettings'] = None, proton_widget: Type['ProtonSettings'] = None, @@ -81,8 +82,11 @@ def __init__( # lambda: self.compat_stack.setCurrentIndex(self.compat_combo.currentData(Qt.ItemDataRole.UserRole)) # ) - self.dxvk = dxvk_widget(self) - self.dxvk.environ_changed.connect(self.env_vars.reset_model) + self.dxvk_overlay = dxvk_hud_widget(self) + self.dxvk_overlay.environ_changed.connect(self.env_vars.reset_model) + + self.dxvk_config = dxvk_config_widget(self) + self.dxvk_config.environ_changed.connect(self.env_vars.reset_model) if pf.system() in {"Linux", "FreeBSD"}: self.mangohud = mangohud_widget(self) @@ -92,7 +96,8 @@ def __init__( self.main_layout.addWidget(self.launch) if pf.system() != "Windows": self.main_layout.addWidget(self.compat) - self.main_layout.addWidget(self.dxvk) + self.main_layout.addWidget(self.dxvk_overlay) + self.main_layout.addWidget(self.dxvk_config) if pf.system() in {"Linux", "FreeBSD"}: self.main_layout.addWidget(self.mangohud) self.main_layout.addWidget(self.env_vars) diff --git a/rare/components/tabs/settings/widgets/overlay.py b/rare/components/tabs/settings/widgets/overlay.py index eccd3ec0f..77b38bf5f 100644 --- a/rare/components/tabs/settings/widgets/overlay.py +++ b/rare/components/tabs/settings/widgets/overlay.py @@ -5,7 +5,7 @@ from PySide6.QtCore import Signal, Qt from PySide6.QtGui import QIntValidator, QDoubleValidator, QShowEvent -from PySide6.QtWidgets import QGroupBox, QCheckBox, QLineEdit, QComboBox +from PySide6.QtWidgets import QGroupBox, QCheckBox, QLineEdit, QComboBox, QSpinBox from rare.ui.components.tabs.settings.widgets.overlay import Ui_OverlaySettings from rare.utils import config_helper as config @@ -123,9 +123,10 @@ def __init__(self, parent=None): self.ui.show_overlay_combo.addItem(self.tr("Enabled (defaults)"), ActivationStates.DEFAULTS) self.ui.show_overlay_combo.addItem(self.tr("Enabled (custom)"), ActivationStates.CUSTOM) - self.envvar: str = None - self.force_disabled: str = None - self.force_defaults: str = None + self.envvar: Union[str, None] = None + self.force_disabled: Union[str, None] = None + self.force_defaults: Union[str, None] = None + self.separator: Union[str, None] = None self.app_name: str = "default" self.option_widgets: List[Union[OverlayCheckBox, OverlayLineEdit, OverlayComboBox]] = [] @@ -142,10 +143,12 @@ def setupWidget( envvar: str, force_disabled: str, force_defaults: str, + separator: str, ): self.envvar = envvar self.force_disabled = force_disabled self.force_defaults = force_defaults + self.separator = separator for i, widget in enumerate(grid_map): widget.setParent(self.ui.options_group) @@ -185,7 +188,7 @@ def update_settings(self): # custom options options = (name for widget in self.option_widgets if (name := widget.getValue()) is not None) - config.set_envvar(self.app_name, self.envvar, ",".join(options)) + config.set_envvar(self.app_name, self.envvar, self.separator.join(options)) self.environ_changed.emit(self.envvar) self.update_settings_override(current_state) @@ -201,7 +204,7 @@ def showEvent(self, a0: QShowEvent): config_options = config.get_envvar(self.app_name, self.envvar, fallback=None) if config_options is None: - logger.debug("Overlay setting %s is not present", self.envvar) + logger.debug("Setting %s is not present", self.envvar) self.setCurrentState(ActivationStates.GLOBAL) elif config_options == self.force_disabled: @@ -213,7 +216,7 @@ def showEvent(self, a0: QShowEvent): else: self.setCurrentState(ActivationStates.CUSTOM) opts = {} - for o in config_options.split(","): + for o in config_options.split(self.separator): if "=" in o: k, v = o.split("=") opts[k] = v @@ -224,68 +227,97 @@ def showEvent(self, a0: QShowEvent): for widget in self.option_widgets: widget.setValue(opts) if opts: - logger.info("Remaining options without a gui switch: %s", ",".join(opts.keys())) + logger.info("Remaining options without a gui switch: %s", self.separator.join(opts.keys())) self.ui.options_group.blockSignals(False) return super().showEvent(a0) -class DxvkSettings(OverlaySettings): +class DxvkOverlaySettings(OverlaySettings): def __init__(self, parent=None): - super(DxvkSettings, self).__init__(parent=parent) + super(DxvkOverlaySettings, self).__init__(parent=parent) self.setTitle(self.tr("DXVK HUD")) grid = [ OverlayCheckBox("fps", self.tr("FPS")), - OverlayCheckBox("frametime", self.tr("Frametime")), + OverlayCheckBox("frametimes", self.tr("Frame time graph")), OverlayCheckBox("memory", self.tr("Memory usage")), + OverlayCheckBox("allocations", self.tr("Memory chunk suballocation")), OverlayCheckBox("gpuload", self.tr("GPU usage")), OverlayCheckBox("devinfo", self.tr("Device info")), OverlayCheckBox("version", self.tr("DXVK version")), OverlayCheckBox("api", self.tr("D3D feature level")), OverlayCheckBox("compiler", self.tr("Compiler activity")), + OverlayCheckBox("devinfo", self.tr("GPU driver and version")), + OverlayCheckBox("drawcalls", self.tr("Draw calls per frame")), ] form = [ - (OverlayNumberInput("scale", 1.0), self.tr("Scale")) + (OverlayNumberInput("scale", 1.0), self.tr("Scale")), + (OverlayNumberInput("opacity", 1.0), self.tr("Opacity")), + ] - self.setupWidget(grid, form, "DXVK_HUD", "0", "1") + self.setupWidget(grid, form, envvar="DXVK_HUD", force_disabled="0", force_defaults="1", separator=",") def update_settings_override(self, state: ActivationStates): pass -mangohud_position = ( - ("default", "default"), - ("top-left", "top-left"), - ("top-right", "top-right"), - ("middle-left", "middle-left"), - ("middle-right", "middle-right"), - ("bottom-left", "bottom-left"), - ("bottom-right", "bottom-right"), - ("top-center", "top-center"), -) - -mangohud_vsync = ( - ("config", None), - ("adaptive", "0"), - ("off", "1"), - ("mailbox", "2"), - ("on", "3"), -) - -mangohud_gl_vsync = ( - ("config", None), - ("off", "0"), - ("on", "1"), - ("half", "2"), - ("third", "3"), - ("quarter", "4"), -) +class DxvkConfigSettings(OverlaySettings): + def __init__(self, parent=None): + super(DxvkConfigSettings, self).__init__(parent=parent) + self.setTitle(self.tr("DXVK Config")) + dxvk_config_trinary = ( + ("Auto", "Auto"), + ("True", "True"), + ("False", "False") + ) + grid = [ + ] + form = [ + (OverlayLineEdit("dxvk.deviceFilter", "",), "dxvk.deviceFilter"), + (OverlayNumberInput("dxgi.syncInterval", -1,), "dxgi.syncInterval"), + (OverlayNumberInput("d3d9.presentInterval", -1, ), "d3d9.presentInterval"), + (OverlayNumberInput("dxgi.maxFrameRate", 0,), "dxgi.maxFrameRate"), + (OverlayNumberInput("d3d9.maxFrameRate", 0,), "d3d9.maxFrameRate"), + (OverlaySelectInput("dxvk.tearFree", dxvk_config_trinary), "dxvk.tearFree"), + + ] + self.setupWidget(grid, form, envvar="DXVK_CONFIG", force_disabled="0", force_defaults="", separator=";") + + def update_settings_override(self, state: ActivationStates): + pass class MangoHudSettings(OverlaySettings): def __init__(self, parent=None): super(MangoHudSettings, self).__init__(parent=parent) self.setTitle(self.tr("MangoHud")) + mangohud_position = ( + ("default", "default"), + ("top-left", "top-left"), + ("top-right", "top-right"), + ("middle-left", "middle-left"), + ("middle-right", "middle-right"), + ("bottom-left", "bottom-left"), + ("bottom-right", "bottom-right"), + ("top-center", "top-center"), + ) + + mangohud_vsync = ( + ("config", None), + ("adaptive", "0"), + ("off", "1"), + ("mailbox", "2"), + ("on", "3"), + ) + + mangohud_gl_vsync = ( + ("config", None), + ("off", "0"), + ("on", "1"), + ("half", "2"), + ("third", "3"), + ("quarter", "4"), + ) grid = [ OverlayCheckBox("read_cfg", self.tr("Read config")), OverlayCheckBox("fps", self.tr("FPS"), default_enabled=True), @@ -312,7 +344,7 @@ def __init__(self, parent=None): (OverlaySelectInput("position", mangohud_position), self.tr("Position")), ] - self.setupWidget(grid, form, "MANGOHUD_CONFIG", "no_display", "read_cfg") + self.setupWidget(grid, form, "MANGOHUD_CONFIG", "no_display", "read_cfg", separator=",") def showEvent(self, a0: QShowEvent): if a0.spontaneous(): @@ -339,21 +371,30 @@ def update_settings_override(self, state: IntEnum): # pylint: disable=E0202 if __name__ == "__main__": import sys + from argparse import Namespace from PySide6.QtWidgets import QApplication, QDialog, QVBoxLayout - from legendary.core import LegendaryCore - - core = LegendaryCore() - config.init_config_handler(core) + global config + config = Namespace() + def get_envvar(x, y, fallback): + return "" + config.get_envvar = get_envvar + config.set_option = lambda x, y, z: print(x, y, z) + config.set_envvar = lambda x, y, z: print(x, y, z) + config.remove_option = lambda x, y: print(x, y) + config.remove_envvar = lambda x, y: print(x, y) + config.save_config = lambda: print() app = QApplication(sys.argv) dlg = QDialog() - dxvk = DxvkSettings(dlg) + dxvk_hud = DxvkOverlaySettings(dlg) + dxvk_cfg = DxvkConfigSettings(dlg) mangohud = MangoHudSettings(dlg) layout = QVBoxLayout(dlg) - layout.addWidget(dxvk) + layout.addWidget(dxvk_hud) + layout.addWidget(dxvk_cfg) layout.addWidget(mangohud) dlg.show()