diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs index 11daeb593c..beade52db3 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs @@ -1,10 +1,13 @@ using OpenTK.Graphics.OpenGL; +using Ryujinx.Common.Logging; using System; namespace Ryujinx.Graphics.Gal.OpenGL { - static class OGLExtension + public static class OGLExtension { + private static bool _strictOpenGL; + private static Lazy s_EnhancedLayouts = new Lazy(() => HasExtension("GL_ARB_enhanced_layouts")); private static Lazy s_TextureMirrorClamp = new Lazy(() => HasExtension("GL_EXT_texture_mirror_clamp")); private static Lazy s_ViewportArray = new Lazy(() => HasExtension("GL_ARB_viewport_array")); @@ -13,6 +16,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL public static bool TextureMirrorClamp => s_TextureMirrorClamp.Value; public static bool ViewportArray => s_ViewportArray.Value; + // Strict + private static Lazy s_ViewportArrayStrict = new Lazy(() => HasExtensionStrict("GL_ARB_viewport_array")); + + public static bool ViewportArrayStrict => s_ViewportArrayStrict.Value; + + public static void SetStrictOpenGL(bool enabled) => _strictOpenGL = enabled; + private static bool HasExtension(string Name) { int NumExtensions = GL.GetInteger(GetPName.NumExtensions); @@ -25,6 +35,26 @@ namespace Ryujinx.Graphics.Gal.OpenGL } } + Logger.PrintWarning(LogClass.Gpu, $"OpenGL extension {Name} unavailable. You may experience some rendering issues or performance degredation"); + + return false; + } + + private static bool HasExtensionStrict(string Name) + { + bool available = HasExtension(Name); + + if (available) + { + return true; + } + + if (_strictOpenGL) + { + throw new Exception($"Required OpenGL extension {Name} unavailable. You can ignore this message by disabling 'enable_strict_opengl' " + + $"in the config however you may experience some rendering issues or performance degredation"); + } + return false; } } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs index 824f414e38..3a46662620 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs @@ -281,8 +281,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL { if (New.ScissorTestEnabled[Index]) { - // If there is only 1 scissor test, and it's the first, the scissor test applies to all viewports - if (Index == 0 && New.ScissorTestCount == 1) + // If viewport arrays are unavailable apply first scissor test to all or + // there is only 1 scissor test and it's the first, the scissor test applies to all viewports + if (!OGLExtension.ViewportArrayStrict || (Index == 0 && New.ScissorTestCount == 1)) { GL.Enable(EnableCap.ScissorTest); applyToAll = true; @@ -310,8 +311,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL } } - // If all scissor tests have been applied so we can skip remaining itterations - if (++scissorsApplied == New.ScissorTestCount) + // If all scissor tests have been applied, or viewport arrays are unavailable we can skip remaining itterations + if (!OGLExtension.ViewportArrayStrict || ++scissorsApplied == New.ScissorTestCount) { break; } diff --git a/Ryujinx/Config.jsonc b/Ryujinx/Config.jsonc index 1ba601647a..a21fc4807a 100644 --- a/Ryujinx/Config.jsonc +++ b/Ryujinx/Config.jsonc @@ -40,7 +40,10 @@ // Enable integrity checks on Switch content files "enable_fs_integrity_checks": true, - + + // Enable strict OpenGL. Required OpenGL extensions/features will throw exceptions rather than potentially problamatic fallbacks + "enable_strict_opengl": true, + // The primary controller's type // Supported Values: Handheld, ProController, NpadPair, NpadLeft, NpadRight "controller_type": "Handheld", diff --git a/Ryujinx/Configuration.cs b/Ryujinx/Configuration.cs index dbbec1cbc6..3df4718729 100644 --- a/Ryujinx/Configuration.cs +++ b/Ryujinx/Configuration.cs @@ -2,6 +2,7 @@ using LibHac.IO; using OpenTK.Input; using Ryujinx.Common; using Ryujinx.Common.Logging; +using Ryujinx.Graphics.Gal.OpenGL; using Ryujinx.HLE; using Ryujinx.HLE.HOS.SystemState; using Ryujinx.HLE.Input; @@ -61,6 +62,11 @@ namespace Ryujinx /// public bool EnableFileLog { get; private set; } + /// + /// Enables or disables stict OpenGL + /// + public bool EnableStrictOpengl { get; private set; } + /// /// Change System Language /// @@ -182,6 +188,8 @@ namespace Ryujinx } } + OGLExtension.SetStrictOpenGL(Instance.EnableStrictOpengl); + device.EnableDeviceVsync = Instance.EnableVsync; device.System.State.DockedMode = Instance.DockedMode;