diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs | 56 |
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 |