GAL: Send all buffer assignments at once rather than individually (#3881)

* 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)
This commit is contained in:
riperiperi
2022-11-24 07:50:59 +00:00
committed by GitHub
parent f3cc2e5703
commit ece36b274d
11 changed files with 91 additions and 78 deletions

View File

@ -163,12 +163,13 @@ namespace Ryujinx.Graphics.Vulkan
SignalDirty(DirtyFlags.Image);
}
public void SetStorageBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan<BufferRange> buffers)
public void SetStorageBuffers(CommandBuffer commandBuffer, ReadOnlySpan<BufferAssignment> buffers)
{
for (int i = 0; i < buffers.Length; i++)
{
var buffer = buffers[i];
int index = first + i;
var assignment = buffers[i];
var buffer = assignment.Range;
int index = assignment.Binding;
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
@ -243,12 +244,13 @@ namespace Ryujinx.Graphics.Vulkan
SignalDirty(DirtyFlags.Texture);
}
public void SetUniformBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan<BufferRange> buffers)
public void SetUniformBuffers(CommandBuffer commandBuffer, ReadOnlySpan<BufferAssignment> buffers)
{
for (int i = 0; i < buffers.Length; i++)
{
var buffer = buffers[i];
int index = first + i;
var assignment = buffers[i];
var buffer = assignment.Range;
int index = assignment.Binding;
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
ref Auto<DisposableBuffer> currentVkBuffer = ref _uniformBufferRefs[index];

View File

@ -177,7 +177,7 @@ namespace Ryujinx.Graphics.Vulkan
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
_pipeline.SetUniformBuffers(1, stackalloc[] { new BufferRange(bufferHandle, 0, RegionBufferSize) });
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
@ -240,7 +240,7 @@ namespace Ryujinx.Graphics.Vulkan
gd.BufferManager.SetData<float>(bufferHandle, 0, clearColor);
_pipeline.SetUniformBuffers(1, stackalloc[] { new BufferRange(bufferHandle, 0, ClearColorBufferSize) });
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, ClearColorBufferSize)) });
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
@ -302,7 +302,7 @@ namespace Ryujinx.Graphics.Vulkan
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
pipeline.SetUniformBuffers(1, stackalloc[] { new BufferRange(bufferHandle, 0, RegionBufferSize) });
pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
@ -380,7 +380,7 @@ namespace Ryujinx.Graphics.Vulkan
_pipeline.SetCommandBuffer(cbs);
_pipeline.SetUniformBuffers(0, stackalloc[] { new BufferRange(bufferHandle, 0, ParamsBufferSize) });
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) });
Span<Auto<DisposableBuffer>> sbRanges = new Auto<DisposableBuffer>[2];
@ -571,7 +571,7 @@ namespace Ryujinx.Graphics.Vulkan
int conversionType = srcIsMs ? src.Info.BytesPerPixel : -src.Info.BytesPerPixel;
_pipeline.Specialize(conversionType);
_pipeline.SetUniformBuffers(0, stackalloc[] { new BufferRange(bufferHandle, 0, ParamsBufferSize) });
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) });
if (src.Info.Target == Target.Texture2DMultisampleArray ||
dst.Info.Target == Target.Texture2DMultisampleArray)
@ -776,7 +776,7 @@ namespace Ryujinx.Graphics.Vulkan
srcIndirectBufferOffset,
indirectDataSize);
_pipeline.SetUniformBuffers(0, stackalloc[] { drawCountBufferAligned });
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, drawCountBufferAligned) });
_pipeline.SetStorageBuffers(1, new[] { srcIndirectBuffer.GetBuffer(), dstIndirectBuffer.GetBuffer(), patternBuffer.GetBuffer() });
_pipeline.SetProgram(_programConvertIndirectData);
@ -804,7 +804,7 @@ namespace Ryujinx.Graphics.Vulkan
0,
convertedCount * outputIndexSize);
_pipeline.SetUniformBuffers(0, stackalloc[] { new BufferRange(patternBufferHandle, 0, ParamsBufferSize) });
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(patternBufferHandle, 0, ParamsBufferSize)) });
_pipeline.SetStorageBuffers(1, new[] { srcIndexBuffer.GetBuffer(), dstIndexBuffer.GetBuffer() });
_pipeline.SetProgram(_programConvertIndexBuffer);

View File

@ -973,9 +973,9 @@ namespace Ryujinx.Graphics.Vulkan
SignalStateChange();
}
public void SetStorageBuffers(int first, ReadOnlySpan<BufferRange> buffers)
public void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers)
{
_descriptorSetUpdater.SetStorageBuffers(CommandBuffer, first, buffers);
_descriptorSetUpdater.SetStorageBuffers(CommandBuffer, buffers);
}
public void SetStorageBuffers(int first, ReadOnlySpan<Auto<DisposableBuffer>> buffers)
@ -1013,9 +1013,9 @@ namespace Ryujinx.Graphics.Vulkan
}
}
public void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers)
public void SetUniformBuffers(ReadOnlySpan<BufferAssignment> buffers)
{
_descriptorSetUpdater.SetUniformBuffers(CommandBuffer, first, buffers);
_descriptorSetUpdater.SetUniformBuffers(CommandBuffer, buffers);
}
public void SetUserClipDistance(int index, bool enableClip)