aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/Pipeline.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-10-25 17:23:42 -0300
committerGitHub <noreply@github.com>2020-10-25 17:23:42 -0300
commit812e32f7753d452f5c6776fa18e2b2a26b4ff3bb (patch)
tree4dd4c085b5e20686dbc80d14b04024108909800d /Ryujinx.Graphics.OpenGL/Pipeline.cs
parentcf0f0fc4e740c774eadaa328dc543ee9a03fbd09 (diff)
Fix transform feedback errors caused by host pause/resume and multiple uses (#1634)
* Fix transform feedback errors caused by host pause/resume * Fix TFB being used as something else issue with copies * This is supposed to be StreamCopy
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Pipeline.cs')
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs87
1 files changed, 69 insertions, 18 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index 2650e9ee..6277fe16 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -5,7 +5,6 @@ using Ryujinx.Graphics.OpenGL.Image;
using Ryujinx.Graphics.OpenGL.Queries;
using Ryujinx.Graphics.Shader;
using System;
-using System.Threading;
namespace Ryujinx.Graphics.OpenGL
{
@@ -49,6 +48,10 @@ namespace Ryujinx.Graphics.OpenGL
private bool _scissor0Enable = false;
private bool _tfEnabled;
+ private TransformFeedbackPrimitiveType _tfTopology;
+
+ private readonly BufferHandle[] _tfbs;
+ private readonly BufferRange[] _tfbTargets;
private ColorF _blendConstant;
@@ -74,6 +77,9 @@ namespace Ryujinx.Graphics.OpenGL
{
_cpRenderScale[index] = 1f;
}
+
+ _tfbs = new BufferHandle[Constants.MaxTransformFeedbackBuffers];
+ _tfbTargets = new BufferRange[Constants.MaxTransformFeedbackBuffers];
}
public void Barrier()
@@ -83,7 +89,7 @@ namespace Ryujinx.Graphics.OpenGL
public void BeginTransformFeedback(PrimitiveTopology topology)
{
- GL.BeginTransformFeedback(topology.ConvertToTfType());
+ GL.BeginTransformFeedback(_tfTopology = topology.ConvertToTfType());
_tfEnabled = true;
}
@@ -175,7 +181,7 @@ namespace Ryujinx.Graphics.OpenGL
return;
}
- PrepareForDraw();
+ PreDraw();
if (_primitiveType == PrimitiveType.Quads)
{
@@ -190,7 +196,7 @@ namespace Ryujinx.Graphics.OpenGL
DrawImpl(vertexCount, instanceCount, firstVertex, firstInstance);
}
- _framebuffer.SignalModified();
+ PostDraw();
}
private void DrawQuadsImpl(
@@ -293,7 +299,7 @@ namespace Ryujinx.Graphics.OpenGL
return;
}
- PrepareForDraw();
+ PreDraw();
int indexElemSize = 1;
@@ -335,7 +341,7 @@ namespace Ryujinx.Graphics.OpenGL
firstInstance);
}
- _framebuffer.SignalModified();
+ PostDraw();
}
private void DrawQuadsIndexedImpl(
@@ -790,9 +796,9 @@ namespace Ryujinx.Graphics.OpenGL
if (_tfEnabled)
{
- GL.PauseTransformFeedback();
+ GL.EndTransformFeedback();
_program.Bind();
- GL.ResumeTransformFeedback();
+ GL.BeginTransformFeedback(_tfTopology);
}
else
{
@@ -993,19 +999,39 @@ namespace Ryujinx.Graphics.OpenGL
}
}
- public void SetTransformFeedbackBuffer(int index, BufferRange buffer)
+ public void SetTransformFeedbackBuffers(ReadOnlySpan<BufferRange> buffers)
{
- const BufferRangeTarget target = BufferRangeTarget.TransformFeedbackBuffer;
-
if (_tfEnabled)
{
- GL.PauseTransformFeedback();
- GL.BindBufferRange(target, index, buffer.Handle.ToInt32(), (IntPtr)buffer.Offset, buffer.Size);
- GL.ResumeTransformFeedback();
+ GL.EndTransformFeedback();
}
- else
+
+ int count = Math.Min(buffers.Length, Constants.MaxTransformFeedbackBuffers);
+
+ for (int i = 0; i < count; i++)
{
- GL.BindBufferRange(target, index, buffer.Handle.ToInt32(), (IntPtr)buffer.Offset, buffer.Size);
+ BufferRange buffer = buffers[i];
+ _tfbTargets[i] = buffer;
+
+ if (buffer.Handle == BufferHandle.Null)
+ {
+ GL.BindBufferBase(BufferRangeTarget.TransformFeedbackBuffer, i, 0);
+ continue;
+ }
+
+ if (_tfbs[i] == BufferHandle.Null)
+ {
+ _tfbs[i] = Buffer.Create();
+ }
+
+ Buffer.Resize(_tfbs[i], buffer.Size);
+ Buffer.Copy(buffer.Handle, _tfbs[i], buffer.Offset, 0, buffer.Size);
+ GL.BindBufferBase(BufferRangeTarget.TransformFeedbackBuffer, i, _tfbs[i].ToInt32());
+ }
+
+ if (_tfEnabled)
+ {
+ GL.BeginTransformFeedback(_tfTopology);
}
}
@@ -1104,7 +1130,7 @@ namespace Ryujinx.Graphics.OpenGL
? BufferRangeTarget.ShaderStorageBuffer
: BufferRangeTarget.UniformBuffer;
- if (buffer.Handle == null)
+ if (buffer.Handle == BufferHandle.Null)
{
GL.BindBufferRange(target, bindingPoint, 0, IntPtr.Zero, 0);
return;
@@ -1237,7 +1263,7 @@ namespace Ryujinx.Graphics.OpenGL
}
}
- private void PrepareForDraw()
+ private void PreDraw()
{
_vertexArray.Validate();
@@ -1247,6 +1273,22 @@ namespace Ryujinx.Graphics.OpenGL
}
}
+ private void PostDraw()
+ {
+ _framebuffer?.SignalModified();
+
+ if (_tfEnabled)
+ {
+ for (int i = 0; i < Constants.MaxTransformFeedbackBuffers; i++)
+ {
+ if (_tfbTargets[i].Handle != BufferHandle.Null)
+ {
+ Buffer.Copy(_tfbs[i], _tfbTargets[i].Handle, 0, _tfbTargets[i].Offset, _tfbTargets[i].Size);
+ }
+ }
+ }
+ }
+
private void RestoreComponentMask(int index)
{
GL.ColorMask(
@@ -1319,6 +1361,15 @@ namespace Ryujinx.Graphics.OpenGL
public void Dispose()
{
+ for (int i = 0; i < Constants.MaxTransformFeedbackBuffers; i++)
+ {
+ if (_tfbs[i] != BufferHandle.Null)
+ {
+ Buffer.Delete(_tfbs[i]);
+ _tfbs[i] = BufferHandle.Null;
+ }
+ }
+
_framebuffer?.Dispose();
_vertexArray?.Dispose();
}