diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-30 00:54:19 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-30 00:54:38 -0400 |
| commit | 092c16d6f39b395e7b3e105a42963733bf9de045 (patch) | |
| tree | fd0913c27aa5a40b2d39b1d4e518a4e420462542 | |
| parent | 59fce4d557a23e33bcd671710ea9f7b292dcdb46 (diff) | |
gpu_split: reset the ring when the split stops
GpuSplit is a static instance and outlives the emulation session. Stop()
joined the back thread but kept the ring positions and engine pointers,
so the next session's back thread started reading at 0 of a new, empty
ring while `published` still held the old session's position: each
empty entry reads as a wrap, the back thread skipped ahead a ring at a
time and never landed on the old position. The front then spun in
Drain(), the next game's first GPU work never ran, and it waited on its
first syncpoint forever (Mario Kart World loaded after another Switch 2
game: syncpoint 2 stuck at 0, waiting for 2). The back thread also held
the previous session's freed engines.
Stop() now drops the ring and resets the positions, the engines and the
front macro mode, so MaybeStart() begins a clean ring.
| -rw-r--r-- | src/video_core/gpu_split.cpp | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/video_core/gpu_split.cpp b/src/video_core/gpu_split.cpp index 07fda589ff..f913ca82ce 100644 --- a/src/video_core/gpu_split.cpp +++ b/src/video_core/gpu_split.cpp @@ -122,6 +122,21 @@ void GpuSplit::Stop() { wake.notify_one(); back_thread.join(); active = false; + // The split is static and outlives the emulation session. The next session's back thread + // starts reading at 0: with the old positions kept it skipped through the new, empty ring a + // wrap at a time and never reached the old write position (the next game's first GPU work + // never ran, it waited on its syncpoint forever), and the engines it held were freed. + ring.reset(); + write_position = 0; + published_local = 0; + consumed_cache = 0; + publish_every = PublishEvery; + front_engine = nullptr; + back_engine = nullptr; + front_macros = false; + published.store(0, std::memory_order_relaxed); + consumed.store(0, std::memory_order_relaxed); + back_waiting.store(false, std::memory_order_relaxed); } u64* GpuSplit::ReserveSlow(size_t words) { |
