diff --git a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
index e4cd63d6..9123f044 100644
--- a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
+++ b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
@@ -19,10 +19,15 @@ namespace Ryujinx.Configuration
///
/// The current version of the file format
///
- public const int CurrentVersion = 3;
+ public const int CurrentVersion = 4;
public int Version { get; set; }
+ ///
+ /// Max Anisotropy. Values range from 0 - 16. Set to -1 to let the game decide.
+ ///
+ public float MaxAnisotropy { get; set; }
+
///
/// Dumps shaders in this local directory
///
diff --git a/Ryujinx.Common/Configuration/ConfigurationState.cs b/Ryujinx.Common/Configuration/ConfigurationState.cs
index e563008a..67628aa1 100644
--- a/Ryujinx.Common/Configuration/ConfigurationState.cs
+++ b/Ryujinx.Common/Configuration/ConfigurationState.cs
@@ -235,6 +235,11 @@ namespace Ryujinx.Configuration
///
public class GraphicsSection
{
+ ///
+ /// Max Anisotropy. Values range from 0 - 16. Set to -1 to let the game decide.
+ ///
+ public ReactiveObject MaxAnisotropy { get; private set; }
+
///
/// Dumps shaders in this local directory
///
@@ -247,6 +252,7 @@ namespace Ryujinx.Configuration
public GraphicsSection()
{
+ MaxAnisotropy = new ReactiveObject();
ShadersDumpPath = new ReactiveObject();
EnableVsync = new ReactiveObject();
}
@@ -302,6 +308,7 @@ namespace Ryujinx.Configuration
ConfigurationFileFormat configurationFile = new ConfigurationFileFormat
{
Version = ConfigurationFileFormat.CurrentVersion,
+ MaxAnisotropy = Graphics.MaxAnisotropy,
GraphicsShadersDumpPath = Graphics.ShadersDumpPath,
LoggingEnableDebug = Logger.EnableDebug,
LoggingEnableStub = Logger.EnableStub,
@@ -349,6 +356,7 @@ namespace Ryujinx.Configuration
public void LoadDefault()
{
+ Graphics.MaxAnisotropy.Value = -1;
Graphics.ShadersDumpPath.Value = "";
Logger.EnableDebug.Value = false;
Logger.EnableStub.Value = true;
@@ -487,6 +495,16 @@ namespace Ryujinx.Configuration
configurationFileUpdated = true;
}
+ if (configurationFileFormat.Version < 4)
+ {
+ Common.Logging.Logger.PrintWarning(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 4.");
+
+ configurationFileFormat.MaxAnisotropy = -1;
+
+ configurationFileUpdated = true;
+ }
+
+ Graphics.MaxAnisotropy.Value = configurationFileFormat.MaxAnisotropy;
Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath;
Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug;
Logger.EnableStub.Value = configurationFileFormat.LoggingEnableStub;
diff --git a/Ryujinx.Graphics.GAL/Capabilities.cs b/Ryujinx.Graphics.GAL/Capabilities.cs
index b75ceb94..8ea4c02a 100644
--- a/Ryujinx.Graphics.GAL/Capabilities.cs
+++ b/Ryujinx.Graphics.GAL/Capabilities.cs
@@ -8,16 +8,20 @@ namespace Ryujinx.Graphics.GAL
public int MaximumComputeSharedMemorySize { get; }
public int StorageBufferOffsetAlignment { get; }
+ public float MaxSupportedAnisotropy { get; }
+
public Capabilities(
- bool supportsAstcCompression,
- bool supportsNonConstantTextureOffset,
- int maximumComputeSharedMemorySize,
- int storageBufferOffsetAlignment)
+ bool supportsAstcCompression,
+ bool supportsNonConstantTextureOffset,
+ int maximumComputeSharedMemorySize,
+ int storageBufferOffsetAlignment,
+ float maxSupportedAnisotropy)
{
SupportsAstcCompression = supportsAstcCompression;
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize;
StorageBufferOffsetAlignment = storageBufferOffsetAlignment;
+ MaxSupportedAnisotropy = maxSupportedAnisotropy;
}
}
}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/GraphicsConfig.cs b/Ryujinx.Graphics.Gpu/GraphicsConfig.cs
index 468d3a34..4bda7c19 100644
--- a/Ryujinx.Graphics.Gpu/GraphicsConfig.cs
+++ b/Ryujinx.Graphics.Gpu/GraphicsConfig.cs
@@ -5,6 +5,11 @@ namespace Ryujinx.Graphics.Gpu
///
public static class GraphicsConfig
{
+ ///
+ /// Max Anisotropy. Values range from 0 - 16. Set to -1 to let the game decide.
+ ///
+ public static float MaxAnisotropy;
+
///
/// Base directory used to write shader code dumps.
/// Set to null to disable code dumping.
diff --git a/Ryujinx.Graphics.Gpu/Image/Sampler.cs b/Ryujinx.Graphics.Gpu/Image/Sampler.cs
index 45f5f519..827d6077 100644
--- a/Ryujinx.Graphics.Gpu/Image/Sampler.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Sampler.cs
@@ -40,7 +40,11 @@ namespace Ryujinx.Graphics.Gpu.Image
float maxLod = descriptor.UnpackMaxLod();
float mipLodBias = descriptor.UnpackMipLodBias();
- float maxAnisotropy = descriptor.UnpackMaxAnisotropy();
+ float maxRequestedAnisotropy = GraphicsConfig.MaxAnisotropy >= 0 && GraphicsConfig.MaxAnisotropy <= 16 ? GraphicsConfig.MaxAnisotropy : descriptor.UnpackMaxAnisotropy();
+ float maxSupportedAnisotropy = context.Capabilities.MaxSupportedAnisotropy;
+
+ if (maxRequestedAnisotropy > maxSupportedAnisotropy)
+ maxRequestedAnisotropy = maxSupportedAnisotropy;
HostSampler = context.Renderer.CreateSampler(new SamplerCreateInfo(
minFilter,
@@ -54,7 +58,7 @@ namespace Ryujinx.Graphics.Gpu.Image
minLod,
maxLod,
mipLodBias,
- maxAnisotropy));
+ maxRequestedAnisotropy));
}
///
diff --git a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
index 3d72cb7d..4b572af8 100644
--- a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
+++ b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
@@ -22,12 +22,16 @@ namespace Ryujinx.Graphics.OpenGL
public static GpuVendor Vendor => _gpuVendor.Value;
+ private static Lazy _maxSupportedAnisotropy = new Lazy(GL.GetFloat((GetPName)All.MaxTextureMaxAnisotropy));
+
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia;
public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value;
+ public static float MaxSupportedAnisotropy => _maxSupportedAnisotropy.Value;
+
private static bool HasExtension(string name)
{
int numExtensions = GL.GetInteger(GetPName.NumExtensions);
diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs
index cf2adc45..504a947b 100644
--- a/Ryujinx.Graphics.OpenGL/Renderer.cs
+++ b/Ryujinx.Graphics.OpenGL/Renderer.cs
@@ -67,7 +67,8 @@ namespace Ryujinx.Graphics.OpenGL
HwCapabilities.SupportsAstcCompression,
HwCapabilities.SupportsNonConstantTextureOffset,
HwCapabilities.MaximumComputeSharedMemorySize,
- HwCapabilities.StorageBufferOffsetAlignment);
+ HwCapabilities.StorageBufferOffsetAlignment,
+ HwCapabilities.MaxSupportedAnisotropy);
}
public ulong GetCounter(CounterType type)
diff --git a/Ryujinx/Config.json b/Ryujinx/Config.json
index 80430899..8a365550 100644
--- a/Ryujinx/Config.json
+++ b/Ryujinx/Config.json
@@ -1,5 +1,6 @@
{
- "version": 2,
+ "version": 4,
+ "max_anisotropy": -1,
"graphics_shaders_dump_path": "",
"logging_enable_debug": false,
"logging_enable_stub": true,
@@ -12,6 +13,7 @@
"enable_file_log": true,
"system_language": "AmericanEnglish",
"system_region": "USA",
+ "system_time_zone": "UTC",
"docked_mode": false,
"enable_discord_integration": true,
"enable_vsync": true,
diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs
index e6c632d9..16438ecc 100644
--- a/Ryujinx/Ui/MainWindow.cs
+++ b/Ryujinx/Ui/MainWindow.cs
@@ -308,6 +308,7 @@ namespace Ryujinx.Ui
HLE.Switch device = InitializeSwitchInstance();
// TODO: Move this somewhere else + reloadable?
+ Graphics.Gpu.GraphicsConfig.MaxAnisotropy = ConfigurationState.Instance.Graphics.MaxAnisotropy;
Graphics.Gpu.GraphicsConfig.ShadersDumpPath = ConfigurationState.Instance.Graphics.ShadersDumpPath;
if (Directory.Exists(path))
diff --git a/Ryujinx/Ui/SwitchSettings.cs b/Ryujinx/Ui/SwitchSettings.cs
index 777313a1..8ff40427 100644
--- a/Ryujinx/Ui/SwitchSettings.cs
+++ b/Ryujinx/Ui/SwitchSettings.cs
@@ -52,6 +52,7 @@ namespace Ryujinx.Ui
[GUI] ToggleButton _browseDir;
[GUI] ToggleButton _removeDir;
[GUI] Entry _graphicsShadersDumpPath;
+ [GUI] ComboBoxText _anisotropy;
[GUI] Image _controller1Image;
[GUI] ComboBoxText _controller1Type;
@@ -215,6 +216,7 @@ namespace Ryujinx.Ui
_systemLanguageSelect.SetActiveId(ConfigurationState.Instance.System.Language.Value.ToString());
_systemRegionSelect .SetActiveId(ConfigurationState.Instance.System.Region.Value.ToString());
_systemTimeZoneSelect.SetActiveId(timeZoneContentManager.SanityCheckDeviceLocationName());
+ _anisotropy .SetActiveId(ConfigurationState.Instance.Graphics.MaxAnisotropy.Value.ToString());
_controller1Type .SetActiveId(ConfigurationState.Instance.Hid.ControllerType.Value.ToString());
Controller_Changed(null, null, _controller1Type.ActiveId, _controller1Image);
@@ -458,6 +460,7 @@ namespace Ryujinx.Ui
ConfigurationState.Instance.System.Language.Value = (Language)Enum.Parse(typeof(Language), _systemLanguageSelect.ActiveId);
ConfigurationState.Instance.System.Region.Value = (Configuration.System.Region)Enum.Parse(typeof(Configuration.System.Region), _systemRegionSelect.ActiveId);
+ ConfigurationState.Instance.Graphics.MaxAnisotropy.Value = float.Parse(_anisotropy.ActiveId);
ConfigurationState.Instance.Hid.ControllerType.Value = (ControllerType)Enum.Parse(typeof(ControllerType), _controller1Type.ActiveId);
ConfigurationState.Instance.Ui.CustomThemePath.Value = _custThemePath.Buffer.Text;
ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = _graphicsShadersDumpPath.Buffer.Text;
diff --git a/Ryujinx/Ui/SwitchSettings.glade b/Ryujinx/Ui/SwitchSettings.glade
index fc9413ec..7c934639 100644
--- a/Ryujinx/Ui/SwitchSettings.glade
+++ b/Ryujinx/Ui/SwitchSettings.glade
@@ -177,8 +177,8 @@
False
True
- 2
5
+ 2
@@ -247,6 +247,11 @@
+
+ False
+ True
+ 0
+
@@ -1452,6 +1457,52 @@
+
+ False
+ True
+ 5
+ 3
+
+
+
+
False
True