From 38d900c9325db6794f4085d01e582d0896b98c87 Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Thu, 9 May 2024 19:13:37 -0400 Subject: [PATCH] PersistentBuffers & Sync --- Directory.Packages.props | 1 + src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs | 7 +- .../PersistentBuffers.cs | 72 +++++++++++-------- .../Ryujinx.Graphics.OpenGL.csproj | 1 + src/Ryujinx.Graphics.OpenGL/Sync.cs | 4 +- 5 files changed, 52 insertions(+), 33 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 69b3ccdac..86fb6c688 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -39,6 +39,7 @@ + diff --git a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs index 176b3527b..60638c647 100644 --- a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs +++ b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs @@ -5,6 +5,7 @@ using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.OpenGL.Image; using Ryujinx.Graphics.OpenGL.Queries; using Ryujinx.Graphics.Shader.Translation; +using Silk.NET.OpenGL.Legacy.Extensions.ARB; using System; using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler; @@ -56,7 +57,7 @@ namespace Ryujinx.Graphics.OpenGL TextureCopyIncompatible = new TextureCopyIncompatible(this); TextureCopyMS = new TextureCopyMS(this); _sync = new Sync(Api); - PersistentBuffers = new PersistentBuffers(); + PersistentBuffers = new PersistentBuffers(Api); ResourcePool = new ResourcePool(); } @@ -232,7 +233,9 @@ namespace Ryujinx.Graphics.OpenGL if (HwCapabilities.SupportsParallelShaderCompile) { - GL.Arb.MaxShaderCompilerThreads(Math.Min(Environment.ProcessorCount, 8)); + Api.TryGetExtension(out ArbParallelShaderCompile arbParallelShaderCompile); + + arbParallelShaderCompile.MaxShaderCompilerThreads((uint)Math.Min(Environment.ProcessorCount, 8)); } _counters.Initialize(); diff --git a/src/Ryujinx.Graphics.OpenGL/PersistentBuffers.cs b/src/Ryujinx.Graphics.OpenGL/PersistentBuffers.cs index 3ba8b1e19..181799d88 100644 --- a/src/Ryujinx.Graphics.OpenGL/PersistentBuffers.cs +++ b/src/Ryujinx.Graphics.OpenGL/PersistentBuffers.cs @@ -11,33 +11,41 @@ namespace Ryujinx.Graphics.OpenGL { class PersistentBuffers : IDisposable { - private readonly PersistentBuffer _main = new(); - private readonly PersistentBuffer _background = new(); + private readonly GL _api; + private readonly PersistentBuffer _main; + private readonly PersistentBuffer _background; private readonly Dictionary _maps = new(); public PersistentBuffer Default => BackgroundContextWorker.InBackground ? _background : _main; + public PersistentBuffers(GL api) + { + _api = api; + _main = new(_api); + _background = new(_api); + } + public void Dispose() { _main?.Dispose(); _background?.Dispose(); } - public void Map(BufferHandle handle, int size) + public unsafe void Map(BufferHandle handle, int size) { - GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32()); - IntPtr ptr = GL.MapBufferRange(BufferTargetARB.CopyWriteBuffer, IntPtr.Zero, size, BufferAccessMask.MapReadBit | BufferAccessMask.MapPersistentBit); + _api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32()); + void* ptr = _api.MapBufferRange(BufferTargetARB.CopyWriteBuffer, IntPtr.Zero, (uint)size, MapBufferAccessMask.ReadBit | MapBufferAccessMask.PersistentBit); - _maps[handle] = ptr; + _maps[handle] = new IntPtr(ptr); } public void Unmap(BufferHandle handle) { if (_maps.ContainsKey(handle)) { - GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32()); - GL.UnmapBuffer(BufferTargetARB.CopyWriteBuffer); + _api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32()); + _api.UnmapBuffer(BufferTargetARB.CopyWriteBuffer); _maps.Remove(handle); } @@ -51,6 +59,7 @@ namespace Ryujinx.Graphics.OpenGL class PersistentBuffer : IDisposable { + private readonly GL _api; private IntPtr _bufferMap; private uint _copyBufferHandle; private int _copyBufferSize; @@ -58,24 +67,29 @@ namespace Ryujinx.Graphics.OpenGL private byte[] _data; private IntPtr _dataMap; - private void EnsureBuffer(int requiredSize) + public PersistentBuffer(GL api) + { + _api = api; + } + + private unsafe void EnsureBuffer(int requiredSize) { if (_copyBufferSize < requiredSize && _copyBufferHandle != 0) { - GL.DeleteBuffer(_copyBufferHandle); + _api.DeleteBuffer(_copyBufferHandle); _copyBufferHandle = 0; } if (_copyBufferHandle == 0) { - _copyBufferHandle = GL.GenBuffer(); + _copyBufferHandle = _api.GenBuffer(); _copyBufferSize = requiredSize; - GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle); - GL.BufferStorage(BufferTargetARB.CopyWriteBuffer, requiredSize, IntPtr.Zero, BufferStorageFlags.MapReadBit | BufferStorageFlags.MapPersistentBit); + _api.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle); + _api.BufferStorage(BufferStorageTarget.CopyWriteBuffer, (uint)requiredSize, IntPtr.Zero, BufferStorageMask.MapReadBit | BufferStorageMask.MapPersistentBit); - _bufferMap = GL.MapBufferRange(BufferTargetARB.CopyWriteBuffer, IntPtr.Zero, requiredSize, BufferAccessMask.MapReadBit | BufferAccessMask.MapPersistentBit); + _bufferMap = new IntPtr(_api.MapBufferRange(BufferTargetARB.CopyWriteBuffer, IntPtr.Zero, (uint)requiredSize, MapBufferAccessMask.ReadBit | MapBufferAccessMask.PersistentBit)); } } @@ -91,30 +105,30 @@ namespace Ryujinx.Graphics.OpenGL return _dataMap; } - private static void Sync() + private void Sync() { - GL.MemoryBarrier(MemoryBarrierMask.ClientMappedBufferBarrierBit); + _api.MemoryBarrier(MemoryBarrierMask.ClientMappedBufferBarrierBit); - IntPtr sync = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None); - WaitSyncStatus syncResult = GL.ClientWaitSync(sync, ClientWaitSyncFlags.SyncFlushCommandsBit, 1000000000); + IntPtr sync = _api.FenceSync(SyncCondition.SyncGpuCommandsComplete, SyncBehaviorFlags.None); + GLEnum syncResult = _api.ClientWaitSync(sync, SyncObjectMask.Bit, 1000000000); - if (syncResult == WaitSyncStatus.TimeoutExpired) + if (syncResult == GLEnum.TimeoutExpired) { Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to sync persistent buffer state within 1000ms. Continuing..."); } - GL.DeleteSync(sync); + _api.DeleteSync(sync); } public unsafe ReadOnlySpan GetTextureData(TextureView view, int size) { EnsureBuffer(size); - GL.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle); + _api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle); view.WriteToPbo(0, false); - GL.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); + _api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); Sync(); @@ -125,11 +139,11 @@ namespace Ryujinx.Graphics.OpenGL { EnsureBuffer(size); - GL.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle); + _api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle); int offset = view.WriteToPbo2D(0, layer, level); - GL.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); + _api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); Sync(); @@ -140,12 +154,12 @@ namespace Ryujinx.Graphics.OpenGL { EnsureBuffer(size); - GL.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32()); - GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle); + _api.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32()); + _api.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle); - GL.CopyBufferSubData(BufferTargetARB.CopyReadBuffer, BufferTargetARB.CopyWriteBuffer, (IntPtr)offset, IntPtr.Zero, size); + _api.CopyBufferSubData(CopyBufferSubDataTarget.CopyReadBuffer, CopyBufferSubDataTarget.CopyWriteBuffer, offset, IntPtr.Zero, (uint)size); - GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, 0); + _api.BindBuffer(BufferTargetARB.CopyWriteBuffer, 0); Sync(); @@ -156,7 +170,7 @@ namespace Ryujinx.Graphics.OpenGL { if (_copyBufferHandle != 0) { - GL.DeleteBuffer(_copyBufferHandle); + _api.DeleteBuffer(_copyBufferHandle); } } } diff --git a/src/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj b/src/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj index bcfde2236..fefc36f98 100644 --- a/src/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj +++ b/src/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj @@ -7,6 +7,7 @@ + diff --git a/src/Ryujinx.Graphics.OpenGL/Sync.cs b/src/Ryujinx.Graphics.OpenGL/Sync.cs index 7b0334968..f853c4f88 100644 --- a/src/Ryujinx.Graphics.OpenGL/Sync.cs +++ b/src/Ryujinx.Graphics.OpenGL/Sync.cs @@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.OpenGL } private ulong _firstHandle = 0; - private static SyncBehaviorFlags SyncFlags => HwCapabilities.RequiresSyncFlush ? SyncBehaviorFlags.None : SyncBehaviorFlags.SyncFlushCommandsBit; + private static SyncObjectMask SyncFlags => HwCapabilities.RequiresSyncFlush ? 0 : SyncObjectMask.Bit; private readonly List _handles = new(); private readonly GL _api; @@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.OpenGL if (HwCapabilities.RequiresSyncFlush) { // Force commands to flush up to the syncpoint. - _api.ClientWaitSync(handle.Handle, SyncBehaviorFlags.SyncFlushCommandsBit, 0); + _api.ClientWaitSync(handle.Handle, SyncObjectMask.Bit, 0); } lock (_handles)