Implement some GPU features (#209)
* Implement stencil testing * Implement depth testing * Implement face culling * Implement front face * Comparison functions now take OGL enums too * Fix front facing when flipping was used * Add depth and stencil clear values
This commit is contained in:
@@ -2,13 +2,13 @@ namespace Ryujinx.Graphics.Gal
|
||||
{
|
||||
public enum GalComparisonOp
|
||||
{
|
||||
Never = 0x200,
|
||||
Less = 0x201,
|
||||
Equal = 0x202,
|
||||
Lequal = 0x203,
|
||||
Greater = 0x204,
|
||||
NotEqual = 0x205,
|
||||
Gequal = 0x206,
|
||||
Always = 0x207
|
||||
Never = 0x1,
|
||||
Less = 0x2,
|
||||
Equal = 0x3,
|
||||
Lequal = 0x4,
|
||||
Greater = 0x5,
|
||||
NotEqual = 0x6,
|
||||
Gequal = 0x7,
|
||||
Always = 0x8
|
||||
}
|
||||
}
|
9
Ryujinx.Graphics/Gal/GalCullFace.cs
Normal file
9
Ryujinx.Graphics/Gal/GalCullFace.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Ryujinx.Graphics.Gal
|
||||
{
|
||||
public enum GalCullFace
|
||||
{
|
||||
Front = 0x404,
|
||||
Back = 0x405,
|
||||
FrontAndBack = 0x408
|
||||
}
|
||||
}
|
8
Ryujinx.Graphics/Gal/GalFrontFace.cs
Normal file
8
Ryujinx.Graphics/Gal/GalFrontFace.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Ryujinx.Graphics.Gal
|
||||
{
|
||||
public enum GalFrontFace
|
||||
{
|
||||
CW = 0x900,
|
||||
CCW = 0x901
|
||||
}
|
||||
}
|
14
Ryujinx.Graphics/Gal/GalStencilOp.cs
Normal file
14
Ryujinx.Graphics/Gal/GalStencilOp.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Ryujinx.Graphics.Gal
|
||||
{
|
||||
public enum GalStencilOp
|
||||
{
|
||||
Keep = 0x1,
|
||||
Zero = 0x2,
|
||||
Replace = 0x3,
|
||||
Incr = 0x4,
|
||||
Decr = 0x5,
|
||||
Invert = 0x6,
|
||||
IncrWrap = 0x7,
|
||||
DecrWrap = 0x8
|
||||
}
|
||||
}
|
@@ -8,16 +8,34 @@ namespace Ryujinx.Graphics.Gal
|
||||
|
||||
bool IsIboCached(long Key, long DataSize);
|
||||
|
||||
void SetFrontFace(GalFrontFace FrontFace);
|
||||
|
||||
void EnableCullFace();
|
||||
|
||||
void DisableCullFace();
|
||||
|
||||
void SetCullFace(GalCullFace CullFace);
|
||||
|
||||
void EnableDepthTest();
|
||||
|
||||
void DisableDepthTest();
|
||||
|
||||
void SetDepthFunction(GalComparisonOp Func);
|
||||
|
||||
void SetClearDepth(float Depth);
|
||||
|
||||
void EnableStencilTest();
|
||||
|
||||
void DisableStencilTest();
|
||||
|
||||
void SetStencilFunction(bool IsFrontFace, GalComparisonOp Func, int Ref, int Mask);
|
||||
|
||||
void SetStencilOp(bool IsFrontFace, GalStencilOp Fail, GalStencilOp ZFail, GalStencilOp ZPass);
|
||||
|
||||
void SetStencilMask(bool IsFrontFace, int Mask);
|
||||
|
||||
void SetClearStencil(int Stencil);
|
||||
|
||||
void CreateVbo(long Key, byte[] Buffer);
|
||||
|
||||
void CreateIbo(long Key, byte[] Buffer);
|
||||
|
@@ -5,17 +5,76 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||
{
|
||||
static class OGLEnumConverter
|
||||
{
|
||||
public static FrontFaceDirection GetFrontFace(GalFrontFace FrontFace)
|
||||
{
|
||||
switch (FrontFace)
|
||||
{
|
||||
case GalFrontFace.CW: return FrontFaceDirection.Cw;
|
||||
case GalFrontFace.CCW: return FrontFaceDirection.Ccw;
|
||||
}
|
||||
|
||||
throw new ArgumentException(nameof(FrontFace));
|
||||
}
|
||||
|
||||
public static CullFaceMode GetCullFace(GalCullFace CullFace)
|
||||
{
|
||||
switch (CullFace)
|
||||
{
|
||||
case GalCullFace.Front: return CullFaceMode.Front;
|
||||
case GalCullFace.Back: return CullFaceMode.Back;
|
||||
case GalCullFace.FrontAndBack: return CullFaceMode.FrontAndBack;
|
||||
}
|
||||
|
||||
throw new ArgumentException(nameof(CullFace));
|
||||
}
|
||||
|
||||
public static StencilOp GetStencilOp(GalStencilOp Op)
|
||||
{
|
||||
switch (Op)
|
||||
{
|
||||
case GalStencilOp.Keep: return StencilOp.Keep;
|
||||
case GalStencilOp.Zero: return StencilOp.Zero;
|
||||
case GalStencilOp.Replace: return StencilOp.Replace;
|
||||
case GalStencilOp.Incr: return StencilOp.Incr;
|
||||
case GalStencilOp.Decr: return StencilOp.Decr;
|
||||
case GalStencilOp.Invert: return StencilOp.Invert;
|
||||
case GalStencilOp.IncrWrap: return StencilOp.IncrWrap;
|
||||
case GalStencilOp.DecrWrap: return StencilOp.DecrWrap;
|
||||
}
|
||||
|
||||
throw new ArgumentException(nameof(Op));
|
||||
}
|
||||
|
||||
public static DepthFunction GetDepthFunc(GalComparisonOp Func)
|
||||
{
|
||||
//Looks like the GPU can take it's own values (described in GalComparisonOp) and OpenGL values alike
|
||||
if ((int)Func >= (int)DepthFunction.Never &&
|
||||
(int)Func <= (int)DepthFunction.Always)
|
||||
{
|
||||
return (DepthFunction)Func;
|
||||
}
|
||||
|
||||
switch (Func)
|
||||
{
|
||||
case GalComparisonOp.Never: return DepthFunction.Never;
|
||||
case GalComparisonOp.Less: return DepthFunction.Less;
|
||||
case GalComparisonOp.Equal: return DepthFunction.Equal;
|
||||
case GalComparisonOp.Lequal: return DepthFunction.Lequal;
|
||||
case GalComparisonOp.Greater: return DepthFunction.Greater;
|
||||
case GalComparisonOp.NotEqual: return DepthFunction.Notequal;
|
||||
case GalComparisonOp.Gequal: return DepthFunction.Gequal;
|
||||
case GalComparisonOp.Always: return DepthFunction.Always;
|
||||
}
|
||||
|
||||
throw new ArgumentException(nameof(Func));
|
||||
}
|
||||
|
||||
public static StencilFunction GetStencilFunc(GalComparisonOp Func)
|
||||
{
|
||||
//OGL comparison values match, it's just an enum cast
|
||||
return (StencilFunction)GetDepthFunc(Func);
|
||||
}
|
||||
|
||||
public static DrawElementsType GetDrawElementsType(GalIndexFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
|
@@ -106,6 +106,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||
return IboCache.TryGetSize(Key, out long Size) && Size == DataSize;
|
||||
}
|
||||
|
||||
public void SetFrontFace(GalFrontFace FrontFace)
|
||||
{
|
||||
GL.FrontFace(OGLEnumConverter.GetFrontFace(FrontFace));
|
||||
}
|
||||
|
||||
public void EnableCullFace()
|
||||
{
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
@@ -116,6 +121,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
}
|
||||
|
||||
public void SetCullFace(GalCullFace CullFace)
|
||||
{
|
||||
GL.CullFace(OGLEnumConverter.GetCullFace(CullFace));
|
||||
}
|
||||
|
||||
public void EnableDepthTest()
|
||||
{
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
@@ -131,6 +141,49 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||
GL.DepthFunc(OGLEnumConverter.GetDepthFunc(Func));
|
||||
}
|
||||
|
||||
public void SetClearDepth(float Depth)
|
||||
{
|
||||
GL.ClearDepth(Depth);
|
||||
}
|
||||
|
||||
public void EnableStencilTest()
|
||||
{
|
||||
GL.Enable(EnableCap.StencilTest);
|
||||
}
|
||||
|
||||
public void DisableStencilTest()
|
||||
{
|
||||
GL.Disable(EnableCap.StencilTest);
|
||||
}
|
||||
|
||||
public void SetStencilFunction(bool IsFrontFace, GalComparisonOp Func, int Ref, int Mask)
|
||||
{
|
||||
GL.StencilFuncSeparate(
|
||||
IsFrontFace ? StencilFace.Front : StencilFace.Back,
|
||||
OGLEnumConverter.GetStencilFunc(Func),
|
||||
Ref,
|
||||
Mask);
|
||||
}
|
||||
|
||||
public void SetStencilOp(bool IsFrontFace, GalStencilOp Fail, GalStencilOp ZFail, GalStencilOp ZPass)
|
||||
{
|
||||
GL.StencilOpSeparate(
|
||||
IsFrontFace ? StencilFace.Front : StencilFace.Back,
|
||||
OGLEnumConverter.GetStencilOp(Fail),
|
||||
OGLEnumConverter.GetStencilOp(ZFail),
|
||||
OGLEnumConverter.GetStencilOp(ZPass));
|
||||
}
|
||||
|
||||
public void SetStencilMask(bool IsFrontFace, int Mask)
|
||||
{
|
||||
GL.StencilMaskSeparate(IsFrontFace ? StencilFace.Front : StencilFace.Back, Mask);
|
||||
}
|
||||
|
||||
public void SetClearStencil(int Stencil)
|
||||
{
|
||||
GL.ClearStencil(Stencil);
|
||||
}
|
||||
|
||||
public void CreateVbo(long Key, byte[] Buffer)
|
||||
{
|
||||
int Handle = GL.GenBuffer();
|
||||
|
Reference in New Issue
Block a user