aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.OpenGL')
-rw-r--r--Ryujinx.Graphics.OpenGL/HwCapabilities.cs2
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs58
-rw-r--r--Ryujinx.Graphics.OpenGL/Renderer.cs1
-rw-r--r--Ryujinx.Graphics.OpenGL/VertexArray.cs22
4 files changed, 80 insertions, 3 deletions
diff --git a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
index 44365ca7..dd917b7b 100644
--- a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
+++ b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
@@ -13,6 +13,7 @@ namespace Ryujinx.Graphics.OpenGL
private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new Lazy<bool>(() => HasExtension("GL_ARB_seamless_cubemap_per_texture"));
private static readonly Lazy<bool> _supportsTextureShadowLod = new Lazy<bool>(() => HasExtension("GL_EXT_texture_shadow_lod"));
private static readonly Lazy<bool> _supportsViewportSwizzle = new Lazy<bool>(() => HasExtension("GL_NV_viewport_swizzle"));
+ private static readonly Lazy<bool> _supportsIndirectParameters = new Lazy<bool>(() => HasExtension("GL_ARB_indirect_parameters"));
private static readonly Lazy<int> _maximumComputeSharedMemorySize = new Lazy<int>(() => GetLimit(All.MaxComputeSharedMemorySize));
private static readonly Lazy<int> _storageBufferOffsetAlignment = new Lazy<int>(() => GetLimit(All.ShaderStorageBufferOffsetAlignment));
@@ -46,6 +47,7 @@ namespace Ryujinx.Graphics.OpenGL
public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value;
public static bool SupportsTextureShadowLod => _supportsTextureShadowLod.Value;
public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value;
+ public static bool SupportsIndirectParameters => _supportsIndirectParameters.Value;
public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.AmdWindows && _gpuVendor.Value != GpuVendor.IntelWindows;
public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia;
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index be526fa9..24dd97f9 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -166,6 +166,11 @@ namespace Ryujinx.Graphics.OpenGL
}
}
+ public void CommandBufferBarrier()
+ {
+ GL.MemoryBarrier(MemoryBarrierFlags.CommandBarrierBit);
+ }
+
public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
{
Buffer.Copy(source, destination, srcOffset, dstOffset, size);
@@ -543,6 +548,57 @@ namespace Ryujinx.Graphics.OpenGL
_tfEnabled = false;
}
+ public void MultiDrawIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
+ {
+ if (!_program.IsLinked)
+ {
+ Logger.Debug?.Print(LogClass.Gpu, "Draw error, shader not linked.");
+ return;
+ }
+
+ PreDraw();
+
+ GL.BindBuffer((BufferTarget)All.DrawIndirectBuffer, indirectBuffer.Handle.ToInt32());
+ GL.BindBuffer((BufferTarget)All.ParameterBuffer, parameterBuffer.Handle.ToInt32());
+
+ GL.MultiDrawArraysIndirectCount(
+ _primitiveType,
+ (IntPtr)indirectBuffer.Offset,
+ (IntPtr)parameterBuffer.Offset,
+ maxDrawCount,
+ stride);
+
+ PostDraw();
+ }
+
+ public void MultiDrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
+ {
+ if (!_program.IsLinked)
+ {
+ Logger.Debug?.Print(LogClass.Gpu, "Draw error, shader not linked.");
+ return;
+ }
+
+ PreDraw();
+
+ _vertexArray.SetRangeOfIndexBuffer();
+
+ GL.BindBuffer((BufferTarget)All.DrawIndirectBuffer, indirectBuffer.Handle.ToInt32());
+ GL.BindBuffer((BufferTarget)All.ParameterBuffer, parameterBuffer.Handle.ToInt32());
+
+ GL.MultiDrawElementsIndirectCount(
+ _primitiveType,
+ (Version46)_elementsType,
+ (IntPtr)indirectBuffer.Offset,
+ (IntPtr)parameterBuffer.Offset,
+ maxDrawCount,
+ stride);
+
+ _vertexArray.RestoreIndexBuffer();
+
+ PostDraw();
+ }
+
public void SetAlphaTest(bool enable, float reference, CompareOp op)
{
if (!enable)
@@ -741,7 +797,7 @@ namespace Ryujinx.Graphics.OpenGL
EnsureVertexArray();
- _vertexArray.SetIndexBuffer(buffer.Handle);
+ _vertexArray.SetIndexBuffer(buffer);
}
public void SetLogicOpState(bool enable, LogicalOp op)
diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs
index 01072176..6b620bb8 100644
--- a/Ryujinx.Graphics.OpenGL/Renderer.cs
+++ b/Ryujinx.Graphics.OpenGL/Renderer.cs
@@ -107,6 +107,7 @@ namespace Ryujinx.Graphics.OpenGL
HwCapabilities.SupportsNonConstantTextureOffset,
HwCapabilities.SupportsTextureShadowLod,
HwCapabilities.SupportsViewportSwizzle,
+ HwCapabilities.SupportsIndirectParameters,
HwCapabilities.MaximumComputeSharedMemorySize,
HwCapabilities.MaximumSupportedAnisotropy,
HwCapabilities.StorageBufferOffsetAlignment);
diff --git a/Ryujinx.Graphics.OpenGL/VertexArray.cs b/Ryujinx.Graphics.OpenGL/VertexArray.cs
index f2fcba1f..bdf14481 100644
--- a/Ryujinx.Graphics.OpenGL/VertexArray.cs
+++ b/Ryujinx.Graphics.OpenGL/VertexArray.cs
@@ -20,12 +20,17 @@ namespace Ryujinx.Graphics.OpenGL
private uint _vertexAttribsInUse;
private uint _vertexBuffersInUse;
+ private BufferRange _indexBuffer;
+ private BufferHandle _tempIndexBuffer;
+
public VertexArray()
{
Handle = GL.GenVertexArray();
_vertexAttribs = new VertexAttribDescriptor[Constants.MaxVertexAttribs];
_vertexBuffers = new VertexBufferDescriptor[Constants.MaxVertexBuffers];
+
+ _tempIndexBuffer = Buffer.Create();
}
public void Bind()
@@ -120,9 +125,22 @@ namespace Ryujinx.Graphics.OpenGL
}
}
- public void SetIndexBuffer(BufferHandle buffer)
+ public void SetIndexBuffer(BufferRange range)
+ {
+ _indexBuffer = range;
+ GL.BindBuffer(BufferTarget.ElementArrayBuffer, range.Handle.ToInt32());
+ }
+
+ public void SetRangeOfIndexBuffer()
+ {
+ Buffer.Resize(_tempIndexBuffer, _indexBuffer.Size);
+ Buffer.Copy(_indexBuffer.Handle, _tempIndexBuffer, _indexBuffer.Offset, 0, _indexBuffer.Size);
+ GL.BindBuffer(BufferTarget.ElementArrayBuffer, _tempIndexBuffer.ToInt32());
+ }
+
+ public void RestoreIndexBuffer()
{
- GL.BindBuffer(BufferTarget.ElementArrayBuffer, buffer.ToInt32());
+ GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer.Handle.ToInt32());
}
public void Validate()