MethodFifo.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using Ryujinx.Graphics.Gpu.State;
  2. using System.Threading;
  3. namespace Ryujinx.Graphics.Gpu.Engine
  4. {
  5. partial class Methods
  6. {
  7. /// <summary>
  8. /// Writes a GPU counter to guest memory.
  9. /// </summary>
  10. /// <param name="state">Current GPU state</param>
  11. /// <param name="argument">Method call argument</param>
  12. public void Semaphore(GpuState state, int argument)
  13. {
  14. FifoSemaphoreOperation op = (FifoSemaphoreOperation)(argument & 3);
  15. var semaphore = state.Get<SemaphoreState>(MethodOffset.Semaphore);
  16. int value = semaphore.Payload;
  17. if (op == FifoSemaphoreOperation.Counter)
  18. {
  19. // TODO: There's much more that should be done here.
  20. // NVN only supports the "Accumulate" mode, so we
  21. // can't currently guess which bits specify the
  22. // reduction operation.
  23. value += _context.MemoryAccessor.Read<int>(semaphore.Address.Pack());
  24. }
  25. _context.MemoryAccessor.Write(semaphore.Address.Pack(), value);
  26. _context.AdvanceSequence();
  27. }
  28. /// <summary>
  29. /// Waits for the GPU to be idle.
  30. /// </summary>
  31. /// <param name="state">Current GPU state</param>
  32. /// <param name="argument">Method call argument</param>
  33. public void WaitForIdle(GpuState state, int argument)
  34. {
  35. PerformDeferredDraws();
  36. _context.Renderer.Pipeline.Barrier();
  37. }
  38. /// <summary>
  39. /// Send macro code/data to the MME.
  40. /// </summary>
  41. /// <param name="state">Current GPU state</param>
  42. /// <param name="argument">Method call argument</param>
  43. public void SendMacroCodeData(GpuState state, int argument)
  44. {
  45. int macroUploadAddress = state.Get<int>(MethodOffset.MacroUploadAddress);
  46. _context.Fifo.SendMacroCodeData(macroUploadAddress++, argument);
  47. state.Write((int)MethodOffset.MacroUploadAddress, macroUploadAddress);
  48. }
  49. /// <summary>
  50. /// Bind a macro index to a position for the MME.
  51. /// </summary>
  52. /// <param name="state">Current GPU state</param>
  53. /// <param name="argument">Method call argument</param>
  54. public void BindMacro(GpuState state, int argument)
  55. {
  56. int macroBindingIndex = state.Get<int>(MethodOffset.MacroBindingIndex);
  57. _context.Fifo.BindMacro(macroBindingIndex++, argument);
  58. state.Write((int)MethodOffset.MacroBindingIndex, macroBindingIndex);
  59. }
  60. public void SetMmeShadowRamControl(GpuState state, int argument)
  61. {
  62. _context.Fifo.SetMmeShadowRamControl((ShadowRamControl)argument);
  63. }
  64. /// <summary>
  65. /// Apply a fence operation on a syncpoint.
  66. /// </summary>
  67. /// <param name="state">Current GPU state</param>
  68. /// <param name="argument">Method call argument</param>
  69. public void FenceAction(GpuState state, int argument)
  70. {
  71. uint threshold = state.Get<uint>(MethodOffset.FenceValue);
  72. FenceActionOperation operation = (FenceActionOperation)(argument & 1);
  73. uint syncpointId = (uint)(argument >> 8) & 0xFF;
  74. if (operation == FenceActionOperation.Acquire)
  75. {
  76. _context.Synchronization.WaitOnSyncpoint(syncpointId, threshold, Timeout.InfiniteTimeSpan);
  77. }
  78. else if (operation == FenceActionOperation.Increment)
  79. {
  80. _context.Synchronization.IncrementSyncpoint(syncpointId);
  81. }
  82. }
  83. }
  84. }