aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjcm <john.moody@coloradocollege.edu>2023-08-07 11:54:05 -0600
committerGitHub <noreply@github.com>2023-08-07 18:54:05 +0100
commit773e239db7ceb2c55aa15f9787add4430edcdfcf (patch)
treee2c712bc0bda2058a1d68e0b6158293a07f012ae
parent42750a74f82ee69cabfaf3c5497af6a8ebc13eca (diff)
Implement color space passthrough option (#5531)1.1.977
Co-authored-by: jcm <butt@butts.com>
-rw-r--r--.editorconfig7
-rw-r--r--src/Ryujinx.Ava/AppHost.cs8
-rw-r--r--src/Ryujinx.Ava/Assets/Locales/en_US.json2
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs3
-rw-r--r--src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml4
-rw-r--r--src/Ryujinx.Graphics.GAL/IWindow.cs1
-rw-r--r--src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs2
-rw-r--r--src/Ryujinx.Graphics.Gpu/GraphicsConfig.cs5
-rw-r--r--src/Ryujinx.Graphics.OpenGL/Window.cs2
-rw-r--r--src/Ryujinx.Graphics.Vulkan/Window.cs49
-rw-r--r--src/Ryujinx.Graphics.Vulkan/WindowBase.cs1
-rw-r--r--src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs7
-rw-r--r--src/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs19
13 files changed, 97 insertions, 13 deletions
diff --git a/.editorconfig b/.editorconfig
index e5a5e617..9d695c7f 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -14,6 +14,13 @@ tab_width = 4
end_of_line = lf
insert_final_newline = true
+# JSON files
+[*.json]
+
+# Indentation and spacing
+indent_size = 2
+tab_width = 2
+
# C# files
[*.cs]
diff --git a/src/Ryujinx.Ava/AppHost.cs b/src/Ryujinx.Ava/AppHost.cs
index 7c1ce542..786b4507 100644
--- a/src/Ryujinx.Ava/AppHost.cs
+++ b/src/Ryujinx.Ava/AppHost.cs
@@ -186,6 +186,7 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Graphics.AntiAliasing.Event += UpdateAntiAliasing;
ConfigurationState.Instance.Graphics.ScalingFilter.Event += UpdateScalingFilter;
ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event += UpdateScalingFilterLevel;
+ ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Event += UpdateColorSpacePassthrough;
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState;
@@ -229,6 +230,11 @@ namespace Ryujinx.Ava
_renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value);
}
+ private void UpdateColorSpacePassthrough(object sender, ReactiveEventArgs<bool> e)
+ {
+ _renderer.Window?.SetColorSpacePassthrough((bool)ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value);
+ }
+
private void ShowCursor()
{
Dispatcher.UIThread.Post(() =>
@@ -461,6 +467,7 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Graphics.ScalingFilter.Event -= UpdateScalingFilter;
ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event -= UpdateScalingFilterLevel;
ConfigurationState.Instance.Graphics.AntiAliasing.Event -= UpdateAntiAliasing;
+ ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Event -= UpdateColorSpacePassthrough;
_topLevel.PointerMoved -= TopLevel_PointerEnterOrMoved;
_topLevel.PointerEnter -= TopLevel_PointerEnterOrMoved;
@@ -887,6 +894,7 @@ namespace Ryujinx.Ava
_renderer?.Window?.SetAntiAliasing((Graphics.GAL.AntiAliasing)ConfigurationState.Instance.Graphics.AntiAliasing.Value);
_renderer?.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value);
_renderer?.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value);
+ _renderer?.Window?.SetColorSpacePassthrough(ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value);
Width = (int)RendererHost.Bounds.Width;
Height = (int)RendererHost.Bounds.Height;
diff --git a/src/Ryujinx.Ava/Assets/Locales/en_US.json b/src/Ryujinx.Ava/Assets/Locales/en_US.json
index 4065a1df..efd3187a 100644
--- a/src/Ryujinx.Ava/Assets/Locales/en_US.json
+++ b/src/Ryujinx.Ava/Assets/Locales/en_US.json
@@ -620,6 +620,8 @@
"SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:",
"SettingsEnableMacroHLE": "Enable Macro HLE",
"SettingsEnableMacroHLETooltip": "High-level emulation of GPU Macro code.\n\nImproves performance, but may cause graphical glitches in some games.\n\nLeave ON if unsure.",
+ "SettingsEnableColorSpacePassthrough": "Color Space Passthrough",
+ "SettingsEnableColorSpacePassthroughTooltip": "Directs the Vulkan backend to pass through color information without specifying a color space. For users with wide gamut displays, this may result in more vibrant colors, at the cost of color correctness.",
"VolumeShort": "Vol",
"UserProfilesManageSaves": "Manage Saves",
"DeleteUserSave": "Do you want to delete user save for this game?",
diff --git a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
index a9eb9c61..1e6d2734 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
@@ -145,6 +145,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableShaderCache { get; set; }
public bool EnableTextureRecompression { get; set; }
public bool EnableMacroHLE { get; set; }
+ public bool EnableColorSpacePassthrough { get; set; }
public bool EnableFileLog { get; set; }
public bool EnableStub { get; set; }
public bool EnableInfo { get; set; }
@@ -419,6 +420,7 @@ namespace Ryujinx.Ava.UI.ViewModels
EnableShaderCache = config.Graphics.EnableShaderCache;
EnableTextureRecompression = config.Graphics.EnableTextureRecompression;
EnableMacroHLE = config.Graphics.EnableMacroHLE;
+ EnableColorSpacePassthrough = config.Graphics.EnableColorSpacePassthrough;
ResolutionScale = config.Graphics.ResScale == -1 ? 4 : config.Graphics.ResScale - 1;
CustomResolutionScale = config.Graphics.ResScaleCustom;
MaxAnisotropy = config.Graphics.MaxAnisotropy == -1 ? 0 : (int)(MathF.Log2(config.Graphics.MaxAnisotropy));
@@ -506,6 +508,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.Graphics.EnableShaderCache.Value = EnableShaderCache;
config.Graphics.EnableTextureRecompression.Value = EnableTextureRecompression;
config.Graphics.EnableMacroHLE.Value = EnableMacroHLE;
+ config.Graphics.EnableColorSpacePassthrough.Value = EnableColorSpacePassthrough;
config.Graphics.ResScale.Value = ResolutionScale == 4 ? -1 : ResolutionScale + 1;
config.Graphics.ResScaleCustom.Value = CustomResolutionScale;
config.Graphics.MaxAnisotropy.Value = MaxAnisotropy == 0 ? -1 : MathF.Pow(2, MaxAnisotropy);
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
index 8e4122f3..670de69c 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
@@ -73,6 +73,10 @@
ToolTip.Tip="{locale:Locale SettingsEnableMacroHLETooltip}">
<TextBlock Text="{locale:Locale SettingsEnableMacroHLE}" />
</CheckBox>
+ <CheckBox IsChecked="{Binding EnableColorSpacePassthrough}"
+ ToolTip.Tip="{locale:Locale SettingsEnableColorSpacePassthroughTooltip}">
+ <TextBlock Text="{locale:Locale SettingsEnableColorSpacePassthrough}" />
+ </CheckBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
diff --git a/src/Ryujinx.Graphics.GAL/IWindow.cs b/src/Ryujinx.Graphics.GAL/IWindow.cs
index 1221d685..83418e70 100644
--- a/src/Ryujinx.Graphics.GAL/IWindow.cs
+++ b/src/Ryujinx.Graphics.GAL/IWindow.cs
@@ -13,5 +13,6 @@ namespace Ryujinx.Graphics.GAL
void SetAntiAliasing(AntiAliasing antialiasing);
void SetScalingFilter(ScalingFilter type);
void SetScalingFilterLevel(float level);
+ void SetColorSpacePassthrough(bool colorSpacePassThroughEnabled);
}
}
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
index 3c4d5414..4f1b795a 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
@@ -38,5 +38,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
public void SetScalingFilter(ScalingFilter type) { }
public void SetScalingFilterLevel(float level) { }
+
+ public void SetColorSpacePassthrough(bool colorSpacePassthroughEnabled) { }
}
}
diff --git a/src/Ryujinx.Graphics.Gpu/GraphicsConfig.cs b/src/Ryujinx.Graphics.Gpu/GraphicsConfig.cs
index 4dfb9338..fbb7399c 100644
--- a/src/Ryujinx.Graphics.Gpu/GraphicsConfig.cs
+++ b/src/Ryujinx.Graphics.Gpu/GraphicsConfig.cs
@@ -67,6 +67,11 @@ namespace Ryujinx.Graphics.Gpu
/// Enables or disables recompression of compressed textures that are not natively supported by the host.
/// </summary>
public static bool EnableTextureRecompression = false;
+
+ /// <summary>
+ /// Enables or disables color space passthrough, if available.
+ /// </summary>
+ public static bool EnableColorSpacePassthrough = false;
}
#pragma warning restore CA2211
}
diff --git a/src/Ryujinx.Graphics.OpenGL/Window.cs b/src/Ryujinx.Graphics.OpenGL/Window.cs
index a8e6031b..6bcfefa4 100644
--- a/src/Ryujinx.Graphics.OpenGL/Window.cs
+++ b/src/Ryujinx.Graphics.OpenGL/Window.cs
@@ -307,6 +307,8 @@ namespace Ryujinx.Graphics.OpenGL
_updateScalingFilter = true;
}
+ public void SetColorSpacePassthrough(bool colorSpacePassthroughEnabled) { }
+
private void UpdateEffect()
{
if (_updateEffect)
diff --git a/src/Ryujinx.Graphics.Vulkan/Window.cs b/src/Ryujinx.Graphics.Vulkan/Window.cs
index 6027962c..2d0ad664 100644
--- a/src/Ryujinx.Graphics.Vulkan/Window.cs
+++ b/src/Ryujinx.Graphics.Vulkan/Window.cs
@@ -28,7 +28,7 @@ namespace Ryujinx.Graphics.Vulkan
private int _width;
private int _height;
private bool _vsyncEnabled;
- private bool _vsyncModeChanged;
+ private bool _swapchainIsDirty;
private VkFormat _format;
private AntiAliasing _currentAntiAliasing;
private bool _updateEffect;
@@ -38,6 +38,7 @@ namespace Ryujinx.Graphics.Vulkan
private float _scalingFilterLevel;
private bool _updateScalingFilter;
private ScalingFilter _currentScalingFilter;
+ private bool _colorSpacePassthroughEnabled;
public unsafe Window(VulkanRenderer gd, SurfaceKHR surface, PhysicalDevice physicalDevice, Device device)
{
@@ -60,7 +61,7 @@ namespace Ryujinx.Graphics.Vulkan
private void RecreateSwapchain()
{
var oldSwapchain = _swapchain;
- _vsyncModeChanged = false;
+ _swapchainIsDirty = false;
for (int i = 0; i < _swapchainImageViews.Length; i++)
{
@@ -106,7 +107,7 @@ namespace Ryujinx.Graphics.Vulkan
imageCount = capabilities.MaxImageCount;
}
- var surfaceFormat = ChooseSwapSurfaceFormat(surfaceFormats);
+ var surfaceFormat = ChooseSwapSurfaceFormat(surfaceFormats, _colorSpacePassthroughEnabled);
var extent = ChooseSwapExtent(capabilities);
@@ -178,22 +179,40 @@ namespace Ryujinx.Graphics.Vulkan
return new Auto<DisposableImageView>(new DisposableImageView(_gd.Api, _device, imageView));
}
- private static SurfaceFormatKHR ChooseSwapSurfaceFormat(SurfaceFormatKHR[] availableFormats)
+ private static SurfaceFormatKHR ChooseSwapSurfaceFormat(SurfaceFormatKHR[] availableFormats, bool colorSpacePassthroughEnabled)
{
if (availableFormats.Length == 1 && availableFormats[0].Format == VkFormat.Undefined)
{
return new SurfaceFormatKHR(VkFormat.B8G8R8A8Unorm, ColorSpaceKHR.PaceSrgbNonlinearKhr);
}
-
- foreach (var format in availableFormats)
+ var formatToReturn = availableFormats[0];
+ if (colorSpacePassthroughEnabled)
{
- if (format.Format == VkFormat.B8G8R8A8Unorm && format.ColorSpace == ColorSpaceKHR.PaceSrgbNonlinearKhr)
+ foreach (var format in availableFormats)
{
- return format;
+ if (format.Format == VkFormat.B8G8R8A8Unorm && format.ColorSpace == ColorSpaceKHR.SpacePassThroughExt)
+ {
+ formatToReturn = format;
+ break;
+ }
+ else if (format.Format == VkFormat.B8G8R8A8Unorm && format.ColorSpace == ColorSpaceKHR.PaceSrgbNonlinearKhr)
+ {
+ formatToReturn = format;
+ }
}
}
-
- return availableFormats[0];
+ else
+ {
+ foreach (var format in availableFormats)
+ {
+ if (format.Format == VkFormat.B8G8R8A8Unorm && format.ColorSpace == ColorSpaceKHR.PaceSrgbNonlinearKhr)
+ {
+ formatToReturn = format;
+ break;
+ }
+ }
+ }
+ return formatToReturn;
}
private static CompositeAlphaFlagsKHR ChooseCompositeAlpha(CompositeAlphaFlagsKHR supportedFlags)
@@ -259,7 +278,7 @@ namespace Ryujinx.Graphics.Vulkan
if (acquireResult == Result.ErrorOutOfDateKhr ||
acquireResult == Result.SuboptimalKhr ||
- _vsyncModeChanged)
+ _swapchainIsDirty)
{
RecreateSwapchain();
}
@@ -443,6 +462,12 @@ namespace Ryujinx.Graphics.Vulkan
_updateScalingFilter = true;
}
+ public override void SetColorSpacePassthrough(bool colorSpacePassthroughEnabled)
+ {
+ _colorSpacePassthroughEnabled = colorSpacePassthroughEnabled;
+ _swapchainIsDirty = true;
+ }
+
private void UpdateEffect()
{
if (_updateEffect)
@@ -559,7 +584,7 @@ namespace Ryujinx.Graphics.Vulkan
public override void ChangeVSyncMode(bool vsyncEnabled)
{
_vsyncEnabled = vsyncEnabled;
- _vsyncModeChanged = true;
+ _swapchainIsDirty = true;
}
protected virtual void Dispose(bool disposing)
diff --git a/src/Ryujinx.Graphics.Vulkan/WindowBase.cs b/src/Ryujinx.Graphics.Vulkan/WindowBase.cs
index 146cf660..da1613f4 100644
--- a/src/Ryujinx.Graphics.Vulkan/WindowBase.cs
+++ b/src/Ryujinx.Graphics.Vulkan/WindowBase.cs
@@ -14,5 +14,6 @@ namespace Ryujinx.Graphics.Vulkan
public abstract void SetAntiAliasing(AntiAliasing effect);
public abstract void SetScalingFilter(ScalingFilter scalerType);
public abstract void SetScalingFilterLevel(float scale);
+ public abstract void SetColorSpacePassthrough(bool colorSpacePassthroughEnabled);
}
}
diff --git a/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs
index 43489432..09e7f570 100644
--- a/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs
+++ b/src/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs
@@ -14,7 +14,7 @@ namespace Ryujinx.Ui.Common.Configuration
/// <summary>
/// The current version of the file format
/// </summary>
- public const int CurrentVersion = 47;
+ public const int CurrentVersion = 48;
/// <summary>
/// Version of the configuration file format
@@ -187,6 +187,11 @@ namespace Ryujinx.Ui.Common.Configuration
public bool EnableMacroHLE { get; set; }
/// <summary>
+ /// Enables or disables color space passthrough, if available.
+ /// </summary>
+ public bool EnableColorSpacePassthrough { get; set; }
+
+ /// <summary>
/// Enables or disables profiled translation cache persistency
/// </summary>
public bool EnablePtc { get; set; }
diff --git a/src/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs b/src/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs
index 7ab20e32..ee898354 100644
--- a/src/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs
+++ b/src/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs
@@ -486,6 +486,11 @@ namespace Ryujinx.Ui.Common.Configuration
public ReactiveObject<bool> EnableMacroHLE { get; private set; }
/// <summary>
+ /// Enables or disables color space passthrough, if available.
+ /// </summary>
+ public ReactiveObject<bool> EnableColorSpacePassthrough { get; private set; }
+
+ /// <summary>
/// Graphics backend
/// </summary>
public ReactiveObject<GraphicsBackend> GraphicsBackend { get; private set; }
@@ -535,6 +540,8 @@ namespace Ryujinx.Ui.Common.Configuration
PreferredGpu.Event += static (sender, e) => LogValueChange(e, nameof(PreferredGpu));
EnableMacroHLE = new ReactiveObject<bool>();
EnableMacroHLE.Event += static (sender, e) => LogValueChange(e, nameof(EnableMacroHLE));
+ EnableColorSpacePassthrough = new ReactiveObject<bool>();
+ EnableColorSpacePassthrough.Event += static (sender, e) => LogValueChange(e, nameof(EnableColorSpacePassthrough));
AntiAliasing = new ReactiveObject<AntiAliasing>();
AntiAliasing.Event += static (sender, e) => LogValueChange(e, nameof(AntiAliasing));
ScalingFilter = new ReactiveObject<ScalingFilter>();
@@ -667,6 +674,7 @@ namespace Ryujinx.Ui.Common.Configuration
EnableShaderCache = Graphics.EnableShaderCache,
EnableTextureRecompression = Graphics.EnableTextureRecompression,
EnableMacroHLE = Graphics.EnableMacroHLE,
+ EnableColorSpacePassthrough = Graphics.EnableColorSpacePassthrough,
EnablePtc = System.EnablePtc,
EnableInternetAccess = System.EnableInternetAccess,
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
@@ -772,6 +780,7 @@ namespace Ryujinx.Ui.Common.Configuration
Graphics.EnableShaderCache.Value = true;
Graphics.EnableTextureRecompression.Value = false;
Graphics.EnableMacroHLE.Value = true;
+ Graphics.EnableColorSpacePassthrough.Value = false;
Graphics.AntiAliasing.Value = AntiAliasing.None;
Graphics.ScalingFilter.Value = ScalingFilter.Bilinear;
Graphics.ScalingFilterLevel.Value = 80;
@@ -1391,6 +1400,15 @@ namespace Ryujinx.Ui.Common.Configuration
configurationFileUpdated = true;
}
+ if (configurationFileFormat.Version < 48)
+ {
+ Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 48.");
+
+ configurationFileFormat.EnableColorSpacePassthrough = false;
+
+ configurationFileUpdated = true;
+ }
+
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.ResScale.Value = configurationFileFormat.ResScale;
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
@@ -1426,6 +1444,7 @@ namespace Ryujinx.Ui.Common.Configuration
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
Graphics.EnableTextureRecompression.Value = configurationFileFormat.EnableTextureRecompression;
Graphics.EnableMacroHLE.Value = configurationFileFormat.EnableMacroHLE;
+ Graphics.EnableColorSpacePassthrough.Value = configurationFileFormat.EnableColorSpacePassthrough;
System.EnablePtc.Value = configurationFileFormat.EnablePtc;
System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess;
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;