aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2023-05-08 09:59:26 +0100
committerGitHub <noreply@github.com>2023-05-08 10:59:26 +0200
commit895d9b53bc37507fed6829a7f91a1b8e3237ab0b (patch)
tree3e3449370616705ffa76bc209e3dd960b87de3e0 /src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs
parent0e06aace458109f70dc5f36535f77117465ea707 (diff)
Vulkan: Batch vertex buffer updates (#4843)
* Vulkan: Batch vertex buffer updates Some games can bind a large number of vertex buffers for draws. This PR allows for vertex buffers to be updated with one call rather than one per buffer. This mostly affects the AMD Mesa driver, the testing platform was Steam Deck with Super Mario Odyssey. It was taking about 12% before, should be greatly reduced now. A small optimization has been added to avoid looking up the same buffer multiple times, as a common pattern is for the same buffer to be bound many times in a row with different ranges. * Only rebind vertex buffers if they have changed * Address feedback
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs')
-rw-r--r--src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs39
1 files changed, 8 insertions, 31 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs b/src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs
index c4856019..2118bfae 100644
--- a/src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs
+++ b/src/Ryujinx.Graphics.Vulkan/VertexBufferState.cs
@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Vulkan
AttributeScalarAlignment = 1;
}
- public void BindVertexBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding, ref PipelineState state)
+ public void BindVertexBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding, ref PipelineState state, VertexBufferUpdater updater)
{
var autoBuffer = _buffer;
@@ -65,21 +65,7 @@ namespace Ryujinx.Graphics.Vulkan
var buffer = autoBuffer.Get(cbs, 0, newSize).Value;
- if (gd.Capabilities.SupportsExtendedDynamicState)
- {
- gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2(
- cbs.CommandBuffer,
- binding,
- 1,
- buffer,
- 0,
- (ulong)newSize,
- (ulong)stride);
- }
- else
- {
- gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, binding, 1, buffer, 0);
- }
+ updater.BindVertexBuffer(cbs, binding, buffer, 0, (ulong)newSize, (ulong)stride);
_buffer = autoBuffer;
@@ -106,21 +92,7 @@ namespace Ryujinx.Graphics.Vulkan
{
var buffer = autoBuffer.Get(cbs, _offset, _size).Value;
- if (gd.Capabilities.SupportsExtendedDynamicState)
- {
- gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2(
- cbs.CommandBuffer,
- binding,
- 1,
- buffer,
- (ulong)_offset,
- (ulong)_size,
- (ulong)_stride);
- }
- else
- {
- gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, binding, 1, buffer, (ulong)_offset);
- }
+ updater.BindVertexBuffer(cbs, binding, buffer, (ulong)_offset, (ulong)_size, (ulong)_stride);
}
}
@@ -129,6 +101,11 @@ namespace Ryujinx.Graphics.Vulkan
return _buffer == buffer;
}
+ public bool Matches(Auto<DisposableBuffer> buffer, int descriptorIndex, int offset, int size, int stride = 0)
+ {
+ return _buffer == buffer && DescriptorIndex == descriptorIndex && _offset == offset && _size == size && _stride == stride;
+ }
+
public void Swap(Auto<DisposableBuffer> from, Auto<DisposableBuffer> to)
{
if (_buffer == from)