aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-05-27 20:03:07 -0300
committerGitHub <noreply@github.com>2020-05-28 09:03:07 +1000
commita15b951721d7c52c30a8e8864e91353ec6fc65f4 (patch)
treedaba23b1f6a22f4c72faa5268a73029e9fc665f7 /Ryujinx.Graphics.OpenGL
parent83d94b21d077e2d31faee74711ff38e0c0499afa (diff)
Fix wrong face culling once and for all (#1277)
* Viewport swizzle support on NV and clip origin * Initialize default viewport swizzle state, emulate viewport swizzle on shaders when not supported * Address PR feedback
Diffstat (limited to 'Ryujinx.Graphics.OpenGL')
-rw-r--r--Ryujinx.Graphics.OpenGL/EnumConversion.cs27
-rw-r--r--Ryujinx.Graphics.OpenGL/HwCapabilities.cs4
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs28
-rw-r--r--Ryujinx.Graphics.OpenGL/Renderer.cs5
4 files changed, 47 insertions, 17 deletions
diff --git a/Ryujinx.Graphics.OpenGL/EnumConversion.cs b/Ryujinx.Graphics.OpenGL/EnumConversion.cs
index 014ddfc1..aebe54fa 100644
--- a/Ryujinx.Graphics.OpenGL/EnumConversion.cs
+++ b/Ryujinx.Graphics.OpenGL/EnumConversion.cs
@@ -416,5 +416,32 @@ namespace Ryujinx.Graphics.OpenGL
return TextureTarget.Texture2D;
}
+
+ public static NvViewportSwizzle Convert(this ViewportSwizzle swizzle)
+ {
+ switch (swizzle)
+ {
+ case ViewportSwizzle.PositiveX:
+ return NvViewportSwizzle.ViewportSwizzlePositiveXNv;
+ case ViewportSwizzle.PositiveY:
+ return NvViewportSwizzle.ViewportSwizzlePositiveYNv;
+ case ViewportSwizzle.PositiveZ:
+ return NvViewportSwizzle.ViewportSwizzlePositiveZNv;
+ case ViewportSwizzle.PositiveW:
+ return NvViewportSwizzle.ViewportSwizzlePositiveWNv;
+ case ViewportSwizzle.NegativeX:
+ return NvViewportSwizzle.ViewportSwizzleNegativeXNv;
+ case ViewportSwizzle.NegativeY:
+ return NvViewportSwizzle.ViewportSwizzleNegativeYNv;
+ case ViewportSwizzle.NegativeZ:
+ return NvViewportSwizzle.ViewportSwizzleNegativeZNv;
+ case ViewportSwizzle.NegativeW:
+ return NvViewportSwizzle.ViewportSwizzleNegativeWNv;
+ }
+
+ Logger.PrintDebug(LogClass.Gpu, $"Invalid {nameof(ViewportSwizzle)} enum value: {swizzle}.");
+
+ return NvViewportSwizzle.ViewportSwizzlePositiveXNv;
+ }
}
}
diff --git a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
index 229b3561..14515b61 100644
--- a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
+++ b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
@@ -7,6 +7,7 @@ namespace Ryujinx.Graphics.OpenGL
{
private static readonly Lazy<bool> _supportsAstcCompression = new Lazy<bool>(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
private static readonly Lazy<bool> _supportsImageLoadFormatted = new Lazy<bool>(() => HasExtension("GL_EXT_shader_image_load_formatted"));
+ private static readonly Lazy<bool> _supportsViewportSwizzle = new Lazy<bool>(() => HasExtension("GL_NV_viewport_swizzle"));
private static readonly Lazy<int> _maximumComputeSharedMemorySize = new Lazy<int>(() => GetLimit(All.MaxComputeSharedMemorySize));
private static readonly Lazy<int> _storageBufferOffsetAlignment = new Lazy<int>(() => GetLimit(All.ShaderStorageBufferOffsetAlignment));
@@ -27,12 +28,13 @@ namespace Ryujinx.Graphics.OpenGL
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
public static bool SupportsImageLoadFormatted => _supportsImageLoadFormatted.Value;
+ public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.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;
+ public static float MaximumSupportedAnisotropy => _maxSupportedAnisotropy.Value;
private static bool HasExtension(string name)
{
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index ee4ce298..6c511e09 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -650,6 +650,13 @@ namespace Ryujinx.Graphics.OpenGL
_vertexArray.SetIndexBuffer(buffer.Handle);
}
+ public void SetOrigin(Origin origin)
+ {
+ ClipOrigin clipOrigin = origin == Origin.UpperLeft ? ClipOrigin.UpperLeft : ClipOrigin.LowerLeft;
+
+ SetOrigin(clipOrigin);
+ }
+
public void SetPointSize(float size)
{
GL.PointSize(size);
@@ -854,8 +861,6 @@ namespace Ryujinx.Graphics.OpenGL
public void SetViewports(int first, ReadOnlySpan<Viewport> viewports)
{
- bool flipY = false;
-
float[] viewportArray = new float[viewports.Length * 4];
double[] depthRangeArray = new double[viewports.Length * 2];
@@ -869,17 +874,14 @@ namespace Ryujinx.Graphics.OpenGL
viewportArray[viewportElemIndex + 0] = viewport.Region.X;
viewportArray[viewportElemIndex + 1] = viewport.Region.Y;
- // OpenGL does not support per-viewport flipping, so
- // instead we decide that based on the viewport 0 value.
- // It will apply to all viewports.
- if (index == 0)
+ if (HwCapabilities.SupportsViewportSwizzle)
{
- flipY = viewport.Region.Height < 0;
- }
-
- if (viewport.SwizzleY == ViewportSwizzle.NegativeY)
- {
- flipY = !flipY;
+ GL.NV.ViewportSwizzle(
+ index,
+ viewport.SwizzleX.Convert(),
+ viewport.SwizzleY.Convert(),
+ viewport.SwizzleZ.Convert(),
+ viewport.SwizzleW.Convert());
}
viewportArray[viewportElemIndex + 2] = MathF.Abs(viewport.Region.Width);
@@ -892,8 +894,6 @@ namespace Ryujinx.Graphics.OpenGL
GL.ViewportArray(first, viewports.Length, viewportArray);
GL.DepthRangeArray(first, viewports.Length, depthRangeArray);
-
- SetOrigin(flipY ? ClipOrigin.UpperLeft : ClipOrigin.LowerLeft);
}
public void TextureBarrier()
diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs
index c839c296..49dba9cc 100644
--- a/Ryujinx.Graphics.OpenGL/Renderer.cs
+++ b/Ryujinx.Graphics.OpenGL/Renderer.cs
@@ -75,9 +75,10 @@ namespace Ryujinx.Graphics.OpenGL
HwCapabilities.SupportsAstcCompression,
HwCapabilities.SupportsImageLoadFormatted,
HwCapabilities.SupportsNonConstantTextureOffset,
+ HwCapabilities.SupportsViewportSwizzle,
HwCapabilities.MaximumComputeSharedMemorySize,
- HwCapabilities.StorageBufferOffsetAlignment,
- HwCapabilities.MaxSupportedAnisotropy);
+ HwCapabilities.MaximumSupportedAnisotropy,
+ HwCapabilities.StorageBufferOffsetAlignment);
}
public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data)