diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-08-25 01:16:58 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-08-25 01:16:58 -0300 |
| commit | a42ab2e40cae5db96cc58634f1e70c4e31bb095d (patch) | |
| tree | f727a1f9685fa02a8e4f947e188f4b329135ad39 /Ryujinx.Graphics | |
| parent | da7e7027518c40702536d4c51905ae7cb496cdb5 (diff) | |
Implement vertex instancing (#381)
Diffstat (limited to 'Ryujinx.Graphics')
| -rw-r--r-- | Ryujinx.Graphics/Gal/GalPipelineState.cs | 4 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs | 16 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs | 22 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/Shader/GlslDecl.cs | 1 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs | 9 |
5 files changed, 37 insertions, 15 deletions
diff --git a/Ryujinx.Graphics/Gal/GalPipelineState.cs b/Ryujinx.Graphics/Gal/GalPipelineState.cs index d1ffbe76..7c669514 100644 --- a/Ryujinx.Graphics/Gal/GalPipelineState.cs +++ b/Ryujinx.Graphics/Gal/GalPipelineState.cs @@ -7,6 +7,8 @@ public bool Enabled; public int Stride; public long VboKey; + public bool Instanced; + public int Divisor; public GalVertexAttrib[] Attribs; } @@ -22,6 +24,8 @@ public float FlipX; public float FlipY; + public int Instance; + public GalFrontFace FrontFace; public bool CullFaceEnabled; diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs index 5828921d..051b1050 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs @@ -126,9 +126,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL BindVertexLayout(New); - if (New.FlipX != Old.FlipX || New.FlipY != Old.FlipY) + if (New.FlipX != Old.FlipX || New.FlipY != Old.FlipY || New.Instance != Old.Instance) { - Shader.SetFlip(New.FlipX, New.FlipY); + Shader.SetExtraData(New.FlipX, New.FlipY, New.Instance); } //Note: Uncomment SetFrontFace and SetCullFace when flipping issues are solved @@ -290,8 +290,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL private void BindConstBuffers(GalPipelineState New) { - //Index 0 is reserved - int FreeBinding = 1; + int FreeBinding = OGLShader.ReservedCbufCount; void BindIfNotNull(OGLShaderStage Stage) { @@ -385,6 +384,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL { GL.VertexAttribPointer(Attrib.Index, Size, Type, Normalize, Binding.Stride, Offset); } + + if (Binding.Instanced && Binding.Divisor != 0) + { + GL.VertexAttribDivisor(Attrib.Index, 1); + } + else + { + GL.VertexAttribDivisor(Attrib.Index, 0); + } } } } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs index 0108a0da..73d37b87 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs @@ -9,6 +9,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL { class OGLShader : IGalShader { + public const int ReservedCbufCount = 1; + + private const int ExtraDataSize = 4; + public OGLShaderProgram Current; private ConcurrentDictionary<long, OGLShaderStage> Stages; @@ -96,7 +100,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL return Enumerable.Empty<ShaderDeclInfo>(); } - public unsafe void SetFlip(float X, float Y) + public unsafe void SetExtraData(float FlipX, float FlipY, int Instance) { BindProgram(); @@ -104,14 +108,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.BindBuffer(BufferTarget.UniformBuffer, ExtraUboHandle); - float* Data = stackalloc float[4]; - Data[0] = X; - Data[1] = Y; + float* Data = stackalloc float[ExtraDataSize]; + Data[0] = FlipX; + Data[1] = FlipY; + Data[2] = BitConverter.Int32BitsToSingle(Instance); //Invalidate buffer - GL.BufferData(BufferTarget.UniformBuffer, 4 * sizeof(float), IntPtr.Zero, BufferUsageHint.StreamDraw); + GL.BufferData(BufferTarget.UniformBuffer, ExtraDataSize * sizeof(float), IntPtr.Zero, BufferUsageHint.StreamDraw); - GL.BufferSubData(BufferTarget.UniformBuffer, IntPtr.Zero, 4 * sizeof(float), (IntPtr)Data); + GL.BufferSubData(BufferTarget.UniformBuffer, IntPtr.Zero, ExtraDataSize * sizeof(float), (IntPtr)Data); } public void Bind(long Key) @@ -197,7 +202,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.BindBuffer(BufferTarget.UniformBuffer, ExtraUboHandle); - GL.BufferData(BufferTarget.UniformBuffer, 4 * sizeof(float), IntPtr.Zero, BufferUsageHint.StreamDraw); + GL.BufferData(BufferTarget.UniformBuffer, ExtraDataSize * sizeof(float), IntPtr.Zero, BufferUsageHint.StreamDraw); GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, ExtraUboHandle); } @@ -219,8 +224,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.UniformBlockBinding(ProgramHandle, ExtraBlockindex, 0); - //First index is reserved - int FreeBinding = 1; + int FreeBinding = ReservedCbufCount; void BindUniformBlocksIfNotNull(OGLShaderStage Stage) { diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs index 25f64db8..c22a282d 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs @@ -41,6 +41,7 @@ namespace Ryujinx.Graphics.Gal.Shader public const string ExtraUniformBlockName = "Extra"; public const string FlipUniformName = "flip"; + public const string InstanceUniformName = "instance"; public const string ProgramName = "program"; public const string ProgramAName = ProgramName + "_a"; diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs index 8baf30e0..984684f1 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs @@ -241,10 +241,15 @@ namespace Ryujinx.Graphics.Gal.Shader { if (Decl.ShaderType == GalShaderType.Vertex) { - SB.AppendLine("layout (std140) uniform " + GlslDecl.ExtraUniformBlockName + "{"); + //Memory layout here is [flip_x, flip_y, instance, unused] + //It's using 4 bytes, not 8 + + SB.AppendLine("layout (std140) uniform " + GlslDecl.ExtraUniformBlockName + " {"); SB.AppendLine(IdentationStr + "vec2 " + GlslDecl.FlipUniformName + ";"); + SB.AppendLine(IdentationStr + "int " + GlslDecl.InstanceUniformName + ";"); + SB.AppendLine("};"); } @@ -816,7 +821,7 @@ namespace Ryujinx.Graphics.Gal.Shader switch (Abuf.Offs) { case GlslDecl.VertexIdAttr: return "gl_VertexID"; - case GlslDecl.InstanceIdAttr: return "gl_InstanceID"; + case GlslDecl.InstanceIdAttr: return GlslDecl.InstanceUniformName; } } else if (Decl.ShaderType == GalShaderType.TessEvaluation) |
