aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Engine
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine')
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Compute.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferBind.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferUpdate.cs56
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Methods.cs2
5 files changed, 58 insertions, 6 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Compute.cs b/Ryujinx.Graphics.Gpu/Engine/Compute.cs
index bcff5953..be317a7f 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Compute.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Compute.cs
@@ -16,6 +16,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
/// <param name="argument">Method call argument</param>
public void Dispatch(GpuState state, int argument)
{
+ FlushUboDirty();
+
uint qmdAddress = (uint)state.Get<int>(MethodOffset.DispatchParamsAddress);
var qmd = _context.MemoryManager.Read<ComputeQmd>((ulong)qmdAddress << 8);
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs b/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs
index dd16cb2d..a1cf86ec 100644
--- a/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/MethodCopyBuffer.cs
@@ -69,6 +69,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
return;
}
+ FlushUboDirty();
+
if (copy2D)
{
// Buffer to texture copy.
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferBind.cs b/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferBind.cs
index 3fee1fcf..16fb31d6 100644
--- a/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferBind.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/MethodUniformBufferBind.cs
@@ -66,6 +66,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
int index = (argument >> 4) & 0x1f;
+ FlushUboDirty();
+
if (enable)
{
var uniformBuffer = state.Get<UniformBufferState>(MethodOffset.UniformBufferState);
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
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
index ae9bdb0d..431ea449 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
@@ -130,6 +130,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
_prevTfEnable = false;
}
+ FlushUboDirty();
+
// Shaders must be the first one to be updated if modified, because
// some of the other state depends on information from the currently
// bound shaders.