diff options
| author | Duck912 <350528965+Duck912@users.noreply.github.com> | 2026-11-01 21:39:54 -0500 |
|---|---|---|
| committer | Duck912 <350528965+Duck912@users.noreply.github.com> | 2026-11-01 21:54:48 -0500 |
| commit | e7973dae7e2ea44665ff4ec83d7214a5d2daa366 (patch) | |
| tree | 84c7df0a4a94effb91f1260c2998d70b3f4349b1 | |
| parent | 9f22054c6360fcc1bafa673451a5764f5f2ca7d1 (diff) | |
nx2:vi2: sleep in the guest kernel while pacing presents
The vi2 session is served by AM's thread on guest core 3, so the host
sleep in PaceToVblank held that core for most of every frame. Game
threads scheduled there only ran between presents: Fire Emblem:
Fortune's Weave's loader got one RomFS read per frame (33 ms apart
instead of about 4 ms), which doubled its load times.
Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting)
Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
| -rw-r--r-- | src/core/hle/service/nx2_gsv.h | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/src/core/hle/service/nx2_gsv.h b/src/core/hle/service/nx2_gsv.h index b8268b91a0..397e2aacb8 100644 --- a/src/core/hle/service/nx2_gsv.h +++ b/src/core/hle/service/nx2_gsv.h @@ -46,8 +46,10 @@ #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/k_event.h" +#include "core/hle/kernel/k_hardware_timer.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_session.h" +#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/svc_results.h" #include "core/memory.h" @@ -1589,7 +1591,12 @@ private: // Running slower than the swap interval: show at once and don't bank the lost time. m_next_vblank = now; } else if (now < m_next_vblank) { - std::this_thread::sleep_until(m_next_vblank); + // Sleep this service thread in the guest kernel. It runs on guest core 3, and a host + // sleep held that core for the whole wait: game threads scheduled there ran only + // between presents (Fortune's Weave's loader read one RomFS block per frame). + const auto wait = std::chrono::duration_cast<std::chrono::nanoseconds>(m_next_vblank - now); + static_cast<void>(Kernel::GetCurrentThread(kernel).Sleep( + kernel, kernel.HardwareTimer().GetTick() + wait.count() + 2)); } m_next_vblank += interval; } |
