diff options
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Program.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/Program.cs | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Program.cs b/Ryujinx.Graphics.OpenGL/Program.cs index 8b4f6e24..a0f8eb01 100644 --- a/Ryujinx.Graphics.OpenGL/Program.cs +++ b/Ryujinx.Graphics.OpenGL/Program.cs @@ -2,6 +2,10 @@ using OpenTK.Graphics.OpenGL; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; +using Ryujinx.Graphics.Shader.CodeGen.Glsl; +using System; +using System.Collections.Generic; +using System.Linq; namespace Ryujinx.Graphics.OpenGL { @@ -31,7 +35,7 @@ namespace Ryujinx.Graphics.OpenGL private int[] _textureUnits; private int[] _imageUnits; - public Program(IShader[] shaders) + public Program(IShader[] shaders, TransformFeedbackDescriptor[] transformFeedbackDescriptors) { _ubBindingPoints = new int[UbsPerStage * ShaderStages]; _sbBindingPoints = new int[SbsPerStage * ShaderStages]; @@ -67,6 +71,54 @@ namespace Ryujinx.Graphics.OpenGL GL.AttachShader(Handle, shaderHandle); } + if (transformFeedbackDescriptors != null) + { + List<string> varyings = new List<string>(); + + int cbi = 0; + + foreach (var tfd in transformFeedbackDescriptors.OrderBy(x => x.BufferIndex)) + { + if (tfd.VaryingLocations.Length == 0) + { + continue; + } + + while (cbi < tfd.BufferIndex) + { + varyings.Add("gl_NextBuffer"); + + cbi++; + } + + int stride = Math.Min(128 * 4, (tfd.Stride + 3) & ~3); + + int j = 0; + + for (; j < tfd.VaryingLocations.Length && j * 4 < stride; j++) + { + byte location = tfd.VaryingLocations[j]; + + varyings.Add(Varying.GetName(location) ?? "gl_SkipComponents1"); + + j += Varying.GetSize(location) - 1; + } + + int feedbackBytes = j * 4; + + while (feedbackBytes < stride) + { + int bytes = Math.Min(16, stride - feedbackBytes); + + varyings.Add($"gl_SkipComponents{(bytes / 4)}"); + + feedbackBytes += bytes; + } + } + + GL.TransformFeedbackVaryings(Handle, varyings.Count, varyings.ToArray(), TransformFeedbackMode.InterleavedAttribs); + } + GL.LinkProgram(Handle); for (int index = 0; index < shaders.Length; index++) |