Avoid some redundant GL calls (#1958)
This commit is contained in:
parent
d6bd0470fb
commit
caf049ed15
6 changed files with 115 additions and 51 deletions
|
@ -68,8 +68,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
void SetSampler(int binding, ISampler sampler);
|
void SetSampler(int binding, ISampler sampler);
|
||||||
|
|
||||||
void SetScissorEnable(int index, bool enable);
|
void SetScissor(int index, bool enable, int x, int y, int width, int height);
|
||||||
void SetScissor(int index, int x, int y, int width, int height);
|
|
||||||
|
|
||||||
void SetStencilTest(StencilTestDescriptor stencilTest);
|
void SetStencilTest(StencilTestDescriptor stencilTest);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL
|
namespace Ryujinx.Graphics.GAL
|
||||||
{
|
{
|
||||||
public struct VertexAttribDescriptor
|
public struct VertexAttribDescriptor : IEquatable<VertexAttribDescriptor>
|
||||||
{
|
{
|
||||||
public int BufferIndex { get; }
|
public int BufferIndex { get; }
|
||||||
public int Offset { get; }
|
public int Offset { get; }
|
||||||
|
@ -16,5 +18,23 @@ namespace Ryujinx.Graphics.GAL
|
||||||
IsZero = isZero;
|
IsZero = isZero;
|
||||||
Format = format;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
bool enable = scissor.Enable && (scissor.X1 != 0 || scissor.Y1 != 0 || scissor.X2 != 0xffff || scissor.Y2 != 0xffff);
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetScissorEnable(index, enable);
|
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
int x = scissor.X1;
|
int x = scissor.X1;
|
||||||
|
@ -454,7 +452,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
height = (int)Math.Ceiling(height * scale);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ using OpenTK.Graphics.OpenGL;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.OpenGL.Image;
|
using Ryujinx.Graphics.OpenGL.Image;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.OpenGL
|
namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
|
@ -29,21 +30,27 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
return Handle;
|
return Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void AttachColor(int index, TextureView color)
|
public void AttachColor(int index, TextureView color)
|
||||||
{
|
{
|
||||||
|
if (_colors[index] == color)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FramebufferAttachment attachment = FramebufferAttachment.ColorAttachment0 + index;
|
FramebufferAttachment attachment = FramebufferAttachment.ColorAttachment0 + index;
|
||||||
|
|
||||||
if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.Amd ||
|
if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.Amd ||
|
||||||
HwCapabilities.Vendor == HwCapabilities.GpuVendor.Intel)
|
HwCapabilities.Vendor == HwCapabilities.GpuVendor.Intel)
|
||||||
{
|
{
|
||||||
GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.GetIncompatibleFormatViewHandle() ?? 0, 0);
|
GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.GetIncompatibleFormatViewHandle() ?? 0, 0);
|
||||||
|
|
||||||
_colors[index] = color;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.Handle ?? 0, 0);
|
GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.Handle ?? 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_colors[index] = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AttachDepthStencil(TextureView depthStencil)
|
public void AttachDepthStencil(TextureView depthStencil)
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
private readonly uint[] _componentMasks;
|
private readonly uint[] _componentMasks;
|
||||||
|
|
||||||
private bool _scissor0Enable = false;
|
private uint _scissorEnables;
|
||||||
|
|
||||||
private bool _tfEnabled;
|
private bool _tfEnabled;
|
||||||
private TransformFeedbackPrimitiveType _tfTopology;
|
private TransformFeedbackPrimitiveType _tfTopology;
|
||||||
|
@ -883,25 +883,27 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
((Sampler)sampler).Bind(binding);
|
((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)
|
uint mask = 1u << index;
|
||||||
|
|
||||||
|
if (!enable)
|
||||||
{
|
{
|
||||||
|
if ((_scissorEnables & mask) != 0)
|
||||||
|
{
|
||||||
|
_scissorEnables &= ~mask;
|
||||||
|
GL.Disable(IndexedEnableCap.ScissorTest, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_scissorEnables & mask) == 0)
|
||||||
|
{
|
||||||
|
_scissorEnables |= mask;
|
||||||
GL.Enable(IndexedEnableCap.ScissorTest, index);
|
GL.Enable(IndexedEnableCap.ScissorTest, index);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
GL.Disable(IndexedEnableCap.ScissorTest, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == 0)
|
|
||||||
{
|
|
||||||
_scissor0Enable = enable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetScissor(int index, int x, int y, int width, int height)
|
|
||||||
{
|
|
||||||
GL.ScissorIndexed(index, x, y, width, height);
|
GL.ScissorIndexed(index, x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1241,7 +1243,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public void RestoreScissor0Enable()
|
public void RestoreScissor0Enable()
|
||||||
{
|
{
|
||||||
if (_scissor0Enable)
|
if ((_scissorEnables & 1u) != 0)
|
||||||
{
|
{
|
||||||
GL.Enable(IndexedEnableCap.ScissorTest, 0);
|
GL.Enable(IndexedEnableCap.ScissorTest, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.OpenGL
|
namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
|
@ -16,6 +17,9 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
private int _vertexAttribsCount;
|
private int _vertexAttribsCount;
|
||||||
private int _vertexBuffersCount;
|
private int _vertexBuffersCount;
|
||||||
|
|
||||||
|
private uint _vertexAttribsInUse;
|
||||||
|
private uint _vertexBuffersInUse;
|
||||||
|
|
||||||
public VertexArray()
|
public VertexArray()
|
||||||
{
|
{
|
||||||
Handle = GL.GenVertexArray();
|
Handle = GL.GenVertexArray();
|
||||||
|
@ -31,30 +35,30 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers)
|
public void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers)
|
||||||
{
|
{
|
||||||
int bindingIndex = 0;
|
int bindingIndex;
|
||||||
|
for (bindingIndex = 0; bindingIndex < vertexBuffers.Length; bindingIndex++)
|
||||||
for (int index = 0; index < vertexBuffers.Length; index++)
|
|
||||||
{
|
{
|
||||||
VertexBufferDescriptor vb = vertexBuffers[index];
|
VertexBufferDescriptor vb = vertexBuffers[bindingIndex];
|
||||||
|
|
||||||
if (vb.Buffer.Handle != BufferHandle.Null)
|
if (vb.Buffer.Handle != BufferHandle.Null)
|
||||||
{
|
{
|
||||||
GL.BindVertexBuffer(bindingIndex, vb.Buffer.Handle.ToInt32(), (IntPtr)vb.Buffer.Offset, vb.Stride);
|
GL.BindVertexBuffer(bindingIndex, vb.Buffer.Handle.ToInt32(), (IntPtr)vb.Buffer.Offset, vb.Stride);
|
||||||
|
|
||||||
GL.VertexBindingDivisor(bindingIndex, vb.Divisor);
|
GL.VertexBindingDivisor(bindingIndex, vb.Divisor);
|
||||||
|
_vertexBuffersInUse |= 1u << bindingIndex;
|
||||||
}
|
}
|
||||||
else
|
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;
|
_vertexBuffers[bindingIndex] = vb;
|
||||||
|
|
||||||
bindingIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_vertexBuffersCount = bindingIndex;
|
_vertexBuffersCount = bindingIndex;
|
||||||
|
|
||||||
_needsAttribsUpdate = true;
|
_needsAttribsUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,17 +70,22 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
VertexAttribDescriptor attrib = vertexAttribs[index];
|
VertexAttribDescriptor attrib = vertexAttribs[index];
|
||||||
|
|
||||||
|
if (attrib.Equals(_vertexAttribs[index]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
FormatInfo fmtInfo = FormatTable.GetFormatInfo(attrib.Format);
|
FormatInfo fmtInfo = FormatTable.GetFormatInfo(attrib.Format);
|
||||||
|
|
||||||
if (attrib.IsZero)
|
if (attrib.IsZero)
|
||||||
{
|
{
|
||||||
// Disabling the attribute causes the shader to read a constant value.
|
// 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).
|
// The value is configurable, but by default is a vector of (0, 0, 0, 1).
|
||||||
GL.DisableVertexAttribArray(index);
|
DisableVertexAttrib(index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GL.EnableVertexAttribArray(index);
|
EnableVertexAttrib(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int offset = attrib.Offset;
|
int offset = attrib.Offset;
|
||||||
|
@ -107,7 +116,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
for (; index < Constants.MaxVertexAttribs; index++)
|
for (; index < Constants.MaxVertexAttribs; index++)
|
||||||
{
|
{
|
||||||
GL.DisableVertexAttribArray(index);
|
DisableVertexAttrib(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,29 +131,54 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
VertexAttribDescriptor attrib = _vertexAttribs[attribIndex];
|
VertexAttribDescriptor attrib = _vertexAttribs[attribIndex];
|
||||||
|
|
||||||
if ((uint)attrib.BufferIndex >= _vertexBuffersCount)
|
if (!attrib.IsZero)
|
||||||
{
|
{
|
||||||
GL.DisableVertexAttribArray(attribIndex);
|
if ((uint)attrib.BufferIndex >= _vertexBuffersCount)
|
||||||
|
{
|
||||||
|
DisableVertexAttrib(attribIndex);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
if (_vertexBuffers[attrib.BufferIndex].Buffer.Handle == BufferHandle.Null)
|
||||||
}
|
{
|
||||||
|
DisableVertexAttrib(attribIndex);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (_vertexBuffers[attrib.BufferIndex].Buffer.Handle == BufferHandle.Null)
|
if (_needsAttribsUpdate)
|
||||||
{
|
{
|
||||||
GL.DisableVertexAttribArray(attribIndex);
|
EnableVertexAttrib(attribIndex);
|
||||||
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_needsAttribsUpdate && !attrib.IsZero)
|
|
||||||
{
|
|
||||||
GL.EnableVertexAttribArray(attribIndex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_needsAttribsUpdate = false;
|
_needsAttribsUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private void EnableVertexAttrib(int index)
|
||||||
|
{
|
||||||
|
uint mask = 1u << index;
|
||||||
|
|
||||||
|
if ((_vertexAttribsInUse & mask) == 0)
|
||||||
|
{
|
||||||
|
_vertexAttribsInUse |= mask;
|
||||||
|
GL.EnableVertexAttribArray(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private void DisableVertexAttrib(int index)
|
||||||
|
{
|
||||||
|
uint mask = 1u << index;
|
||||||
|
|
||||||
|
if ((_vertexAttribsInUse & mask) != 0)
|
||||||
|
{
|
||||||
|
_vertexAttribsInUse &= ~mask;
|
||||||
|
GL.DisableVertexAttribArray(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (Handle != 0)
|
if (Handle != 0)
|
||||||
|
|
Reference in a new issue