|
@@ -8,6 +8,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
class ConstantBufferUpdater
|
|
class ConstantBufferUpdater
|
|
|
{
|
|
{
|
|
|
|
|
+ private const int UniformDataCacheSize = 512;
|
|
|
|
|
+
|
|
|
private readonly GpuChannel _channel;
|
|
private readonly GpuChannel _channel;
|
|
|
private readonly DeviceStateWithShadow<ThreedClassState> _state;
|
|
private readonly DeviceStateWithShadow<ThreedClassState> _state;
|
|
|
|
|
|
|
@@ -16,6 +18,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
private ulong _ubBeginCpuAddress = 0;
|
|
private ulong _ubBeginCpuAddress = 0;
|
|
|
private ulong _ubFollowUpAddress = 0;
|
|
private ulong _ubFollowUpAddress = 0;
|
|
|
private ulong _ubByteCount = 0;
|
|
private ulong _ubByteCount = 0;
|
|
|
|
|
+ private int _ubIndex = 0;
|
|
|
|
|
+ private int[] _ubData = new int[UniformDataCacheSize];
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// Creates a new instance of the constant buffer updater.
|
|
/// Creates a new instance of the constant buffer updater.
|
|
@@ -108,9 +112,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
if (_ubFollowUpAddress != 0)
|
|
if (_ubFollowUpAddress != 0)
|
|
|
{
|
|
{
|
|
|
var memoryManager = _channel.MemoryManager;
|
|
var memoryManager = _channel.MemoryManager;
|
|
|
- memoryManager.Physical.BufferCache.ForceDirty(memoryManager, _ubFollowUpAddress - _ubByteCount, _ubByteCount);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ Span<byte> data = MemoryMarshal.Cast<int, byte>(_ubData.AsSpan(0, (int)(_ubByteCount / 4)));
|
|
|
|
|
+
|
|
|
|
|
+ if (memoryManager.Physical.WriteWithRedundancyCheck(_ubBeginCpuAddress, data))
|
|
|
|
|
+ {
|
|
|
|
|
+ memoryManager.Physical.BufferCache.ForceDirty(memoryManager, _ubFollowUpAddress - _ubByteCount, _ubByteCount);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
_ubFollowUpAddress = 0;
|
|
_ubFollowUpAddress = 0;
|
|
|
|
|
+ _ubIndex = 0;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -124,7 +135,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
|
|
|
|
|
ulong address = uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset;
|
|
ulong address = uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset;
|
|
|
|
|
|
|
|
- if (_ubFollowUpAddress != address)
|
|
|
|
|
|
|
+ if (_ubFollowUpAddress != address || _ubIndex == _ubData.Length)
|
|
|
{
|
|
{
|
|
|
FlushUboDirty();
|
|
FlushUboDirty();
|
|
|
|
|
|
|
@@ -132,8 +143,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
_ubBeginCpuAddress = _channel.MemoryManager.Translate(address);
|
|
_ubBeginCpuAddress = _channel.MemoryManager.Translate(address);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- var byteData = MemoryMarshal.Cast<int, byte>(MemoryMarshal.CreateSpan(ref argument, 1));
|
|
|
|
|
- _channel.MemoryManager.Physical.WriteUntracked(_ubBeginCpuAddress + _ubByteCount, byteData);
|
|
|
|
|
|
|
+ _ubData[_ubIndex++] = argument;
|
|
|
|
|
|
|
|
_ubFollowUpAddress = address + 4;
|
|
_ubFollowUpAddress = address + 4;
|
|
|
_ubByteCount += 4;
|
|
_ubByteCount += 4;
|
|
@@ -153,7 +163,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
|
|
|
|
|
ulong size = (ulong)data.Length * 4;
|
|
ulong size = (ulong)data.Length * 4;
|
|
|
|
|
|
|
|
- if (_ubFollowUpAddress != address)
|
|
|
|
|
|
|
+ if (_ubFollowUpAddress != address || _ubIndex + data.Length > _ubData.Length)
|
|
|
{
|
|
{
|
|
|
FlushUboDirty();
|
|
FlushUboDirty();
|
|
|
|
|
|
|
@@ -161,8 +171,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
_ubBeginCpuAddress = _channel.MemoryManager.Translate(address);
|
|
_ubBeginCpuAddress = _channel.MemoryManager.Translate(address);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- var byteData = MemoryMarshal.Cast<int, byte>(data);
|
|
|
|
|
- _channel.MemoryManager.Physical.WriteUntracked(_ubBeginCpuAddress + _ubByteCount, byteData);
|
|
|
|
|
|
|
+ data.CopyTo(_ubData.AsSpan(_ubIndex));
|
|
|
|
|
+ _ubIndex += data.Length;
|
|
|
|
|
|
|
|
_ubFollowUpAddress = address + size;
|
|
_ubFollowUpAddress = address + size;
|
|
|
_ubByteCount += size;
|
|
_ubByteCount += size;
|