@@ -81,29 +81,35 @@ class Limiter {
8181 }
8282
8383#if _WIN32
84- bool m_initialized;
85- double m_countPerNs;
86-
8784 void NanoSleep (const duration_t duration) {
88- if (!m_initialized) {
85+ static bool initialized = false ;
86+ static double countPerNs;
87+ static size_t numSleeps = 0 ;
88+
89+ // QueryPerformanceFrequency's result is constant, but calling it occasionally
90+ // appears to stabilize QueryPerformanceCounter. Without it, the game drifts
91+ // from 60hz to 144hz. (Cursed, but I suspect it's NVIDIA/G-SYNC related)
92+ if (!initialized || numSleeps++ % 1000 == 0 ) {
8993 LARGE_INTEGER freq;
90- QueryPerformanceFrequency (&freq);
91- m_countPerNs = static_cast <double >(freq.QuadPart ) / 1000000000.0 ;
92- m_initialized = true ;
94+ if (QueryPerformanceFrequency (&freq) == 0 ) {
95+ spdlog::warn (" QueryPerformanceFrequency failed: {}" , GetLastError ());
96+ return ;
97+ }
98+ countPerNs = static_cast <double >(freq.QuadPart ) / 1e9 ;
99+ initialized = true ;
100+ numSleeps = 0 ;
93101 }
94102
95- DWORD ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count ();
96- auto tickCount = static_cast <LONGLONG>(static_cast <double >(duration.count ()) * m_countPerNs);
97- LARGE_INTEGER count;
98- QueryPerformanceCounter (&count);
99- if (ms > 10 ) {
100- // Adjust for Sleep overhead
101- ::Sleep (ms - 10 );
103+ LARGE_INTEGER start, current;
104+ QueryPerformanceCounter (&start);
105+ LONGLONG ticksToWait = static_cast <LONGLONG>(duration.count () * countPerNs);
106+ if (DWORD ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count (); ms > 1 ) {
107+ ::Sleep (ms - 1 );
102108 }
103- auto end = count.QuadPart + tickCount;
104109 do {
105- QueryPerformanceCounter (&count);
106- } while (count.QuadPart < end);
110+ QueryPerformanceCounter (¤t);
111+ _mm_pause (); // Yield CPU
112+ } while (current.QuadPart - start.QuadPart < ticksToWait);
107113 }
108114#else
109115 void NanoSleep (const duration_t duration) { std::this_thread::sleep_for (duration); }
0 commit comments