diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 15:56:45 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 20:49:48 -0400 |
| commit | 72fc31f44b954f8e0ebf1a36c2c8565eec83be3a (patch) | |
| tree | 71ae751ef6162d6d5d14322e8b55428df28f12aa /src/video_core/control | |
| parent | c30df71ee0752005e0be3bbf2f3233b65f38cabc (diff) | |
video_core: stop resuming pending channels once the system is powered off
At shutdown is_powered_on is cleared before the GPU thread is stopped.
A channel suspended on a semaphore acquire that can resume then went
through DispatchCalls, which returns at once when powered off, so the
acquire stayed pending and ResumePending counted it as progress forever:
the GPU thread never got back to its stop request and closing the game
hung in ThreadManager::NotifyShutdown.
Diffstat (limited to 'src/video_core/control')
| -rw-r--r-- | src/video_core/control/scheduler.cpp | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/src/video_core/control/scheduler.cpp b/src/video_core/control/scheduler.cpp index c120533c37..dc42906752 100644 --- a/src/video_core/control/scheduler.cpp +++ b/src/video_core/control/scheduler.cpp @@ -9,6 +9,7 @@ #include <vector> #include "common/assert.h" +#include "core/core.h" #include "video_core/control/channel_state.h" #include "video_core/control/scheduler.h" #include "video_core/gpu.h" @@ -59,6 +60,12 @@ void Scheduler::ResumePending(GPU& gpu) { progress = false; for (const auto& state : pending_channels) { auto& dma_pusher = state->payload->dma_pusher; + // Powered off (shutting down), DispatchCalls returns at once and the acquire stays + // pending: resuming it again counted as progress forever and the GPU thread never + // reached its stop request (closing the game hung). + if (!dma_pusher.system.IsPoweredOn()) { + return; + } if (!dma_pusher.HasPendingAcquire() || !dma_pusher.CanResumeAcquire()) { continue; } |
