SyncptIncrManager.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using Ryujinx.Graphics.Gpu.Synchronization;
  2. using System.Collections.Generic;
  3. namespace Ryujinx.Graphics.Host1x
  4. {
  5. class SyncptIncrManager
  6. {
  7. private readonly SynchronizationManager _syncMgr;
  8. private struct SyncptIncr
  9. {
  10. public uint Id { get; }
  11. public ClassId ClassId { get; }
  12. public uint SyncptId { get; }
  13. public bool Done { get; }
  14. public SyncptIncr(uint id, ClassId classId, uint syncptId, bool done = false)
  15. {
  16. Id = id;
  17. ClassId = classId;
  18. SyncptId = syncptId;
  19. Done = done;
  20. }
  21. }
  22. private readonly List<SyncptIncr> _incrs = new List<SyncptIncr>();
  23. private uint _currentId;
  24. public SyncptIncrManager(SynchronizationManager syncMgr)
  25. {
  26. _syncMgr = syncMgr;
  27. }
  28. public void Increment(uint id)
  29. {
  30. lock (_incrs)
  31. {
  32. _incrs.Add(new SyncptIncr(0, 0, id, true));
  33. IncrementAllDone();
  34. }
  35. }
  36. public uint IncrementWhenDone(ClassId classId, uint id)
  37. {
  38. lock (_incrs)
  39. {
  40. uint handle = _currentId++;
  41. _incrs.Add(new SyncptIncr(handle, classId, id));
  42. return handle;
  43. }
  44. }
  45. public void SignalDone(uint handle)
  46. {
  47. lock (_incrs)
  48. {
  49. // Set pending increment with the given handle to "done".
  50. for (int i = 0; i < _incrs.Count; i++)
  51. {
  52. SyncptIncr incr = _incrs[i];
  53. if (_incrs[i].Id == handle)
  54. {
  55. _incrs[i] = new SyncptIncr(incr.Id, incr.ClassId, incr.SyncptId, true);
  56. break;
  57. }
  58. }
  59. IncrementAllDone();
  60. }
  61. }
  62. private void IncrementAllDone()
  63. {
  64. lock (_incrs)
  65. {
  66. // Increment all sequential pending increments that are already done.
  67. int doneCount = 0;
  68. for (; doneCount < _incrs.Count; doneCount++)
  69. {
  70. if (!_incrs[doneCount].Done)
  71. {
  72. break;
  73. }
  74. _syncMgr.IncrementSyncpoint(_incrs[doneCount].SyncptId);
  75. }
  76. _incrs.RemoveRange(0, doneCount);
  77. }
  78. }
  79. }
  80. }