aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal/OpenGL
diff options
context:
space:
mode:
authorBaronKiko <BaronKiko@users.noreply.github.com>2019-03-02 10:50:21 +0000
committerjduncanator <1518948+jduncanator@users.noreply.github.com>2019-03-02 21:50:21 +1100
commit0973daefa1a509a8b08c936384251f1fee475587 (patch)
tree7eae6ce82eca17745f2e4c80c960b421a7f68baa /Ryujinx.Graphics/Gal/OpenGL
parentdbc105eafba1db23858c015d6bd24c42c5dc255c (diff)
Fixed Scissor Test on Intel based GPUs (#595)
* Reworked scissor tests to remove fixme and handle issues with intel gpu's * Error handling for scissor tests * Disable strict opengl by default * Reformatting for JD * Updated scheme for new property in config * Fixed typo * Moved magic value to constant. I liked the magic :( * Fixed ordering for undertale * Fixed undertale bug * Removed strict opengl in favour of required. With this an exception is no longer thrown, just a warning for required extensions * Uses clamp instead of if's * Removed evil tabs and no longer used include
Diffstat (limited to 'Ryujinx.Graphics/Gal/OpenGL')
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs36
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs85
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs3
3 files changed, 83 insertions, 41 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs
index 52b3d0ce..eb06f83c 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs
@@ -1,19 +1,23 @@
using OpenTK.Graphics.OpenGL;
+using Ryujinx.Common.Logging;
using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
static class OGLExtension
{
+ // Private lazy backing variables
private static Lazy<bool> s_EnhancedLayouts = new Lazy<bool>(() => HasExtension("GL_ARB_enhanced_layouts"));
private static Lazy<bool> s_TextureMirrorClamp = new Lazy<bool>(() => HasExtension("GL_EXT_texture_mirror_clamp"));
private static Lazy<bool> s_ViewportArray = new Lazy<bool>(() => HasExtension("GL_ARB_viewport_array"));
private static Lazy<bool> s_NvidiaDriver = new Lazy<bool>(() => IsNvidiaDriver());
+ // Public accessors
public static bool EnhancedLayouts => s_EnhancedLayouts.Value;
public static bool TextureMirrorClamp => s_TextureMirrorClamp.Value;
public static bool ViewportArray => s_ViewportArray.Value;
+
public static bool NvidiaDrvier => s_NvidiaDriver.Value;
private static bool HasExtension(string Name)
@@ -28,11 +32,39 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
}
+ Logger.PrintInfo(LogClass.Gpu, $"OpenGL extension {Name} unavailable. You may experience some performance degredation");
+
return false;
}
- private static bool IsNvidiaDriver() {
+ private static bool IsNvidiaDriver()
+ {
return GL.GetString(StringName.Vendor).Equals("NVIDIA Corporation");
}
+
+ public static class Required
+ {
+ // Public accessors
+ public static bool EnhancedLayouts => s_EnhancedLayoutsRequired.Value;
+ public static bool TextureMirrorClamp => s_TextureMirrorClampRequired.Value;
+ public static bool ViewportArray => s_ViewportArrayRequired.Value;
+
+ // Private lazy backing variables
+ private static Lazy<bool> s_EnhancedLayoutsRequired = new Lazy<bool>(() => HasExtensionRequired(OGLExtension.EnhancedLayouts, "GL_ARB_enhanced_layouts"));
+ private static Lazy<bool> s_TextureMirrorClampRequired = new Lazy<bool>(() => HasExtensionRequired(OGLExtension.TextureMirrorClamp, "GL_EXT_texture_mirror_clamp"));
+ private static Lazy<bool> s_ViewportArrayRequired = new Lazy<bool>(() => HasExtensionRequired(OGLExtension.ViewportArray, "GL_ARB_viewport_array"));
+
+ private static bool HasExtensionRequired(bool Value, string Name)
+ {
+ if (Value)
+ {
+ return true;
+ }
+
+ Logger.PrintWarning(LogClass.Gpu, $"Required OpenGL extension {Name} unavailable. You may experience some rendering issues");
+
+ return false;
+ }
+ }
}
-} \ No newline at end of file
+}
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
index 6a928603..96d42e02 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
@@ -270,47 +270,52 @@ namespace Ryujinx.Graphics.Gal.OpenGL
// Scissor Test
- bool forceUpdate;
-
- for (int Index = 0; Index < New.ScissorTestCount; Index++)
+ // All scissor test are disabled before drawing final framebuffer to screen so we don't need to handle disabling
+ // Skip if there are no scissor tests to enable
+ if (New.ScissorTestCount != 0)
{
- forceUpdate = false;
+ int scissorsApplied = 0;
+ bool applyToAll = false;
- if (New.ScissorTestEnabled[Index])
+ for (int Index = 0; Index < GalPipelineState.RenderTargetsCount; Index++)
{
- // If there is only 1 scissor test, geometry shaders are disabled so the scissor test applies to all viewports
- if (New.ScissorTestCount == 1)
- {
- GL.Enable(EnableCap.ScissorTest);
- }
- else
+ if (New.ScissorTestEnabled[Index])
{
- GL.Enable(IndexedEnableCap.ScissorTest, Index);
- }
- forceUpdate = true;
- }
- else
- {
- GL.Disable(IndexedEnableCap.ScissorTest, Index);
- }
+ // 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.Required.ViewportArray || (Index == 0 && New.ScissorTestCount == 1))
+ {
+ GL.Enable(EnableCap.ScissorTest);
+ applyToAll = true;
+ }
+ else
+ {
+ GL.Enable(IndexedEnableCap.ScissorTest, Index);
+ }
- if (New.ScissorTestEnabled[Index] &&
- (New.ScissorTestX[Index] != Old.ScissorTestX[Index] ||
- New.ScissorTestY[Index] != Old.ScissorTestY[Index] ||
- New.ScissorTestWidth[Index] != Old.ScissorTestWidth[Index] ||
- New.ScissorTestHeight[Index] != Old.ScissorTestHeight[Index] ||
- forceUpdate)) // Force update intentionally last to reduce if comparisons
- {
- // If there is only 1 scissor test geometry shaders are disables so the scissor test applies to all viewports
- if (New.ScissorTestCount == 1)
- {
- GL.Scissor(New.ScissorTestX[Index], New.ScissorTestY[Index],
- New.ScissorTestWidth[Index], New.ScissorTestHeight[Index]);
- }
- else
- {
- GL.ScissorIndexed(Index, New.ScissorTestX[Index], New.ScissorTestY[Index],
- New.ScissorTestWidth[Index], New.ScissorTestHeight[Index]);
+ if (New.ScissorTestEnabled[Index] != Old.ScissorTestEnabled[Index] ||
+ New.ScissorTestX[Index] != Old.ScissorTestX[Index] ||
+ New.ScissorTestY[Index] != Old.ScissorTestY[Index] ||
+ New.ScissorTestWidth[Index] != Old.ScissorTestWidth[Index] ||
+ New.ScissorTestHeight[Index] != Old.ScissorTestHeight[Index])
+ {
+ if (applyToAll)
+ {
+ GL.Scissor(New.ScissorTestX[Index], New.ScissorTestY[Index],
+ New.ScissorTestWidth[Index], New.ScissorTestHeight[Index]);
+ }
+ else
+ {
+ GL.ScissorIndexed(Index, New.ScissorTestX[Index], New.ScissorTestY[Index],
+ New.ScissorTestWidth[Index], New.ScissorTestHeight[Index]);
+ }
+ }
+
+ // If all scissor tests have been applied, or viewport arrays are unavailable we can skip remaining itterations
+ if (!OGLExtension.Required.ViewportArray || ++scissorsApplied == New.ScissorTestCount)
+ {
+ break;
+ }
}
}
}
@@ -378,6 +383,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Old = New;
}
+ public void Unbind(GalPipelineState State)
+ {
+ if (State.ScissorTestCount > 0)
+ {
+ GL.Disable(EnableCap.ScissorTest);
+ }
+ }
+
private void SetAllBlendState(BlendState New)
{
Enable(EnableCap.Blend, New.Enabled);
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
index 8dd3b37f..53cfd4a6 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs
@@ -367,9 +367,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.Disable(EnableCap.FramebufferSrgb);
- // Will be re-enabled if needed while binding, called before any game GL calls
- GL.Disable(EnableCap.ScissorTest);
-
GL.BlitFramebuffer(
SrcX0,
SrcY0,