aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Engine/Methods.cs
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.Gpu/Engine/Methods.cs
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.Gpu/Engine/Methods.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Methods.cs56
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);
}