Fifo.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright 2008 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <atomic>
  5. #include <cstddef>
  6. #include <optional>
  7. #include "Common/BlockingLoop.h"
  8. #include "Common/CommonTypes.h"
  9. #include "Common/Config/Config.h"
  10. #include "Common/Event.h"
  11. #include "Common/Flag.h"
  12. class PointerWrap;
  13. namespace Core
  14. {
  15. class System;
  16. }
  17. namespace CoreTiming
  18. {
  19. struct EventType;
  20. }
  21. namespace Fifo
  22. {
  23. // Used for diagnostics.
  24. enum class SyncGPUReason
  25. {
  26. Other,
  27. Wraparound,
  28. EFBPoke,
  29. PerfQuery,
  30. BBox,
  31. Swap,
  32. AuxSpace,
  33. };
  34. class FifoManager final
  35. {
  36. public:
  37. explicit FifoManager(Core::System& system);
  38. FifoManager(const FifoManager& other) = delete;
  39. FifoManager(FifoManager&& other) = delete;
  40. FifoManager& operator=(const FifoManager& other) = delete;
  41. FifoManager& operator=(FifoManager&& other) = delete;
  42. ~FifoManager();
  43. void Init();
  44. void Shutdown();
  45. void Prepare(); // Must be called from the CPU thread.
  46. void DoState(PointerWrap& f);
  47. void PauseAndLock(bool do_lock, bool unpause_on_unlock);
  48. void UpdateWantDeterminism(bool want);
  49. bool UseDeterministicGPUThread() const { return m_use_deterministic_gpu_thread; }
  50. bool UseSyncGPU() const { return m_config_sync_gpu; }
  51. // In deterministic GPU thread mode this waits for the GPU to be done with pending work.
  52. void SyncGPU(SyncGPUReason reason, bool may_move_read_ptr = true);
  53. // In single core mode, this runs the GPU for a single slice.
  54. // In dual core mode, this synchronizes with the GPU thread.
  55. void SyncGPUForRegisterAccess();
  56. void PushFifoAuxBuffer(const void* ptr, size_t size);
  57. void* PopFifoAuxBuffer(size_t size);
  58. void FlushGpu();
  59. void RunGpu();
  60. void GpuMaySleep();
  61. void RunGpuLoop();
  62. void ExitGpuLoop();
  63. void EmulatorState(bool running);
  64. void ResetVideoBuffer();
  65. private:
  66. void RefreshConfig();
  67. void ReadDataFromFifo(u32 read_ptr);
  68. void ReadDataFromFifoOnCPU(u32 read_ptr);
  69. int RunGpuOnCpu(int ticks);
  70. int WaitForGpuThread(int ticks);
  71. static void SyncGPUCallback(Core::System& system, u64 ticks, s64 cyclesLate);
  72. static constexpr u32 FIFO_SIZE = 2 * 1024 * 1024;
  73. Common::BlockingLoop m_gpu_mainloop;
  74. Common::Flag m_emu_running_state;
  75. // Most of this array is unlikely to be faulted in...
  76. u8 m_fifo_aux_data[FIFO_SIZE]{};
  77. u8* m_fifo_aux_write_ptr = nullptr;
  78. u8* m_fifo_aux_read_ptr = nullptr;
  79. // This could be in SConfig, but it depends on multiple settings
  80. // and can change at runtime.
  81. bool m_use_deterministic_gpu_thread = false;
  82. CoreTiming::EventType* m_event_sync_gpu = nullptr;
  83. // STATE_TO_SAVE
  84. u8* m_video_buffer = nullptr;
  85. u8* m_video_buffer_read_ptr = nullptr;
  86. std::atomic<u8*> m_video_buffer_write_ptr = nullptr;
  87. std::atomic<u8*> m_video_buffer_seen_ptr = nullptr;
  88. u8* m_video_buffer_pp_read_ptr = nullptr;
  89. // The read_ptr is always owned by the GPU thread. In normal mode, so is the
  90. // write_ptr, despite it being atomic. In deterministic GPU thread mode,
  91. // things get a bit more complicated:
  92. // - The seen_ptr is written by the GPU thread, and points to what it's already
  93. // processed as much of as possible - in the case of a partial command which
  94. // caused it to stop, not the same as the read ptr. It's written by the GPU,
  95. // under the lock, and updating the cond.
  96. // - The write_ptr is written by the CPU thread after it copies data from the
  97. // FIFO. Maybe someday it will be under the lock. For now, because RunGpuLoop
  98. // polls, it's just atomic.
  99. // - The pp_read_ptr is the CPU preprocessing version of the read_ptr.
  100. std::atomic<int> m_sync_ticks = 0;
  101. bool m_syncing_suspended = false;
  102. Common::Event m_sync_wakeup_event;
  103. std::optional<Config::ConfigChangedCallbackID> m_config_callback_id = std::nullopt;
  104. bool m_config_sync_gpu = false;
  105. int m_config_sync_gpu_max_distance = 0;
  106. int m_config_sync_gpu_min_distance = 0;
  107. float m_config_sync_gpu_overclock = 0.0f;
  108. Core::System& m_system;
  109. };
  110. bool AtBreakpoint(Core::System& system);
  111. } // namespace Fifo