mirror of
https://github.com/izzy2lost/xenia-edge.git
synced 2026-07-06 00:20:26 -07:00
Fix regression with vsync timing on Windows introduced in 11ee3fa
This commit is contained in:
@@ -163,11 +163,57 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
|
||||
1000.0 / static_cast<double>(
|
||||
normalized_framerate_limit))
|
||||
: 1.0;
|
||||
uint64_t last_frame_time = Clock::QueryGuestTickCount();
|
||||
// Sleep for 90% of the vblank duration on Windows, spin for 10%
|
||||
// Linux uses full sleep duration due to scheduler quantum issues
|
||||
#if XE_PLATFORM_WIN32
|
||||
constexpr double duration_scalar = 0.90;
|
||||
#endif
|
||||
#if XE_PLATFORM_LINUX
|
||||
constexpr double duration_scalar = 1.0;
|
||||
#endif
|
||||
|
||||
while (frame_limiter_worker_running_) {
|
||||
register_file()->values[XE_GPU_REG_D1MODE_V_COUNTER] +=
|
||||
GetInternalDisplayResolution().second;
|
||||
|
||||
#if XE_PLATFORM_WIN32
|
||||
if (cvars::vsync) {
|
||||
const uint64_t current_time = Clock::QueryGuestTickCount();
|
||||
const uint64_t tick_freq = Clock::guest_tick_frequency();
|
||||
const uint64_t time_delta = current_time - last_frame_time;
|
||||
const double elapsed_d =
|
||||
static_cast<double>(time_delta) /
|
||||
(static_cast<double>(tick_freq) / 1000.0);
|
||||
if (elapsed_d >= vsync_duration_d) {
|
||||
last_frame_time = current_time;
|
||||
|
||||
MarkVblank();
|
||||
const uint64_t estimated_nanoseconds = static_cast<uint64_t>(
|
||||
(vsync_duration_d * 1000000.0) *
|
||||
duration_scalar); // 1000 microseconds = 1 ms
|
||||
|
||||
threading::NanoSleep(estimated_nanoseconds);
|
||||
}
|
||||
}
|
||||
|
||||
if (!cvars::vsync) {
|
||||
MarkVblank();
|
||||
if (normalized_framerate_limit > 0) {
|
||||
// framerate_limit is over 0, vsync disabled
|
||||
// - No VSYNC + limited frames defined by user
|
||||
uint64_t framerate_limited_sleep_time =
|
||||
1000000000 / normalized_framerate_limit;
|
||||
xe::threading::NanoSleep(framerate_limited_sleep_time);
|
||||
} else {
|
||||
// framerate_limit is 0, vsync disabled
|
||||
// - No VSYNC + unlimited frames
|
||||
xe::threading::Sleep(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if XE_PLATFORM_LINUX
|
||||
// Linux: Use simplified timing logic to avoid oversleeping
|
||||
MarkVblank();
|
||||
|
||||
if (cvars::vsync || normalized_framerate_limit > 0) {
|
||||
@@ -180,6 +226,7 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
|
||||
} else {
|
||||
xe::threading::Sleep(std::chrono::milliseconds(1));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user