diff options
Diffstat (limited to 'Ryujinx.Graphics.OpenGL')
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/HwCapabilities.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Pipeline.cs | 58 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Renderer.cs | 1 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/VertexArray.cs | 22 |
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() |
