diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-07-05 15:47:29 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-07-05 15:47:29 -0300 |
| commit | 97ca974213ec9564ed4a9c57e998ca726dbbb64f (patch) | |
| tree | 5daf598d267d3ce05f3ef342621e7f93536fa554 /Ryujinx.Graphics | |
| parent | c99b2884e4eb9adfb5b893ee84d7678262d19b06 (diff) | |
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
Diffstat (limited to 'Ryujinx.Graphics')
| -rw-r--r-- | Ryujinx.Graphics/Gal/GalComparisonOp.cs | 16 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/GalCullFace.cs | 9 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/GalFrontFace.cs | 8 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/GalStencilOp.cs | 14 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/IGalRasterizer.cs | 18 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs | 59 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs | 53 |
7 files changed, 169 insertions, 8 deletions
diff --git a/Ryujinx.Graphics/Gal/GalComparisonOp.cs b/Ryujinx.Graphics/Gal/GalComparisonOp.cs index ddddeceb..f26a7753 100644 --- a/Ryujinx.Graphics/Gal/GalComparisonOp.cs +++ b/Ryujinx.Graphics/Gal/GalComparisonOp.cs @@ -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 } }
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalCullFace.cs b/Ryujinx.Graphics/Gal/GalCullFace.cs new file mode 100644 index 00000000..4ab3e174 --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalCullFace.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalCullFace + { + Front = 0x404, + Back = 0x405, + FrontAndBack = 0x408 + } +} diff --git a/Ryujinx.Graphics/Gal/GalFrontFace.cs b/Ryujinx.Graphics/Gal/GalFrontFace.cs new file mode 100644 index 00000000..17ad1126 --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalFrontFace.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalFrontFace + { + CW = 0x900, + CCW = 0x901 + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalStencilOp.cs b/Ryujinx.Graphics/Gal/GalStencilOp.cs new file mode 100644 index 00000000..fc83ca5e --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalStencilOp.cs @@ -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 + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalRasterizer.cs b/Ryujinx.Graphics/Gal/IGalRasterizer.cs index e0469382..586eae6b 100644 --- a/Ryujinx.Graphics/Gal/IGalRasterizer.cs +++ b/Ryujinx.Graphics/Gal/IGalRasterizer.cs @@ -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); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 349c695e..3a81150d 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -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) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs index 8bff6bb3..b9885711 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs @@ -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(); |
