From 900a84ae0a90ae13c8c3f5158eff85c68a953362 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 27 Jun 2018 01:32:28 -0300 Subject: [PATCH] Fix vertex buffer size on the gpu when the draw vertex count is less than the buffer size, added a few more registers (currently not implemented) --- Ryujinx.Graphics/Gal/GalComparisonOp.cs | 14 ++++++++++ Ryujinx.Graphics/Gal/IGalRasterizer.cs | 10 +++++++ .../Gal/OpenGL/OGLEnumConverter.cs | 11 ++++++++ Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs | 25 ++++++++++++++++++ Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs | 2 +- Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs | 26 ++++++++++--------- Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs | 5 ++++ 7 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 Ryujinx.Graphics/Gal/GalComparisonOp.cs diff --git a/Ryujinx.Graphics/Gal/GalComparisonOp.cs b/Ryujinx.Graphics/Gal/GalComparisonOp.cs new file mode 100644 index 000000000..ddddecebb --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalComparisonOp.cs @@ -0,0 +1,14 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalComparisonOp + { + Never = 0x200, + Less = 0x201, + Equal = 0x202, + Lequal = 0x203, + Greater = 0x204, + NotEqual = 0x205, + Gequal = 0x206, + Always = 0x207 + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalRasterizer.cs b/Ryujinx.Graphics/Gal/IGalRasterizer.cs index 81c922bef..1323372a2 100644 --- a/Ryujinx.Graphics/Gal/IGalRasterizer.cs +++ b/Ryujinx.Graphics/Gal/IGalRasterizer.cs @@ -8,6 +8,16 @@ namespace Ryujinx.Graphics.Gal bool IsIboCached(long Key, long DataSize); + void EnableCullFace(); + + void DisableCullFace(); + + void EnableDepthTest(); + + void DisableDepthTest(); + + void SetDepthFunction(GalComparisonOp Func); + 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 c2b0c40a7..cb2c1a0e8 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -5,6 +5,17 @@ namespace Ryujinx.Graphics.Gal.OpenGL { static class OGLEnumConverter { + public static DepthFunction GetDepthFunc(GalComparisonOp Func) + { + if ((int)Func >= (int)DepthFunction.Never && + (int)Func <= (int)DepthFunction.Always) + { + return (DepthFunction)Func; + } + + throw new ArgumentException(nameof(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 bdf22b9c1..052506969 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs @@ -106,6 +106,31 @@ namespace Ryujinx.Graphics.Gal.OpenGL return IboCache.TryGetSize(Key, out long Size) && Size == DataSize; } + public void EnableCullFace() + { + GL.Enable(EnableCap.CullFace); + } + + public void DisableCullFace() + { + GL.Disable(EnableCap.CullFace); + } + + public void EnableDepthTest() + { + GL.Enable(EnableCap.DepthTest); + } + + public void DisableDepthTest() + { + GL.Disable(EnableCap.DepthTest); + } + + public void SetDepthFunction(GalComparisonOp Func) + { + GL.DepthFunc(OGLEnumConverter.GetDepthFunc(Func)); + } + public void CreateVbo(long Key, byte[] Buffer) { int Handle = GL.GenBuffer(); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs index 28fa8728e..da2762d6c 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs @@ -283,7 +283,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL return FreeBinding; } - + BindUniformBuffersIfNotNull(Current.Vertex); BindUniformBuffersIfNotNull(Current.TessControl); BindUniformBuffersIfNotNull(Current.TessEvaluation); diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs index 02461d5dd..1663d4c59 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs @@ -79,6 +79,8 @@ namespace Ryujinx.HLE.Gpu.Engines Gpu.Renderer.Shader.BindProgram(); + SetCullFace(); + SetDepth(); SetAlphaBlending(); UploadTextures(Vmm, Keys); @@ -98,8 +100,7 @@ namespace Ryujinx.HLE.Gpu.Engines SetFrameBuffer(Vmm, 0); - //TODO: Enable this once the frame buffer problems are fixed. - //Gpu.Renderer.ClearBuffers(Layer, Flags); + Gpu.Renderer.Rasterizer.ClearBuffers(Layer, Flags); } private void SetFrameBuffer(NvGpuVmm Vmm, int FbIndex) @@ -177,6 +178,16 @@ namespace Ryujinx.HLE.Gpu.Engines throw new ArgumentOutOfRangeException(nameof(Program)); } + private void SetCullFace() + { + //TODO. + } + + private void SetDepth() + { + //TODO. + } + private void SetAlphaBlending() { //TODO: Support independent blend properly. @@ -434,16 +445,7 @@ namespace Ryujinx.HLE.Gpu.Engines int Stride = Control & 0xfff; - long VbSize = 0; - - if (IndexCount != 0) - { - VbSize = (VertexEndPos - VertexPosition) + 1; - } - else - { - VbSize = VertexCount * Stride; - } + long VbSize = (VertexEndPos - VertexPosition) + 1; bool VboCached = Gpu.Renderer.Rasterizer.IsVboCached(VertexPosition, VbSize); diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs index de2b2eef2..64866ce9a 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs @@ -15,7 +15,9 @@ namespace Ryujinx.HLE.Gpu.Engines VertexArrayFirst = 0x35d, VertexArrayCount = 0x35e, VertexAttribNFormat = 0x458, + DepthTestEnable = 0x4b3, IBlendEnable = 0x4b9, + DepthTestFunction = 0x4c3, BlendSeparateAlpha = 0x4cf, BlendEquationRgb = 0x4d0, BlendFuncSrcRgb = 0x4d1, @@ -35,6 +37,9 @@ namespace Ryujinx.HLE.Gpu.Engines IndexArrayFormat = 0x5f6, IndexBatchFirst = 0x5f7, IndexBatchCount = 0x5f8, + CullFaceEnable = 0x646, + FrontFace = 0x647, + CullFace = 0x648, QueryAddress = 0x6c0, QuerySequence = 0x6c2, QueryControl = 0x6c3,