From 65778a6b78ab8bde4090478482227e40c551db4d Mon Sep 17 00:00:00 2001 From: riperiperi Date: Thu, 24 Nov 2022 14:50:15 +0000 Subject: GPU: Don't trigger uploads for redundant buffer updates (#3828) * Initial implementation * Actually do The Thing * Add remark about performance to IVirtualMemoryManager --- .../Engine/Threed/ConstantBufferUpdater.cs | 24 +++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'Ryujinx.Graphics.Gpu/Engine') diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ConstantBufferUpdater.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ConstantBufferUpdater.cs index f4006ba9..5c936616 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/ConstantBufferUpdater.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/ConstantBufferUpdater.cs @@ -8,6 +8,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// class ConstantBufferUpdater { + private const int UniformDataCacheSize = 512; + private readonly GpuChannel _channel; private readonly DeviceStateWithShadow _state; @@ -16,6 +18,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed private ulong _ubBeginCpuAddress = 0; private ulong _ubFollowUpAddress = 0; private ulong _ubByteCount = 0; + private int _ubIndex = 0; + private int[] _ubData = new int[UniformDataCacheSize]; /// /// Creates a new instance of the constant buffer updater. @@ -108,9 +112,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed if (_ubFollowUpAddress != 0) { var memoryManager = _channel.MemoryManager; - memoryManager.Physical.BufferCache.ForceDirty(memoryManager, _ubFollowUpAddress - _ubByteCount, _ubByteCount); + + Span data = MemoryMarshal.Cast(_ubData.AsSpan(0, (int)(_ubByteCount / 4))); + + if (memoryManager.Physical.WriteWithRedundancyCheck(_ubBeginCpuAddress, data)) + { + memoryManager.Physical.BufferCache.ForceDirty(memoryManager, _ubFollowUpAddress - _ubByteCount, _ubByteCount); + } _ubFollowUpAddress = 0; + _ubIndex = 0; } } @@ -124,7 +135,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed ulong address = uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset; - if (_ubFollowUpAddress != address) + if (_ubFollowUpAddress != address || _ubIndex == _ubData.Length) { FlushUboDirty(); @@ -132,8 +143,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _ubBeginCpuAddress = _channel.MemoryManager.Translate(address); } - var byteData = MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref argument, 1)); - _channel.MemoryManager.Physical.WriteUntracked(_ubBeginCpuAddress + _ubByteCount, byteData); + _ubData[_ubIndex++] = argument; _ubFollowUpAddress = address + 4; _ubByteCount += 4; @@ -153,7 +163,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed ulong size = (ulong)data.Length * 4; - if (_ubFollowUpAddress != address) + if (_ubFollowUpAddress != address || _ubIndex + data.Length > _ubData.Length) { FlushUboDirty(); @@ -161,8 +171,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _ubBeginCpuAddress = _channel.MemoryManager.Translate(address); } - var byteData = MemoryMarshal.Cast(data); - _channel.MemoryManager.Physical.WriteUntracked(_ubBeginCpuAddress + _ubByteCount, byteData); + data.CopyTo(_ubData.AsSpan(_ubIndex)); + _ubIndex += data.Length; _ubFollowUpAddress = address + size; _ubByteCount += size; -- cgit v1.2.3