aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2021-01-26 18:44:07 -0300
committerGitHub <noreply@github.com>2021-01-27 08:44:07 +1100
commitcaf049ed15f1c22d55aacfab79019538b2587e11 (patch)
tree33bf4b410a901fd8de49b79b73161976453e4837
parentd6bd0470fb0507cc9c6069e577ae2814e614265b (diff)
Avoid some redundant GL calls (#1958)
-rw-r--r--Ryujinx.Graphics.GAL/IPipeline.cs3
-rw-r--r--Ryujinx.Graphics.GAL/VertexAttribDescriptor.cs22
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Methods.cs8
-rw-r--r--Ryujinx.Graphics.OpenGL/Framebuffer.cs11
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs30
-rw-r--r--Ryujinx.Graphics.OpenGL/VertexArray.cs88
6 files changed, 113 insertions, 49 deletions
diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs
index 96ccfb28..bb3a8dca 100644
--- a/Ryujinx.Graphics.GAL/IPipeline.cs
+++ b/Ryujinx.Graphics.GAL/IPipeline.cs
@@ -68,8 +68,7 @@ namespace Ryujinx.Graphics.GAL
void SetSampler(int binding, ISampler sampler);
- void SetScissorEnable(int index, bool enable);
- void SetScissor(int index, int x, int y, int width, int height);
+ void SetScissor(int index, bool enable, int x, int y, int width, int height);
void SetStencilTest(StencilTestDescriptor stencilTest);
diff --git a/Ryujinx.Graphics.GAL/VertexAttribDescriptor.cs b/Ryujinx.Graphics.GAL/VertexAttribDescriptor.cs
index 1547658e..b3248b62 100644
--- a/Ryujinx.Graphics.GAL/VertexAttribDescriptor.cs
+++ b/Ryujinx.Graphics.GAL/VertexAttribDescriptor.cs
@@ -1,6 +1,8 @@
+using System;
+
namespace Ryujinx.Graphics.GAL
{
- public struct VertexAttribDescriptor
+ public struct VertexAttribDescriptor : IEquatable<VertexAttribDescriptor>
{
public int BufferIndex { get; }
public int Offset { get; }
@@ -16,5 +18,23 @@ namespace Ryujinx.Graphics.GAL
IsZero = isZero;
Format = format;
}
+
+ public override bool Equals(object obj)
+ {
+ return obj is VertexAttribDescriptor other && Equals(other);
+ }
+
+ public bool Equals(VertexAttribDescriptor other)
+ {
+ return BufferIndex == other.BufferIndex &&
+ Offset == other.Offset &&
+ IsZero == other.IsZero &&
+ Format == other.Format;
+ }
+
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(BufferIndex, Offset, IsZero, Format);
+ }
}
}
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
index d6bd5110..a41fd541 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
@@ -436,8 +436,6 @@ namespace Ryujinx.Graphics.Gpu.Engine
bool enable = scissor.Enable && (scissor.X1 != 0 || scissor.Y1 != 0 || scissor.X2 != 0xffff || scissor.Y2 != 0xffff);
- _context.Renderer.Pipeline.SetScissorEnable(index, enable);
-
if (enable)
{
int x = scissor.X1;
@@ -454,7 +452,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
height = (int)Math.Ceiling(height * scale);
}
- _context.Renderer.Pipeline.SetScissor(index, x, y, width, height);
+ _context.Renderer.Pipeline.SetScissor(index, true, x, y, width, height);
+ }
+ else
+ {
+ _context.Renderer.Pipeline.SetScissor(index, false, 0, 0, 0, 0);
}
}
}
diff --git a/Ryujinx.Graphics.OpenGL/Framebuffer.cs b/Ryujinx.Graphics.OpenGL/Framebuffer.cs
index 015b0ec0..66bf892b 100644
--- a/Ryujinx.Graphics.OpenGL/Framebuffer.cs
+++ b/Ryujinx.Graphics.OpenGL/Framebuffer.cs
@@ -2,6 +2,7 @@ using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL.Image;
using System;
+using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.OpenGL
{
@@ -29,21 +30,27 @@ namespace Ryujinx.Graphics.OpenGL
return Handle;
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AttachColor(int index, TextureView color)
{
+ if (_colors[index] == color)
+ {
+ return;
+ }
+
FramebufferAttachment attachment = FramebufferAttachment.ColorAttachment0 + index;
if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.Amd ||
HwCapabilities.Vendor == HwCapabilities.GpuVendor.Intel)
{
GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.GetIncompatibleFormatViewHandle() ?? 0, 0);
-
- _colors[index] = color;
}
else
{
GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.Handle ?? 0, 0);
}
+
+ _colors[index] = color;
}
public void AttachDepthStencil(TextureView depthStencil)
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index b6a34e9c..f42187bd 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.OpenGL
private readonly uint[] _componentMasks;
- private bool _scissor0Enable = false;
+ private uint _scissorEnables;
private bool _tfEnabled;
private TransformFeedbackPrimitiveType _tfTopology;
@@ -883,25 +883,27 @@ namespace Ryujinx.Graphics.OpenGL
((Sampler)sampler).Bind(binding);
}
- public void SetScissorEnable(int index, bool enable)
+ public void SetScissor(int index, bool enable, int x, int y, int width, int height)
{
- if (enable)
- {
- GL.Enable(IndexedEnableCap.ScissorTest, index);
- }
- else
+ uint mask = 1u << index;
+
+ if (!enable)
{
- GL.Disable(IndexedEnableCap.ScissorTest, index);
+ if ((_scissorEnables & mask) != 0)
+ {
+ _scissorEnables &= ~mask;
+ GL.Disable(IndexedEnableCap.ScissorTest, index);
+ }
+
+ return;
}
- if (index == 0)
+ if ((_scissorEnables & mask) == 0)
{
- _scissor0Enable = enable;
+ _scissorEnables |= mask;
+ GL.Enable(IndexedEnableCap.ScissorTest, index);
}
- }
- public void SetScissor(int index, int x, int y, int width, int height)
- {
GL.ScissorIndexed(index, x, y, width, height);
}
@@ -1241,7 +1243,7 @@ namespace Ryujinx.Graphics.OpenGL
public void RestoreScissor0Enable()
{
- if (_scissor0Enable)
+ if ((_scissorEnables & 1u) != 0)
{
GL.Enable(IndexedEnableCap.ScissorTest, 0);
}
diff --git a/Ryujinx.Graphics.OpenGL/VertexArray.cs b/Ryujinx.Graphics.OpenGL/VertexArray.cs
index 64c6a821..17703cd1 100644
--- a/Ryujinx.Graphics.OpenGL/VertexArray.cs
+++ b/Ryujinx.Graphics.OpenGL/VertexArray.cs
@@ -1,6 +1,7 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL;
using System;
+using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.OpenGL
{
@@ -16,6 +17,9 @@ namespace Ryujinx.Graphics.OpenGL
private int _vertexAttribsCount;
private int _vertexBuffersCount;
+ private uint _vertexAttribsInUse;
+ private uint _vertexBuffersInUse;
+
public VertexArray()
{
Handle = GL.GenVertexArray();
@@ -31,30 +35,30 @@ namespace Ryujinx.Graphics.OpenGL
public void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers)
{
- int bindingIndex = 0;
-
- for (int index = 0; index < vertexBuffers.Length; index++)
+ int bindingIndex;
+ for (bindingIndex = 0; bindingIndex < vertexBuffers.Length; bindingIndex++)
{
- VertexBufferDescriptor vb = vertexBuffers[index];
+ VertexBufferDescriptor vb = vertexBuffers[bindingIndex];
if (vb.Buffer.Handle != BufferHandle.Null)
{
GL.BindVertexBuffer(bindingIndex, vb.Buffer.Handle.ToInt32(), (IntPtr)vb.Buffer.Offset, vb.Stride);
-
GL.VertexBindingDivisor(bindingIndex, vb.Divisor);
+ _vertexBuffersInUse |= 1u << bindingIndex;
}
else
{
- GL.BindVertexBuffer(bindingIndex, 0, IntPtr.Zero, 0);
+ if ((_vertexBuffersInUse & (1u << bindingIndex)) != 0)
+ {
+ GL.BindVertexBuffer(bindingIndex, 0, IntPtr.Zero, 0);
+ _vertexBuffersInUse &= ~(1u << bindingIndex);
+ }
}
- _vertexBuffers[index] = vb;
-
- bindingIndex++;
+ _vertexBuffers[bindingIndex] = vb;
}
_vertexBuffersCount = bindingIndex;
-
_needsAttribsUpdate = true;
}
@@ -66,17 +70,22 @@ namespace Ryujinx.Graphics.OpenGL
{
VertexAttribDescriptor attrib = vertexAttribs[index];
+ if (attrib.Equals(_vertexAttribs[index]))
+ {
+ continue;
+ }
+
FormatInfo fmtInfo = FormatTable.GetFormatInfo(attrib.Format);
if (attrib.IsZero)
{
// Disabling the attribute causes the shader to read a constant value.
// The value is configurable, but by default is a vector of (0, 0, 0, 1).
- GL.DisableVertexAttribArray(index);
+ DisableVertexAttrib(index);
}
else
{
- GL.EnableVertexAttribArray(index);
+ EnableVertexAttrib(index);
}
int offset = attrib.Offset;
@@ -107,7 +116,7 @@ namespace Ryujinx.Graphics.OpenGL
for (; index < Constants.MaxVertexAttribs; index++)
{
- GL.DisableVertexAttribArray(index);
+ DisableVertexAttrib(index);
}
}
@@ -122,27 +131,52 @@ namespace Ryujinx.Graphics.OpenGL
{
VertexAttribDescriptor attrib = _vertexAttribs[attribIndex];
- if ((uint)attrib.BufferIndex >= _vertexBuffersCount)
+ if (!attrib.IsZero)
{
- GL.DisableVertexAttribArray(attribIndex);
-
- continue;
+ if ((uint)attrib.BufferIndex >= _vertexBuffersCount)
+ {
+ DisableVertexAttrib(attribIndex);
+ continue;
+ }
+
+ if (_vertexBuffers[attrib.BufferIndex].Buffer.Handle == BufferHandle.Null)
+ {
+ DisableVertexAttrib(attribIndex);
+ continue;
+ }
+
+ if (_needsAttribsUpdate)
+ {
+ EnableVertexAttrib(attribIndex);
+ }
}
+ }
- if (_vertexBuffers[attrib.BufferIndex].Buffer.Handle == BufferHandle.Null)
- {
- GL.DisableVertexAttribArray(attribIndex);
+ _needsAttribsUpdate = false;
+ }
- continue;
- }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void EnableVertexAttrib(int index)
+ {
+ uint mask = 1u << index;
- if (_needsAttribsUpdate && !attrib.IsZero)
- {
- GL.EnableVertexAttribArray(attribIndex);
- }
+ if ((_vertexAttribsInUse & mask) == 0)
+ {
+ _vertexAttribsInUse |= mask;
+ GL.EnableVertexAttribArray(index);
}
+ }
- _needsAttribsUpdate = false;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void DisableVertexAttrib(int index)
+ {
+ uint mask = 1u << index;
+
+ if ((_vertexAttribsInUse & mask) != 0)
+ {
+ _vertexAttribsInUse &= ~mask;
+ GL.DisableVertexAttribArray(index);
+ }
}
public void Dispose()