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