aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/Program.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-07-15 00:01:10 -0300
committerGitHub <noreply@github.com>2020-07-15 13:01:10 +1000
commit788ca6a411762035a6a7a88100c4b582b47ee82d (patch)
treed48bfb91aecaead2906ec2d390357546f8c0611f /Ryujinx.Graphics.OpenGL/Program.cs
parent16dafe63166d065f40b57a9b7cf8017a6ba0b1ef (diff)
Initial transform feedback support (#1370)
* Initial transform feedback support * Some nits and fixes * Update ReportCounterType and Write method * Can't change shader or TFB bindings while TFB is active * Fix geometry shader input names with new naming
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++)