diff options
author | riperiperi <rhy3756547@hotmail.com> | 2022-11-24 07:50:59 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-24 07:50:59 +0000 |
commit | ece36b274da3957d727387d2f7c96adbd0f29bc3 (patch) | |
tree | e4f024265342c69eba254083a4308c32a5aad83d /Ryujinx.Graphics.GAL/Multithreading | |
parent | f3cc2e5703e5df5c359ce1789a4fb0d73fb9a637 (diff) |
GAL: Send all buffer assignments at once rather than individually (#3881)1.1.377
* GAL: Send all buffer assignments at once rather than individually
The `(int first, BufferRange[] ranges)` method call has very significant performance implications when the bindings are spread out, which they generally always are in Vulkan. This change makes it so that these methods are only called a maximum of one time per draw.
Significantly improves GPU thread performance in Pokemon Scarlet/Violet.
* Address Feedback
Removed SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers)
Diffstat (limited to 'Ryujinx.Graphics.GAL/Multithreading')
4 files changed, 36 insertions, 16 deletions
diff --git a/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs b/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs index fcf09f9f..24b0af2d 100644 --- a/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs +++ b/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs @@ -142,6 +142,30 @@ namespace Ryujinx.Graphics.GAL.Multithreading return ranges; } + internal Span<BufferAssignment> MapBufferRanges(Span<BufferAssignment> ranges) + { + // Rewrite the buffer ranges to point to the mapped handles. + + lock (_bufferMap) + { + for (int i = 0; i < ranges.Length; i++) + { + ref BufferAssignment assignment = ref ranges[i]; + BufferRange range = assignment.Range; + BufferHandle result; + + if (!_bufferMap.TryGetValue(range.Handle, out result)) + { + result = BufferHandle.Null; + } + + assignment = new BufferAssignment(ranges[i].Binding, new BufferRange(result, range.Offset, range.Size)); + } + } + + return ranges; + } + internal Span<VertexBufferDescriptor> MapBufferRanges(Span<VertexBufferDescriptor> ranges) { // Rewrite the buffer ranges to point to the mapped handles. diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs index c2963373..610603ca 100644 --- a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs +++ b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs @@ -6,19 +6,17 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands struct SetStorageBuffersCommand : IGALCommand { public CommandType CommandType => CommandType.SetStorageBuffers; - private int _first; - private SpanRef<BufferRange> _buffers; + private SpanRef<BufferAssignment> _buffers; - public void Set(int first, SpanRef<BufferRange> buffers) + public void Set(SpanRef<BufferAssignment> buffers) { - _first = first; _buffers = buffers; } public static void Run(ref SetStorageBuffersCommand command, ThreadedRenderer threaded, IRenderer renderer) { - Span<BufferRange> buffers = command._buffers.Get(threaded); - renderer.Pipeline.SetStorageBuffers(command._first, threaded.Buffers.MapBufferRanges(buffers)); + Span<BufferAssignment> buffers = command._buffers.Get(threaded); + renderer.Pipeline.SetStorageBuffers(threaded.Buffers.MapBufferRanges(buffers)); command._buffers.Dispose(threaded); } } diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs index 750d8dac..e4abb403 100644 --- a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs +++ b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs @@ -6,19 +6,17 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands struct SetUniformBuffersCommand : IGALCommand { public CommandType CommandType => CommandType.SetUniformBuffers; - private int _first; - private SpanRef<BufferRange> _buffers; + private SpanRef<BufferAssignment> _buffers; - public void Set(int first, SpanRef<BufferRange> buffers) + public void Set(SpanRef<BufferAssignment> buffers) { - _first = first; _buffers = buffers; } public static void Run(ref SetUniformBuffersCommand command, ThreadedRenderer threaded, IRenderer renderer) { - Span<BufferRange> buffers = command._buffers.Get(threaded); - renderer.Pipeline.SetUniformBuffers(command._first, threaded.Buffers.MapBufferRanges(buffers)); + Span<BufferAssignment> buffers = command._buffers.Get(threaded); + renderer.Pipeline.SetUniformBuffers(threaded.Buffers.MapBufferRanges(buffers)); command._buffers.Dispose(threaded); } } diff --git a/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs b/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs index 52d69933..ba120867 100644 --- a/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs +++ b/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs @@ -275,9 +275,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetStorageBuffers(int first, ReadOnlySpan<BufferRange> buffers) + public void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers) { - _renderer.New<SetStorageBuffersCommand>().Set(first, _renderer.CopySpan(buffers)); + _renderer.New<SetStorageBuffersCommand>().Set(_renderer.CopySpan(buffers)); _renderer.QueueCommand(); } @@ -293,9 +293,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers) + public void SetUniformBuffers(ReadOnlySpan<BufferAssignment> buffers) { - _renderer.New<SetUniformBuffersCommand>().Set(first, _renderer.CopySpan(buffers)); + _renderer.New<SetUniformBuffersCommand>().Set(_renderer.CopySpan(buffers)); _renderer.QueueCommand(); } |