aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs56
1 files changed, 50 insertions, 6 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs b/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs
index 61772327..3e1dd151 100644
--- a/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Gpu.State;
using System;
using System.Runtime.InteropServices;
@@ -6,6 +7,25 @@ namespace Ryujinx.Graphics.Gpu.Engine
{
partial class Methods
{
+ // State associated with direct uniform buffer updates.
+ // This state is used to attempt to batch together consecutive updates.
+ private ulong _ubBeginCpuAddress = 0;
+ private ulong _ubFollowUpAddress = 0;
+ private ulong _ubByteCount = 0;
+
+ /// <summary>
+ /// Flushes any queued ubo updates.
+ /// </summary>
+ private void FlushUboDirty()
+ {
+ if (_ubFollowUpAddress != 0)
+ {
+ BufferManager.ForceDirty(_ubFollowUpAddress - _ubByteCount, _ubByteCount);
+
+ _ubFollowUpAddress = 0;
+ }
+ }
+
/// <summary>
/// Updates the uniform buffer data with inline data.
/// </summary>
@@ -15,11 +35,22 @@ namespace Ryujinx.Graphics.Gpu.Engine
{
var uniformBuffer = state.Get<UniformBufferState>(MethodOffset.UniformBufferState);
- _context.MemoryManager.Write(uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset, argument);
+ ulong address = uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset;
- state.SetUniformBufferOffset(uniformBuffer.Offset + 4);
+ if (_ubFollowUpAddress != address)
+ {
+ FlushUboDirty();
+
+ _ubByteCount = 0;
+ _ubBeginCpuAddress = _context.MemoryManager.Translate(address);
+ }
- _context.AdvanceSequence();
+ _context.PhysicalMemory.WriteUntracked(_ubBeginCpuAddress + _ubByteCount, MemoryMarshal.Cast<int, byte>(MemoryMarshal.CreateSpan(ref argument, 1)));
+
+ _ubFollowUpAddress = address + 4;
+ _ubByteCount += 4;
+
+ state.SetUniformBufferOffset(uniformBuffer.Offset + 4);
}
/// <summary>
@@ -31,11 +62,24 @@ namespace Ryujinx.Graphics.Gpu.Engine
{
var uniformBuffer = state.Get<UniformBufferState>(MethodOffset.UniformBufferState);
- _context.MemoryManager.Write(uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset, MemoryMarshal.Cast<int, byte>(data));
+ ulong address = uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset;
- state.SetUniformBufferOffset(uniformBuffer.Offset + data.Length * 4);
+ ulong size = (ulong)data.Length * 4;
+
+ if (_ubFollowUpAddress != address)
+ {
+ FlushUboDirty();
- _context.AdvanceSequence();
+ _ubByteCount = 0;
+ _ubBeginCpuAddress = _context.MemoryManager.Translate(address);
+ }
+
+ _context.PhysicalMemory.WriteUntracked(_ubBeginCpuAddress + _ubByteCount, MemoryMarshal.Cast<int, byte>(data));
+
+ _ubFollowUpAddress = address + size;
+ _ubByteCount += size;
+
+ state.SetUniformBufferOffset(uniformBuffer.Offset + data.Length * 4);
}
}
} \ No newline at end of file