PersistentBuffers & Sync

This commit is contained in:
Isaac Marovitz 2024-05-09 19:13:37 -04:00
parent 740842d600
commit 38d900c932
No known key found for this signature in database
GPG key ID: 97250B2B09A132E1
5 changed files with 52 additions and 33 deletions

View file

@ -39,6 +39,7 @@
<PackageVersion Include="shaderc.net" Version="0.1.0" /> <PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" /> <PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.OpenGL.Legacy" Version="2.21.0" /> <PackageVersion Include="Silk.NET.OpenGL.Legacy" Version="2.21.0" />
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.ARB" Version="2.21.0" />
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.EXT" Version="2.21.0" /> <PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.EXT" Version="2.21.0" />
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.NV" Version="2.21.0" /> <PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.NV" Version="2.21.0" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" /> <PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />

View file

@ -5,6 +5,7 @@ using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL.Image; using Ryujinx.Graphics.OpenGL.Image;
using Ryujinx.Graphics.OpenGL.Queries; using Ryujinx.Graphics.OpenGL.Queries;
using Ryujinx.Graphics.Shader.Translation; using Ryujinx.Graphics.Shader.Translation;
using Silk.NET.OpenGL.Legacy.Extensions.ARB;
using System; using System;
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler; using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
@ -56,7 +57,7 @@ namespace Ryujinx.Graphics.OpenGL
TextureCopyIncompatible = new TextureCopyIncompatible(this); TextureCopyIncompatible = new TextureCopyIncompatible(this);
TextureCopyMS = new TextureCopyMS(this); TextureCopyMS = new TextureCopyMS(this);
_sync = new Sync(Api); _sync = new Sync(Api);
PersistentBuffers = new PersistentBuffers(); PersistentBuffers = new PersistentBuffers(Api);
ResourcePool = new ResourcePool(); ResourcePool = new ResourcePool();
} }
@ -232,7 +233,9 @@ namespace Ryujinx.Graphics.OpenGL
if (HwCapabilities.SupportsParallelShaderCompile) 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(); _counters.Initialize();

View file

@ -11,33 +11,41 @@ namespace Ryujinx.Graphics.OpenGL
{ {
class PersistentBuffers : IDisposable class PersistentBuffers : IDisposable
{ {
private readonly PersistentBuffer _main = new(); private readonly GL _api;
private readonly PersistentBuffer _background = new(); private readonly PersistentBuffer _main;
private readonly PersistentBuffer _background;
private readonly Dictionary<BufferHandle, IntPtr> _maps = new(); private readonly Dictionary<BufferHandle, IntPtr> _maps = new();
public PersistentBuffer Default => BackgroundContextWorker.InBackground ? _background : _main; public PersistentBuffer Default => BackgroundContextWorker.InBackground ? _background : _main;
public PersistentBuffers(GL api)
{
_api = api;
_main = new(_api);
_background = new(_api);
}
public void Dispose() public void Dispose()
{ {
_main?.Dispose(); _main?.Dispose();
_background?.Dispose(); _background?.Dispose();
} }
public void Map(BufferHandle handle, int size) public unsafe void Map(BufferHandle handle, int size)
{ {
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32()); _api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32());
IntPtr ptr = GL.MapBufferRange(BufferTargetARB.CopyWriteBuffer, IntPtr.Zero, size, BufferAccessMask.MapReadBit | BufferAccessMask.MapPersistentBit); 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) public void Unmap(BufferHandle handle)
{ {
if (_maps.ContainsKey(handle)) if (_maps.ContainsKey(handle))
{ {
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32()); _api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32());
GL.UnmapBuffer(BufferTargetARB.CopyWriteBuffer); _api.UnmapBuffer(BufferTargetARB.CopyWriteBuffer);
_maps.Remove(handle); _maps.Remove(handle);
} }
@ -51,6 +59,7 @@ namespace Ryujinx.Graphics.OpenGL
class PersistentBuffer : IDisposable class PersistentBuffer : IDisposable
{ {
private readonly GL _api;
private IntPtr _bufferMap; private IntPtr _bufferMap;
private uint _copyBufferHandle; private uint _copyBufferHandle;
private int _copyBufferSize; private int _copyBufferSize;
@ -58,24 +67,29 @@ namespace Ryujinx.Graphics.OpenGL
private byte[] _data; private byte[] _data;
private IntPtr _dataMap; 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) if (_copyBufferSize < requiredSize && _copyBufferHandle != 0)
{ {
GL.DeleteBuffer(_copyBufferHandle); _api.DeleteBuffer(_copyBufferHandle);
_copyBufferHandle = 0; _copyBufferHandle = 0;
} }
if (_copyBufferHandle == 0) if (_copyBufferHandle == 0)
{ {
_copyBufferHandle = GL.GenBuffer(); _copyBufferHandle = _api.GenBuffer();
_copyBufferSize = requiredSize; _copyBufferSize = requiredSize;
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle); _api.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle);
GL.BufferStorage(BufferTargetARB.CopyWriteBuffer, requiredSize, IntPtr.Zero, BufferStorageFlags.MapReadBit | BufferStorageFlags.MapPersistentBit); _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; 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); IntPtr sync = _api.FenceSync(SyncCondition.SyncGpuCommandsComplete, SyncBehaviorFlags.None);
WaitSyncStatus syncResult = GL.ClientWaitSync(sync, ClientWaitSyncFlags.SyncFlushCommandsBit, 1000000000); 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..."); Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to sync persistent buffer state within 1000ms. Continuing...");
} }
GL.DeleteSync(sync); _api.DeleteSync(sync);
} }
public unsafe ReadOnlySpan<byte> GetTextureData(TextureView view, int size) public unsafe ReadOnlySpan<byte> GetTextureData(TextureView view, int size)
{ {
EnsureBuffer(size); EnsureBuffer(size);
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle); _api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle);
view.WriteToPbo(0, false); view.WriteToPbo(0, false);
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); _api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
Sync(); Sync();
@ -125,11 +139,11 @@ namespace Ryujinx.Graphics.OpenGL
{ {
EnsureBuffer(size); EnsureBuffer(size);
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle); _api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle);
int offset = view.WriteToPbo2D(0, layer, level); int offset = view.WriteToPbo2D(0, layer, level);
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); _api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
Sync(); Sync();
@ -140,12 +154,12 @@ namespace Ryujinx.Graphics.OpenGL
{ {
EnsureBuffer(size); EnsureBuffer(size);
GL.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32()); _api.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32());
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle); _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(); Sync();
@ -156,7 +170,7 @@ namespace Ryujinx.Graphics.OpenGL
{ {
if (_copyBufferHandle != 0) if (_copyBufferHandle != 0)
{ {
GL.DeleteBuffer(_copyBufferHandle); _api.DeleteBuffer(_copyBufferHandle);
} }
} }
} }

View file

@ -7,6 +7,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Silk.NET.OpenGL.Legacy" /> <PackageReference Include="Silk.NET.OpenGL.Legacy" />
<PackageReference Include="Silk.NET.OpenGL.Legacy.Extensions.ARB" />
<PackageReference Include="Silk.NET.OpenGL.Legacy.Extensions.EXT" /> <PackageReference Include="Silk.NET.OpenGL.Legacy.Extensions.EXT" />
<PackageReference Include="Silk.NET.OpenGL.Legacy.Extensions.NV" /> <PackageReference Include="Silk.NET.OpenGL.Legacy.Extensions.NV" />
</ItemGroup> </ItemGroup>

View file

@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.OpenGL
} }
private ulong _firstHandle = 0; 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<SyncHandle> _handles = new(); private readonly List<SyncHandle> _handles = new();
private readonly GL _api; private readonly GL _api;
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.OpenGL
if (HwCapabilities.RequiresSyncFlush) if (HwCapabilities.RequiresSyncFlush)
{ {
// Force commands to flush up to the syncpoint. // Force commands to flush up to the syncpoint.
_api.ClientWaitSync(handle.Handle, SyncBehaviorFlags.SyncFlushCommandsBit, 0); _api.ClientWaitSync(handle.Handle, SyncObjectMask.Bit, 0);
} }
lock (_handles) lock (_handles)