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.Gpu/Memory/BufferManager.cs | |
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.Gpu/Memory/BufferManager.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Memory/BufferManager.cs | 46 |
1 files changed, 11 insertions, 35 deletions
diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs index 1b67f650..f0831e15 100644 --- a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs +++ b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs @@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Gpu.Memory private readonly VertexBuffer[] _vertexBuffers; private readonly BufferBounds[] _transformFeedbackBuffers; private readonly List<BufferTextureBinding> _bufferTextures; - private readonly BufferRange[] _ranges; + private readonly BufferAssignment[] _ranges; /// <summary> /// Holds shader stage buffer state and binding information. @@ -134,7 +134,7 @@ namespace Ryujinx.Graphics.Gpu.Memory _bufferTextures = new List<BufferTextureBinding>(); - _ranges = new BufferRange[Constants.TotalGpUniformBuffers * Constants.ShaderStages]; + _ranges = new BufferAssignment[Constants.TotalGpUniformBuffers * Constants.ShaderStages]; } @@ -618,10 +618,9 @@ namespace Ryujinx.Graphics.Gpu.Memory [MethodImpl(MethodImplOptions.AggressiveInlining)] private void BindBuffers(BufferCache bufferCache, BuffersPerStage[] bindings, bool isStorage) { - int rangesFirst = 0; int rangesCount = 0; - Span<BufferRange> ranges = _ranges; + Span<BufferAssignment> ranges = _ranges; for (ShaderStage stage = ShaderStage.Vertex; stage <= ShaderStage.Fragment; stage++) { @@ -640,25 +639,14 @@ namespace Ryujinx.Graphics.Gpu.Memory ? bufferCache.GetBufferRangeTillEnd(bounds.Address, bounds.Size, isWrite) : bufferCache.GetBufferRange(bounds.Address, bounds.Size); - if (rangesCount == 0) - { - rangesFirst = bindingInfo.Binding; - } - else if (bindingInfo.Binding != rangesFirst + rangesCount) - { - SetHostBuffers(ranges, rangesFirst, rangesCount, isStorage); - rangesFirst = bindingInfo.Binding; - rangesCount = 0; - } - - ranges[rangesCount++] = range; + ranges[rangesCount++] = new BufferAssignment(bindingInfo.Binding, range); } } } if (rangesCount != 0) { - SetHostBuffers(ranges, rangesFirst, rangesCount, isStorage); + SetHostBuffers(ranges, rangesCount, isStorage); } } @@ -671,10 +659,9 @@ namespace Ryujinx.Graphics.Gpu.Memory [MethodImpl(MethodImplOptions.AggressiveInlining)] private void BindBuffers(BufferCache bufferCache, BuffersPerStage buffers, bool isStorage) { - int rangesFirst = 0; int rangesCount = 0; - Span<BufferRange> ranges = _ranges; + Span<BufferAssignment> ranges = _ranges; for (int index = 0; index < buffers.Count; index++) { @@ -689,24 +676,13 @@ namespace Ryujinx.Graphics.Gpu.Memory ? bufferCache.GetBufferRangeTillEnd(bounds.Address, bounds.Size, isWrite) : bufferCache.GetBufferRange(bounds.Address, bounds.Size); - if (rangesCount == 0) - { - rangesFirst = bindingInfo.Binding; - } - else if (bindingInfo.Binding != rangesFirst + rangesCount) - { - SetHostBuffers(ranges, rangesFirst, rangesCount, isStorage); - rangesFirst = bindingInfo.Binding; - rangesCount = 0; - } - - ranges[rangesCount++] = range; + ranges[rangesCount++] = new BufferAssignment(bindingInfo.Binding, range); } } if (rangesCount != 0) { - SetHostBuffers(ranges, rangesFirst, rangesCount, isStorage); + SetHostBuffers(ranges, rangesCount, isStorage); } } @@ -718,15 +694,15 @@ namespace Ryujinx.Graphics.Gpu.Memory /// <param name="count">Number of bindings</param> /// <param name="isStorage">Indicates if the buffers are storage or uniform buffers</param> [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SetHostBuffers(ReadOnlySpan<BufferRange> ranges, int first, int count, bool isStorage) + private void SetHostBuffers(ReadOnlySpan<BufferAssignment> ranges, int count, bool isStorage) { if (isStorage) { - _context.Renderer.Pipeline.SetStorageBuffers(first, ranges.Slice(0, count)); + _context.Renderer.Pipeline.SetStorageBuffers(ranges.Slice(0, count)); } else { - _context.Renderer.Pipeline.SetUniformBuffers(first, ranges.Slice(0, count)); + _context.Renderer.Pipeline.SetUniformBuffers(ranges.Slice(0, count)); } } |