aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/Program.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Program.cs')
-rw-r--r--Ryujinx.Graphics.OpenGL/Program.cs54
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++)