diff --git a/src/Ryujinx.Ava/Assets/Locales/en_US.json b/src/Ryujinx.Ava/Assets/Locales/en_US.json index 6f6f9c540..dde252750 100644 --- a/src/Ryujinx.Ava/Assets/Locales/en_US.json +++ b/src/Ryujinx.Ava/Assets/Locales/en_US.json @@ -141,7 +141,7 @@ "SettingsTabGraphics": "Graphics", "SettingsTabGraphicsAPI": "Graphics API", "SettingsTabGraphicsEnableShaderCache": "Enable Shader Cache", - "SettingsTabGraphicsEnableOGLSpirV": "Enable SPIR-V Shaders on OpenGL", + "SettingsTabGraphicsShadingLanguge": "Shading Language", "SettingsTabGraphicsAnisotropicFiltering": "Anisotropic Filtering:", "SettingsTabGraphicsAnisotropicFilteringAuto": "Auto", "SettingsTabGraphicsAnisotropicFiltering2x": "2x", @@ -470,7 +470,7 @@ "GraphicsBackendThreadingTooltip": "Executes graphics backend commands on a second thread.\n\nSpeeds up shader compilation, reduces stuttering, and improves performance on GPU drivers without multithreading support of their own. Slightly better performance on drivers with multithreading.\n\nSet to AUTO if unsure.", "GalThreadingTooltip": "Executes graphics backend commands on a second thread.\n\nSpeeds up shader compilation, reduces stuttering, and improves performance on GPU drivers without multithreading support of their own. Slightly better performance on drivers with multithreading.\n\nSet to AUTO if unsure.", "ShaderCacheToggleTooltip": "Saves a disk shader cache which reduces stuttering in subsequent runs.\n\nLeave ON if unsure.", - "OGLSpirVTooltip": "Saves shaders as SPIR-V.\n\nLeave OFF if unsure.", + "ShadingLanguageTooltip": "Use SPIR-V Shaders in OpenGL. GLSL on Vulkan not currently supported. Default for OpenGL is GLSL and Vulkan is SPIR-V.\n\nLeave Defaults if unsure.", "ResolutionScaleTooltip": "Resolution Scale applied to applicable render targets", "ResolutionScaleEntryTooltip": "Floating point resolution scale, such as 1.5. Non-integral scales are more likely to cause issues or crash.", "AnisotropyTooltip": "Level of Anisotropic Filtering (set to Auto to use the value requested by the game)", diff --git a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs index 217b0c10e..652ef350d 100644 --- a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs @@ -48,6 +48,7 @@ namespace Ryujinx.Ava.UI.ViewModels private readonly List _gpuIds = new(); private KeyboardHotkeys _keyboardHotkeys; private int _graphicsBackendIndex; + private int _shadinglanguageBackendIndex; private string _customThemePath; private int _scalingFilter; private int _scalingFilterLevel; @@ -144,7 +145,6 @@ namespace Ryujinx.Ava.UI.ViewModels public bool IgnoreMissingServices { get; set; } public bool ExpandDramSize { get; set; } public bool EnableShaderCache { get; set; } - public bool EnableOGLSpirV { get; set; } public bool EnableTextureRecompression { get; set; } public bool EnableMacroHLE { get; set; } public bool EnableColorSpacePassthrough { get; set; } @@ -166,6 +166,8 @@ namespace Ryujinx.Ava.UI.ViewModels public bool IsScalingFilterActive => _scalingFilter == (int)Ryujinx.Common.Configuration.ScalingFilter.Fsr; public bool IsVulkanSelected => GraphicsBackendIndex == 0; + public bool IsSpirVSelected => ShadingLangugeIndex == 0; + public bool IsOGSpirVAvialble => true; public bool UseHypervisor { get; set; } public string TimeZone { get; set; } @@ -217,6 +219,18 @@ namespace Ryujinx.Ava.UI.ViewModels OnPropertyChanged(nameof(IsOpenGLSelected)); } } + + public int ShadingLangugeIndex + { + get => _shadinglanguageBackendIndex; + set + { + _shadinglanguageBackendIndex = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(IsOpenGLSelected)); + } + } + public bool IsOpenGLSelected => !IsVulkanSelected; @@ -252,6 +266,7 @@ namespace Ryujinx.Ava.UI.ViewModels internal AvaloniaList TimeZones { get; set; } public AvaloniaList GameDirectories { get; set; } public ObservableCollection AvailableGpus { get; set; } + //public ObservableCollection ShadingLanguage { get; set; } public AvaloniaList NetworkInterfaceList { @@ -309,6 +324,7 @@ namespace Ryujinx.Ava.UI.ViewModels GameDirectories = new AvaloniaList(); TimeZones = new AvaloniaList(); AvailableGpus = new ObservableCollection(); + //ShadingLanguage = new ObservableCollection(); _validTzRegions = new List(); _networkInterfaces = new Dictionary(); @@ -346,6 +362,7 @@ namespace Ryujinx.Ava.UI.ViewModels { IsVulkanAvailable = false; GraphicsBackendIndex = 1; + ShadingLangugeIndex = 1; } else { @@ -465,9 +482,9 @@ namespace Ryujinx.Ava.UI.ViewModels // Graphics GraphicsBackendIndex = (int)config.Graphics.GraphicsBackend.Value; + ShadingLangugeIndex = (int)config.Graphics.ShadingLanguage.Value; // Physical devices are queried asynchronously hence the prefered index config value is loaded in LoadAvailableGpus(). EnableShaderCache = config.Graphics.EnableShaderCache; - EnableOGLSpirV = config.Graphics.EnableOGLSpirV; EnableTextureRecompression = config.Graphics.EnableTextureRecompression; EnableMacroHLE = config.Graphics.EnableMacroHLE; EnableColorSpacePassthrough = config.Graphics.EnableColorSpacePassthrough; @@ -555,9 +572,9 @@ namespace Ryujinx.Ava.UI.ViewModels // Graphics config.Graphics.GraphicsBackend.Value = (GraphicsBackend)GraphicsBackendIndex; + config.Graphics.ShadingLanguage.Value = (ShadingLanguage)ShadingLangugeIndex; config.Graphics.PreferredGpu.Value = _gpuIds.ElementAtOrDefault(PreferredGpuIndex); config.Graphics.EnableShaderCache.Value = EnableShaderCache; - config.Graphics.EnableOGLSpirV.Value = EnableOGLSpirV; config.Graphics.EnableTextureRecompression.Value = EnableTextureRecompression; config.Graphics.EnableMacroHLE.Value = EnableMacroHLE; config.Graphics.EnableColorSpacePassthrough.Value = EnableColorSpacePassthrough; diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml index 629cdfc34..ae2edd9c7 100644 --- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml +++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml @@ -56,6 +56,23 @@ SelectedIndex="{Binding PreferredGpuIndex}" ItemsSource="{Binding AvailableGpus}"/> + + + + + + + + + + + @@ -65,10 +82,6 @@ ToolTip.Tip="{locale:Locale ShaderCacheToggleTooltip}"> - - - diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs index 6c35061e8..baa80ea7c 100644 --- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs @@ -424,7 +424,7 @@ namespace Ryujinx.Ava.UI.Windows GraphicsConfig.MaxAnisotropy = ConfigurationState.Instance.Graphics.MaxAnisotropy; GraphicsConfig.ShadersDumpPath = ConfigurationState.Instance.Graphics.ShadersDumpPath; GraphicsConfig.EnableShaderCache = ConfigurationState.Instance.Graphics.EnableShaderCache; - GraphicsConfig.EnableOGLSpirV = ConfigurationState.Instance.Graphics.EnableOGLSpirV; + GraphicsConfig.EnableOGLSpirV = ConfigurationState.Instance.Graphics.ShadingLanguage; GraphicsConfig.EnableTextureRecompression = ConfigurationState.Instance.Graphics.EnableTextureRecompression; GraphicsConfig.EnableMacroHLE = ConfigurationState.Instance.Graphics.EnableMacroHLE; #pragma warning restore IDE0055 diff --git a/src/Ryujinx.Common/Configuration/ShadingLanguage.cs b/src/Ryujinx.Common/Configuration/ShadingLanguage.cs new file mode 100644 index 000000000..01880b094 --- /dev/null +++ b/src/Ryujinx.Common/Configuration/ShadingLanguage.cs @@ -0,0 +1,12 @@ +using Ryujinx.Common.Utilities; +using System.Text.Json.Serialization; + +namespace Ryujinx.Common.Configuration +{ + [JsonConverter(typeof(TypedStringEnumConverter))] + public enum ShadingLanguage + { + SPIRV, + GLSL, + } +} diff --git a/src/Ryujinx.Graphics.Gpu/GraphicsConfig.cs b/src/Ryujinx.Graphics.Gpu/GraphicsConfig.cs index 4b52e235d..aaa86e23d 100644 --- a/src/Ryujinx.Graphics.Gpu/GraphicsConfig.cs +++ b/src/Ryujinx.Graphics.Gpu/GraphicsConfig.cs @@ -1,3 +1,5 @@ +using Ryujinx.Common.Configuration; + namespace Ryujinx.Graphics.Gpu { #pragma warning disable CA2211 // Non-constant fields should not be visible @@ -61,7 +63,7 @@ namespace Ryujinx.Graphics.Gpu /// /// Enables or disables Spir-V on OpenGL. /// - public static bool EnableOGLSpirV = false; + public static ShadingLanguage EnableOGLSpirV = ShadingLanguage.SPIRV; /// /// Enables or disables shader SPIR-V compilation. diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs index dd25dd0f8..ef39a4812 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs @@ -1,3 +1,4 @@ +using Ryujinx.Common.Configuration; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader.Translation; @@ -396,7 +397,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache IProgram hostProgram; - if (context.Capabilities.Api == TargetApi.Vulkan || GraphicsConfig.EnableOGLSpirV) + if (context.Capabilities.Api == TargetApi.Vulkan || (GraphicsConfig.EnableOGLSpirV == ShadingLanguage.SPIRV)) { ShaderSource[] shaderSources = ShaderBinarySerializer.Unpack(shaders, hostCode); diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs index 4f3f71fea..e768449f3 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs @@ -1,3 +1,4 @@ +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; @@ -504,7 +505,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache CachedShaderProgram program = new(hostProgram, compilation.SpecializationState, compilation.Shaders); // Vulkan's binary code is the SPIR-V used for compilation, so it is ready immediately. Other APIs get this after compilation. - byte[] binaryCode = (_context.Capabilities.Api == TargetApi.Vulkan || GraphicsConfig.EnableOGLSpirV) ? ShaderBinarySerializer.Pack(shaderSources) : null; + byte[] binaryCode = (_context.Capabilities.Api == TargetApi.Vulkan || (GraphicsConfig.EnableOGLSpirV == ShadingLanguage.SPIRV)) ? ShaderBinarySerializer.Pack(shaderSources) : null; EnqueueForValidation(new ProgramEntry(program, binaryCode, compilation.ProgramIndex, compilation.IsCompute, isBinary: false)); } diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 5cde588b5..f7d465b3b 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -560,7 +560,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { if (_diskCacheHostStorage.CacheEnabled) { - byte[] binaryCode = (_context.Capabilities.Api == TargetApi.Vulkan || GraphicsConfig.EnableOGLSpirV) ? ShaderBinarySerializer.Pack(sources) : null; + byte[] binaryCode = (_context.Capabilities.Api == TargetApi.Vulkan || (GraphicsConfig.EnableOGLSpirV == ShadingLanguage.SPIRV)) ? ShaderBinarySerializer.Pack(sources) : null; ProgramToSave programToSave = new(program, hostProgram, binaryCode); _programsToSaveQueue.Enqueue(programToSave); @@ -814,7 +814,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// Translation options private static TranslationOptions CreateTranslationOptions(TargetApi api, TranslationFlags flags) { - TargetLanguage lang = (GraphicsConfig.EnableSpirvCompilationOnVulkan && api == TargetApi.Vulkan) || (GraphicsConfig.EnableOGLSpirV && _isSpirVCapable) + TargetLanguage lang = (GraphicsConfig.EnableSpirvCompilationOnVulkan && api == TargetApi.Vulkan) || ((GraphicsConfig.EnableOGLSpirV == ShadingLanguage.SPIRV) && _isSpirVCapable) ? TargetLanguage.Spirv : TargetLanguage.Glsl; diff --git a/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs index 6a2da5208..6faba67b4 100644 --- a/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs +++ b/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs @@ -381,6 +381,11 @@ namespace Ryujinx.Ui.Common.Configuration /// public bool UseHypervisor { get; set; } + /// + /// Shading Languge + /// + public ShadingLanguage ShadingLanguge { get; set; } + /// /// Loads a configuration file from disk /// diff --git a/src/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs b/src/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs index 79ad7cf8c..a3821384a 100644 --- a/src/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs +++ b/src/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs @@ -501,6 +501,11 @@ namespace Ryujinx.Ui.Common.Configuration /// Graphics backend /// public ReactiveObject GraphicsBackend { get; private set; } + + /// + /// Graphics backend + /// + public ReactiveObject ShadingLanguage { get; private set; } /// /// Applies anti-aliasing to the renderer. @@ -545,6 +550,8 @@ namespace Ryujinx.Ui.Common.Configuration EnableTextureRecompression.Event += static (sender, e) => LogValueChange(e, nameof(EnableTextureRecompression)); GraphicsBackend = new ReactiveObject(); GraphicsBackend.Event += static (sender, e) => LogValueChange(e, nameof(GraphicsBackend)); + ShadingLanguage = new ReactiveObject(); + ShadingLanguage.Event += static (sender, e) => LogValueChange(e, nameof(ShadingLanguage)); PreferredGpu = new ReactiveObject(); PreferredGpu.Event += static (sender, e) => LogValueChange(e, nameof(PreferredGpu)); EnableMacroHLE = new ReactiveObject(); @@ -757,6 +764,7 @@ namespace Ryujinx.Ui.Common.Configuration InputConfig = Hid.InputConfig, GraphicsBackend = Graphics.GraphicsBackend, PreferredGpu = Graphics.PreferredGpu, + ShadingLanguge = Graphics.ShadingLanguage, MultiplayerLanInterfaceId = Multiplayer.LanInterfaceId, MultiplayerMode = Multiplayer.Mode, }; @@ -773,6 +781,7 @@ namespace Ryujinx.Ui.Common.Configuration Graphics.MaxAnisotropy.Value = -1.0f; Graphics.AspectRatio.Value = AspectRatio.Fixed16x9; Graphics.GraphicsBackend.Value = DefaultGraphicsBackend(); + Graphics.ShadingLanguage.Value = DefaultShadingLanguge(); Graphics.PreferredGpu.Value = ""; Graphics.ShadersDumpPath.Value = ""; Logger.EnableDebug.Value = false; @@ -1443,7 +1452,7 @@ namespace Ryujinx.Ui.Common.Configuration { Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 49."); - configurationFileFormat.EnableOGLSpirV = false; + configurationFileFormat.ShadingLanguge = ShadingLanguage.SPIRV; configurationFileUpdated = true; } @@ -1457,6 +1466,7 @@ namespace Ryujinx.Ui.Common.Configuration Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading; Graphics.GraphicsBackend.Value = configurationFileFormat.GraphicsBackend; Graphics.PreferredGpu.Value = configurationFileFormat.PreferredGpu; + Graphics.ShadingLanguage.Value = configurationFileFormat.ShadingLanguge; Graphics.AntiAliasing.Value = configurationFileFormat.AntiAliasing; Graphics.ScalingFilter.Value = configurationFileFormat.ScalingFilter; Graphics.ScalingFilterLevel.Value = configurationFileFormat.ScalingFilterLevel; @@ -1562,6 +1572,18 @@ namespace Ryujinx.Ui.Common.Configuration return GraphicsBackend.OpenGl; } + + private static ShadingLanguage DefaultShadingLanguge() + { + // Any system running macOS or returning any amount of valid Vulkan devices should default to Vulkan. + // Checks for if the Vulkan version and featureset is compatible should be performed within VulkanRenderer. + if (DefaultGraphicsBackend() == GraphicsBackend.Vulkan) + { + return ShadingLanguage.SPIRV; + } + + return ShadingLanguage.GLSL; + } private static void LogValueChange(ReactiveEventArgs eventArgs, string valueName) { diff --git a/src/Ryujinx/Ui/MainWindow.cs b/src/Ryujinx/Ui/MainWindow.cs index 3d02690a7..d3f46d1f9 100644 --- a/src/Ryujinx/Ui/MainWindow.cs +++ b/src/Ryujinx/Ui/MainWindow.cs @@ -1111,7 +1111,7 @@ namespace Ryujinx.Ui Graphics.Gpu.GraphicsConfig.MaxAnisotropy = ConfigurationState.Instance.Graphics.MaxAnisotropy; Graphics.Gpu.GraphicsConfig.ShadersDumpPath = ConfigurationState.Instance.Graphics.ShadersDumpPath; Graphics.Gpu.GraphicsConfig.EnableShaderCache = ConfigurationState.Instance.Graphics.EnableShaderCache; - Graphics.Gpu.GraphicsConfig.EnableOGLSpirV = ConfigurationState.Instance.Graphics.EnableOGLSpirV; + Graphics.Gpu.GraphicsConfig.EnableOGLSpirV = ConfigurationState.Instance.Graphics.ShadingLanguage; Graphics.Gpu.GraphicsConfig.EnableTextureRecompression = ConfigurationState.Instance.Graphics.EnableTextureRecompression; Graphics.Gpu.GraphicsConfig.EnableMacroHLE = ConfigurationState.Instance.Graphics.EnableMacroHLE; } diff --git a/src/Ryujinx/Ui/Windows/SettingsWindow.cs b/src/Ryujinx/Ui/Windows/SettingsWindow.cs index 283155ff7..e98a436e2 100644 --- a/src/Ryujinx/Ui/Windows/SettingsWindow.cs +++ b/src/Ryujinx/Ui/Windows/SettingsWindow.cs @@ -104,6 +104,7 @@ namespace Ryujinx.Ui.Windows [GUI] ComboBoxText _antiAliasing; [GUI] ComboBoxText _scalingFilter; [GUI] ComboBoxText _graphicsBackend; + [GUI] ComboBoxText _shadingLanguage; [GUI] ComboBoxText _preferredGpu; [GUI] ComboBoxText _resScaleCombo; [GUI] Entry _resScaleText; @@ -362,6 +363,7 @@ namespace Ryujinx.Ui.Windows _anisotropy.SetActiveId(ConfigurationState.Instance.Graphics.MaxAnisotropy.Value.ToString()); _aspectRatio.SetActiveId(((int)ConfigurationState.Instance.Graphics.AspectRatio.Value).ToString()); _graphicsBackend.SetActiveId(((int)ConfigurationState.Instance.Graphics.GraphicsBackend.Value).ToString()); + _shadingLanguage.SetActiveId(((int)ConfigurationState.Instance.Graphics.ShadingLanguage.Value).ToString()); _antiAliasing.SetActiveId(((int)ConfigurationState.Instance.Graphics.AntiAliasing.Value).ToString()); _scalingFilter.SetActiveId(((int)ConfigurationState.Instance.Graphics.ScalingFilter.Value).ToString()); @@ -658,6 +660,7 @@ namespace Ryujinx.Ui.Windows ConfigurationState.Instance.Graphics.AspectRatio.Value = Enum.Parse(_aspectRatio.ActiveId); ConfigurationState.Instance.Graphics.BackendThreading.Value = backendThreading; ConfigurationState.Instance.Graphics.GraphicsBackend.Value = Enum.Parse(_graphicsBackend.ActiveId); + ConfigurationState.Instance.Graphics.ShadingLanguage.Value = Enum.Parse(_shadingLanguage.ActiveId); ConfigurationState.Instance.Graphics.PreferredGpu.Value = _preferredGpu.ActiveId; ConfigurationState.Instance.Graphics.ResScale.Value = int.Parse(_resScaleCombo.ActiveId); ConfigurationState.Instance.Graphics.ResScaleCustom.Value = resScaleCustom; diff --git a/src/Ryujinx/Ui/Windows/SettingsWindow.glade b/src/Ryujinx/Ui/Windows/SettingsWindow.glade index 4b60fa793..7a9671a5c 100644 --- a/src/Ryujinx/Ui/Windows/SettingsWindow.glade +++ b/src/Ryujinx/Ui/Windows/SettingsWindow.glade @@ -2071,6 +2071,51 @@ 0 + + + True + False + 5 + 5 + + + True + False + Shading Language to use + Shading Language: + + + False + True + 5 + 0 + + + + + True + False + Shading Language to use + -1 + + SPIR-V + GLSL + + + + False + True + 1 + + + + + False + True + 5 + 1 + + True @@ -2122,24 +2167,6 @@ 0 - - - Enable SPIR-V Shader in OpenGL - True - True - False - Uses shaders in SPIR-V format. Leave OFF if unsure. - start - 5 - 5 - True - - - False - True - 1 - - Enable Texture Recompression @@ -2155,7 +2182,7 @@ False True - 2 + 1 @@ -2173,7 +2200,7 @@ False True - 3 + 2