wall_clock.h 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <chrono>
  5. #include <memory>
  6. #include <ratio>
  7. #include "common/common_types.h"
  8. namespace Common {
  9. class WallClock {
  10. public:
  11. static constexpr u64 CNTFRQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz
  12. static constexpr u64 GPUTickFreq = 614'400'000; // GM20B GPU Tick Frequency = 614.4 MHz
  13. static constexpr u64 CPUTickFreq = 1'020'000'000; // T210/4 A57 CPU Tick Frequency = 1020.0 MHz
  14. virtual ~WallClock() = default;
  15. /// @returns The time in nanoseconds since the construction of this clock.
  16. virtual std::chrono::nanoseconds GetTimeNS() const = 0;
  17. /// @returns The time in microseconds since the construction of this clock.
  18. virtual std::chrono::microseconds GetTimeUS() const = 0;
  19. /// @returns The time in milliseconds since the construction of this clock.
  20. virtual std::chrono::milliseconds GetTimeMS() const = 0;
  21. /// @returns The guest CNTPCT ticks since the construction of this clock.
  22. virtual u64 GetCNTPCT() const = 0;
  23. /// @returns The guest GPU ticks since the construction of this clock.
  24. virtual u64 GetGPUTick() const = 0;
  25. /// @returns The raw host timer ticks since an indeterminate epoch.
  26. virtual u64 GetHostTicksNow() const = 0;
  27. /// @returns The raw host timer ticks since the construction of this clock.
  28. virtual u64 GetHostTicksElapsed() const = 0;
  29. /// @returns Whether the clock directly uses the host's hardware clock.
  30. virtual bool IsNative() const = 0;
  31. static inline u64 NSToCNTPCT(u64 ns) {
  32. return ns * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
  33. }
  34. static inline u64 NSToGPUTick(u64 ns) {
  35. return ns * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
  36. }
  37. // Cycle Timing
  38. static inline u64 CPUTickToNS(u64 cpu_tick) {
  39. return cpu_tick * CPUTickToNsRatio::num / CPUTickToNsRatio::den;
  40. }
  41. static inline u64 CPUTickToUS(u64 cpu_tick) {
  42. return cpu_tick * CPUTickToUsRatio::num / CPUTickToUsRatio::den;
  43. }
  44. static inline u64 CPUTickToCNTPCT(u64 cpu_tick) {
  45. return cpu_tick * CPUTickToCNTPCTRatio::num / CPUTickToCNTPCTRatio::den;
  46. }
  47. static inline u64 CPUTickToGPUTick(u64 cpu_tick) {
  48. return cpu_tick * CPUTickToGPUTickRatio::num / CPUTickToGPUTickRatio::den;
  49. }
  50. protected:
  51. using NsRatio = std::nano;
  52. using UsRatio = std::micro;
  53. using MsRatio = std::milli;
  54. using NsToUsRatio = std::ratio_divide<std::nano, std::micro>;
  55. using NsToMsRatio = std::ratio_divide<std::nano, std::milli>;
  56. using NsToCNTPCTRatio = std::ratio<CNTFRQ, std::nano::den>;
  57. using NsToGPUTickRatio = std::ratio<GPUTickFreq, std::nano::den>;
  58. // Cycle Timing
  59. using CPUTickToNsRatio = std::ratio<std::nano::den, CPUTickFreq>;
  60. using CPUTickToUsRatio = std::ratio<std::micro::den, CPUTickFreq>;
  61. using CPUTickToCNTPCTRatio = std::ratio<CNTFRQ, CPUTickFreq>;
  62. using CPUTickToGPUTickRatio = std::ratio<GPUTickFreq, CPUTickFreq>;
  63. };
  64. std::unique_ptr<WallClock> CreateOptimalClock();
  65. std::unique_ptr<WallClock> CreateStandardWallClock();
  66. } // namespace Common