diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2020-05-27 20:03:07 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-28 09:03:07 +1000 |
| commit | a15b951721d7c52c30a8e8864e91353ec6fc65f4 (patch) | |
| tree | daba23b1f6a22f4c72faa5268a73029e9fc665f7 /Ryujinx.Graphics.OpenGL | |
| parent | 83d94b21d077e2d31faee74711ff38e0c0499afa (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.cs | 27 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/HwCapabilities.cs | 4 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Pipeline.cs | 28 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Renderer.cs | 5 |
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) |
