From f3545f5eae047c8c12b1cceef91e359d6b576d1f Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Mon, 23 Dec 2024 23:26:47 -0600 Subject: [PATCH] UI: Auto graphics backend --- .../Configuration/GraphicsBackend.cs | 1 + src/Ryujinx/Assets/locales.json | 48 +++++++++++++++++++ src/Ryujinx/UI/Renderer/RendererHost.axaml.cs | 42 +++++++++++++++- .../UI/ViewModels/MainWindowViewModel.cs | 2 +- .../UI/ViewModels/SettingsViewModel.cs | 5 +- .../Views/Settings/SettingsGraphicsView.axaml | 3 ++ 6 files changed, 97 insertions(+), 4 deletions(-) diff --git a/src/Ryujinx.Common/Configuration/GraphicsBackend.cs b/src/Ryujinx.Common/Configuration/GraphicsBackend.cs index ba68fefbe..9d399d560 100644 --- a/src/Ryujinx.Common/Configuration/GraphicsBackend.cs +++ b/src/Ryujinx.Common/Configuration/GraphicsBackend.cs @@ -6,6 +6,7 @@ namespace Ryujinx.Common.Configuration [JsonConverter(typeof(TypedStringEnumConverter))] public enum GraphicsBackend { + Auto, Vulkan, OpenGl, Metal diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index 2e86df0aa..cdf43f474 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -19677,6 +19677,54 @@ "zh_TW": "選擇模擬器將使用的圖形後端。\n\n只要驅動程式是最新的,Vulkan 對所有現代顯示卡來說都更好用。Vulkan 還能在所有 GPU 廠商上實現更快的著色器編譯 (減少卡頓)。\n\nOpenGL 在舊式 Nvidia GPU、Linux 上的舊式 AMD GPU 或 VRAM 較低的 GPU 上可能會取得更好的效果,不過著色器編譯的卡頓會更嚴重。\n\n如果不確定,請設定為 Vulkan。如果您的 GPU 使用最新的圖形驅動程式也不支援 Vulkan,請設定為 OpenGL。" } }, + { + "ID": "SettingsTabGraphicsBackendAuto", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Auto", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, + { + "ID": "SettingsTabGraphicsBackendAutoTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Uses Vulkan.\nOn an ARM Mac, and when playing a game that runs well under it, uses the Metal backend.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "SettingsEnableTextureRecompression", "Translations": { diff --git a/src/Ryujinx/UI/Renderer/RendererHost.axaml.cs b/src/Ryujinx/UI/Renderer/RendererHost.axaml.cs index 7009a9377..58eba063c 100644 --- a/src/Ryujinx/UI/Renderer/RendererHost.axaml.cs +++ b/src/Ryujinx/UI/Renderer/RendererHost.axaml.cs @@ -1,8 +1,10 @@ using Avalonia; using Avalonia.Controls; +using Gommon; using Ryujinx.Common.Configuration; using Ryujinx.UI.Common.Configuration; using System; +using System.Runtime.InteropServices; namespace Ryujinx.Ava.UI.Renderer { @@ -21,13 +23,51 @@ namespace Ryujinx.Ava.UI.Renderer { GraphicsBackend.OpenGl => new EmbeddedWindowOpenGL(), GraphicsBackend.Metal => new EmbeddedWindowMetal(), - GraphicsBackend.Vulkan => new EmbeddedWindowVulkan(), + GraphicsBackend.Vulkan or GraphicsBackend.Auto => new EmbeddedWindowVulkan(), _ => throw new NotSupportedException() }; Initialize(); } + private readonly string[] _knownGreatMetalTitles = + [ + "01006A800016E000", // Smash Ultimate + "0100000000010000", // Super Mario Odyessy + "01008C0016544000", // Sea of Stars + "01005CA01580E000", // Persona 5 + "010028600EBDA000", // Mario 3D World + ]; + + public RendererHost(string titleId) + { + InitializeComponent(); + + switch (ConfigurationState.Instance.Graphics.GraphicsBackend.Value) + { + case GraphicsBackend.Auto: + EmbeddedWindow = + OperatingSystem.IsMacOS() && + RuntimeInformation.ProcessArchitecture == Architecture.Arm64 && + _knownGreatMetalTitles.ContainsIgnoreCase(titleId) + ? new EmbeddedWindowMetal() + : new EmbeddedWindowVulkan(); + break; + case GraphicsBackend.OpenGl: + EmbeddedWindow = new EmbeddedWindowOpenGL(); + break; + case GraphicsBackend.Metal: + EmbeddedWindow = new EmbeddedWindowMetal(); + break; + case GraphicsBackend.Vulkan: + EmbeddedWindow = new EmbeddedWindowVulkan(); + break; + } + + Initialize(); + } + + private void Initialize() { EmbeddedWindow.WindowCreated += CurrentWindow_WindowCreated; diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index ae373c267..f7cd83ed6 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -1938,7 +1938,7 @@ namespace Ryujinx.Ava.UI.ViewModels PrepareLoadScreen(); - RendererHostControl = new RendererHost(); + RendererHostControl = new RendererHost(application.Id.ToString("X16")); AppHost = new AppHost( RendererHostControl, diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 0ee1c9def..85ba203f9 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -252,7 +252,8 @@ namespace Ryujinx.Ava.UI.ViewModels public bool IsCustomResolutionScaleActive => _resolutionScale == 4; public bool IsScalingFilterActive => _scalingFilter == (int)Ryujinx.Common.Configuration.ScalingFilter.Fsr; - public bool IsVulkanSelected => GraphicsBackendIndex == 0; + public bool IsVulkanSelected => + GraphicsBackendIndex == 1 || (GraphicsBackendIndex == 0 && !OperatingSystem.IsMacOS()); public bool UseHypervisor { get; set; } public bool DisableP2P { get; set; } @@ -432,7 +433,7 @@ namespace Ryujinx.Ava.UI.ViewModels if (devices.Length == 0) { IsVulkanAvailable = false; - GraphicsBackendIndex = 1; + GraphicsBackendIndex = 2; } else { diff --git a/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml index c3693ac5f..a2559f393 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml @@ -39,6 +39,9 @@ HorizontalContentAlignment="Left" ToolTip.Tip="{ext:Locale SettingsTabGraphicsBackendTooltip}" SelectedIndex="{Binding GraphicsBackendIndex}"> + + +