Better viewport flipping and depth mode detection method (#1556)

* Use a better viewport flipping approach

* New approach to detect depth mode

* nit: Sort method on the OpenGL backend

* Adjust spacing on comment

* Unswap near and far parameters based on ScaleZ
This commit is contained in:
gdkchan 2020-09-19 19:46:49 -03:00 committed by GitHub
parent 4b1bed1b05
commit 1eea35554c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 101 additions and 136 deletions

View file

@ -39,6 +39,7 @@ namespace Ryujinx.Graphics.OpenGL
private TextureBase _rtColor0Texture;
private TextureBase _rtDepthTexture;
private FrontFaceDirection _frontFace;
private ClipOrigin _clipOrigin;
private ClipDepthMode _clipDepthMode;
@ -48,7 +49,7 @@ namespace Ryujinx.Graphics.OpenGL
private bool _tfEnabled;
ColorF _blendConstant = new ColorF(0, 0, 0, 0);
private ColorF _blendConstant;
internal Pipeline()
{
@ -570,20 +571,6 @@ namespace Ryujinx.Graphics.OpenGL
GL.Enable(IndexedEnableCap.Blend, index);
}
public void SetLogicOpState(bool enable, LogicalOp op)
{
if (enable)
{
GL.Enable(EnableCap.ColorLogicOp);
GL.LogicOp((LogicOp)op.Convert());
}
else
{
GL.Disable(EnableCap.ColorLogicOp);
}
}
public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp)
{
if ((enables & PolygonModeMask.Point) != 0)
@ -676,7 +663,7 @@ namespace Ryujinx.Graphics.OpenGL
public void SetFrontFace(FrontFace frontFace)
{
GL.FrontFace(frontFace.Convert());
SetFrontFace(_frontFace = frontFace.Convert());
}
public void SetImage(int index, ShaderStage stage, ITexture texture)
@ -706,11 +693,18 @@ namespace Ryujinx.Graphics.OpenGL
_vertexArray.SetIndexBuffer(buffer.Handle);
}
public void SetOrigin(Origin origin)
public void SetLogicOpState(bool enable, LogicalOp op)
{
ClipOrigin clipOrigin = origin == Origin.UpperLeft ? ClipOrigin.UpperLeft : ClipOrigin.LowerLeft;
if (enable)
{
GL.Enable(EnableCap.ColorLogicOp);
SetOrigin(clipOrigin);
GL.LogicOp((LogicOp)op.Convert());
}
else
{
GL.Disable(EnableCap.ColorLogicOp);
}
}
public void SetPointParameters(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin)
@ -1030,7 +1024,9 @@ namespace Ryujinx.Graphics.OpenGL
Viewport viewport = viewports[index];
viewportArray[viewportElemIndex + 0] = viewport.Region.X;
viewportArray[viewportElemIndex + 1] = viewport.Region.Y;
viewportArray[viewportElemIndex + 1] = viewport.Region.Y + (viewport.Region.Height < 0 ? viewport.Region.Height : 0);
viewportArray[viewportElemIndex + 2] = viewport.Region.Width;
viewportArray[viewportElemIndex + 3] = MathF.Abs(viewport.Region.Height);
if (HwCapabilities.SupportsViewportSwizzle)
{
@ -1042,13 +1038,14 @@ namespace Ryujinx.Graphics.OpenGL
viewport.SwizzleW.Convert());
}
viewportArray[viewportElemIndex + 2] = MathF.Abs(viewport.Region.Width);
viewportArray[viewportElemIndex + 3] = MathF.Abs(viewport.Region.Height);
depthRangeArray[index * 2 + 0] = viewport.DepthNear;
depthRangeArray[index * 2 + 1] = viewport.DepthFar;
}
bool flipY = viewports.Length != 0 && viewports[0].Region.Height < 0;
SetOrigin(flipY ? ClipOrigin.UpperLeft : ClipOrigin.LowerLeft);
GL.ViewportArray(first, viewports.Length, viewportArray);
GL.DepthRangeArray(first, viewports.Length, depthRangeArray);
@ -1097,9 +1094,24 @@ namespace Ryujinx.Graphics.OpenGL
_clipOrigin = origin;
GL.ClipControl(origin, _clipDepthMode);
SetFrontFace(_frontFace);
}
}
private void SetFrontFace(FrontFaceDirection frontFace)
{
// Changing clip origin will also change the front face to compensate
// for the flipped viewport, we flip it again here to compensate as
// this effect is undesirable for us.
if (_clipOrigin == ClipOrigin.UpperLeft)
{
frontFace = frontFace == FrontFaceDirection.Ccw ? FrontFaceDirection.Cw : FrontFaceDirection.Ccw;
}
GL.FrontFace(frontFace);
}
private void EnsureVertexArray()
{
if (_vertexArray == null)