aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/control
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 15:56:45 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 20:49:48 -0400
commit72fc31f44b954f8e0ebf1a36c2c8565eec83be3a (patch)
tree71ae751ef6162d6d5d14322e8b55428df28f12aa /src/video_core/control
parentc30df71ee0752005e0be3bbf2f3233b65f38cabc (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.cpp7
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;
}