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.Gpu/Engine/Methods.cs | |
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.Gpu/Engine/Methods.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Methods.cs | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs index 733f15c1..d67ce2d1 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs @@ -422,10 +422,23 @@ namespace Ryujinx.Graphics.Gpu.Engine _context.Renderer.Pipeline.SetDepthMode(depthMode); - bool flipY = (state.Get<YControl>(MethodOffset.YControl) & YControl.NegateY) != 0; - float yFlip = flipY ? -1 : 1; + YControl yControl = state.Get<YControl>(MethodOffset.YControl); + + bool flipY = yControl.HasFlag(YControl.NegateY); + Origin origin = yControl.HasFlag(YControl.TriangleRastFlip) ? Origin.LowerLeft : Origin.UpperLeft; + + _context.Renderer.Pipeline.SetOrigin(origin); + + // The triangle rast flip flag only affects rasterization, the viewport is not flipped. + // Setting the origin mode to upper left on the host, however, not onlyy affects rasterization, + // but also flips the viewport. + // We negate the effects of flipping the viewport by flipping it again using the viewport swizzle. + if (origin == Origin.UpperLeft) + { + flipY = !flipY; + } - Viewport[] viewports = new Viewport[Constants.TotalViewports]; + Span<Viewport> viewports = stackalloc Viewport[Constants.TotalViewports]; for (int index = 0; index < Constants.TotalViewports; index++) { @@ -435,17 +448,42 @@ namespace Ryujinx.Graphics.Gpu.Engine float x = transform.TranslateX - MathF.Abs(transform.ScaleX); float y = transform.TranslateY - MathF.Abs(transform.ScaleY); - float width = transform.ScaleX * 2; - float height = transform.ScaleY * 2 * yFlip; + float width = MathF.Abs(transform.ScaleX) * 2; + float height = MathF.Abs(transform.ScaleY) * 2; RectangleF region = new RectangleF(x, y, width, height); + ViewportSwizzle swizzleX = transform.UnpackSwizzleX(); + ViewportSwizzle swizzleY = transform.UnpackSwizzleY(); + ViewportSwizzle swizzleZ = transform.UnpackSwizzleZ(); + ViewportSwizzle swizzleW = transform.UnpackSwizzleW(); + + if (transform.ScaleX < 0) + { + swizzleX ^= ViewportSwizzle.NegativeFlag; + } + + if (flipY) + { + swizzleY ^= ViewportSwizzle.NegativeFlag; + } + + if (transform.ScaleY < 0) + { + swizzleY ^= ViewportSwizzle.NegativeFlag; + } + + if (transform.ScaleZ < 0) + { + swizzleZ ^= ViewportSwizzle.NegativeFlag; + } + viewports[index] = new Viewport( region, - transform.UnpackSwizzleX(), - transform.UnpackSwizzleY(), - transform.UnpackSwizzleZ(), - transform.UnpackSwizzleW(), + swizzleX, + swizzleY, + swizzleZ, + swizzleW, extents.DepthNear, extents.DepthFar); } |