MethodUniformBufferUpdate.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using Ryujinx.Graphics.Gpu.Memory;
  2. using Ryujinx.Graphics.Gpu.State;
  3. using System;
  4. using System.Runtime.InteropServices;
  5. namespace Ryujinx.Graphics.Gpu.Engine
  6. {
  7. partial class Methods
  8. {
  9. // State associated with direct uniform buffer updates.
  10. // This state is used to attempt to batch together consecutive updates.
  11. private ulong _ubBeginCpuAddress = 0;
  12. private ulong _ubFollowUpAddress = 0;
  13. private ulong _ubByteCount = 0;
  14. /// <summary>
  15. /// Flushes any queued ubo updates.
  16. /// </summary>
  17. private void FlushUboDirty()
  18. {
  19. if (_ubFollowUpAddress != 0)
  20. {
  21. BufferCache.ForceDirty(_ubFollowUpAddress - _ubByteCount, _ubByteCount);
  22. _ubFollowUpAddress = 0;
  23. }
  24. }
  25. /// <summary>
  26. /// Updates the uniform buffer data with inline data.
  27. /// </summary>
  28. /// <param name="state">Current GPU state</param>
  29. /// <param name="argument">New uniform buffer data word</param>
  30. private void UniformBufferUpdate(GpuState state, int argument)
  31. {
  32. var uniformBuffer = state.Get<UniformBufferState>(MethodOffset.UniformBufferState);
  33. ulong address = uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset;
  34. if (_ubFollowUpAddress != address)
  35. {
  36. FlushUboDirty();
  37. _ubByteCount = 0;
  38. _ubBeginCpuAddress = _context.MemoryManager.Translate(address);
  39. }
  40. _context.PhysicalMemory.WriteUntracked(_ubBeginCpuAddress + _ubByteCount, MemoryMarshal.Cast<int, byte>(MemoryMarshal.CreateSpan(ref argument, 1)));
  41. _ubFollowUpAddress = address + 4;
  42. _ubByteCount += 4;
  43. state.SetUniformBufferOffset(uniformBuffer.Offset + 4);
  44. }
  45. /// <summary>
  46. /// Updates the uniform buffer data with inline data.
  47. /// </summary>
  48. /// <param name="state">Current GPU state</param>
  49. /// <param name="data">Data to be written to the uniform buffer</param>
  50. public void UniformBufferUpdate(GpuState state, ReadOnlySpan<int> data)
  51. {
  52. var uniformBuffer = state.Get<UniformBufferState>(MethodOffset.UniformBufferState);
  53. ulong address = uniformBuffer.Address.Pack() + (uint)uniformBuffer.Offset;
  54. ulong size = (ulong)data.Length * 4;
  55. if (_ubFollowUpAddress != address)
  56. {
  57. FlushUboDirty();
  58. _ubByteCount = 0;
  59. _ubBeginCpuAddress = _context.MemoryManager.Translate(address);
  60. }
  61. _context.PhysicalMemory.WriteUntracked(_ubBeginCpuAddress + _ubByteCount, MemoryMarshal.Cast<int, byte>(data));
  62. _ubFollowUpAddress = address + size;
  63. _ubByteCount += size;
  64. state.SetUniformBufferOffset(uniformBuffer.Offset + data.Length * 4);
  65. }
  66. }
  67. }