summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar FernandoS272021-10-05 23:54:33 +0200
committerGravatar Fernando Sahmkow2021-10-16 00:23:23 +0200
commit198c6ad0d728447dc97e467c8fb08f0b54c8a742 (patch)
tree615ce23c8f97ab60b8a16fa2890a421959cc2427
parentNVHost_Ctrl: Force wait if the gpu falls behind too long. (diff)
downloadyuzu-198c6ad0d728447dc97e467c8fb08f0b54c8a742.tar.gz
yuzu-198c6ad0d728447dc97e467c8fb08f0b54c8a742.tar.xz
yuzu-198c6ad0d728447dc97e467c8fb08f0b54c8a742.zip
Suspend temporally
-rw-r--r--src/core/core.cpp27
-rw-r--r--src/core/core.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp3
3 files changed, 31 insertions, 1 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 3532839df..4abf037e2 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -140,25 +140,45 @@ struct System::Impl {
140 cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {} 140 cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
141 141
142 SystemResultStatus Run() { 142 SystemResultStatus Run() {
143 std::unique_lock<std::mutex> lk(suspend_guard);
143 status = SystemResultStatus::Success; 144 status = SystemResultStatus::Success;
144 145
145 kernel.Suspend(false); 146 kernel.Suspend(false);
146 core_timing.SyncPause(false); 147 core_timing.SyncPause(false);
147 cpu_manager.Pause(false); 148 cpu_manager.Pause(false);
149 is_paused = false;
148 150
149 return status; 151 return status;
150 } 152 }
151 153
152 SystemResultStatus Pause() { 154 SystemResultStatus Pause() {
155 std::unique_lock<std::mutex> lk(suspend_guard);
153 status = SystemResultStatus::Success; 156 status = SystemResultStatus::Success;
154 157
155 core_timing.SyncPause(true); 158 core_timing.SyncPause(true);
156 kernel.Suspend(true); 159 kernel.Suspend(true);
157 cpu_manager.Pause(true); 160 cpu_manager.Pause(true);
161 is_paused = true;
158 162
159 return status; 163 return status;
160 } 164 }
161 165
166 void stallForGPU(bool pause) {
167 if (pause) {
168 suspend_guard.lock();
169 kernel.Suspend(pause);
170 core_timing.SyncPause(pause);
171 cpu_manager.Pause(pause);
172 } else {
173 if (!is_paused) {
174 core_timing.SyncPause(pause);
175 kernel.Suspend(pause);
176 cpu_manager.Pause(pause);
177 }
178 suspend_guard.unlock();
179 }
180 }
181
162 SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) { 182 SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
163 LOG_DEBUG(Core, "initialized OK"); 183 LOG_DEBUG(Core, "initialized OK");
164 184
@@ -367,6 +387,9 @@ struct System::Impl {
367 return perf_stats->GetAndResetStats(core_timing.GetGlobalTimeUs()); 387 return perf_stats->GetAndResetStats(core_timing.GetGlobalTimeUs());
368 } 388 }
369 389
390 std::mutex suspend_guard;
391 bool is_paused{};
392
370 Timing::CoreTiming core_timing; 393 Timing::CoreTiming core_timing;
371 Kernel::KernelCore kernel; 394 Kernel::KernelCore kernel;
372 /// RealVfsFilesystem instance 395 /// RealVfsFilesystem instance
@@ -464,6 +487,10 @@ void System::Shutdown() {
464 impl->Shutdown(); 487 impl->Shutdown();
465} 488}
466 489
490void System::stallForGPU(bool pause) {
491 impl->stallForGPU(pause);
492}
493
467SystemResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath, 494SystemResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
468 u64 program_id, std::size_t program_index) { 495 u64 program_id, std::size_t program_index) {
469 return impl->Load(*this, emu_window, filepath, program_id, program_index); 496 return impl->Load(*this, emu_window, filepath, program_id, program_index);
diff --git a/src/core/core.h b/src/core/core.h
index c1234ef77..8b21816cc 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -160,6 +160,8 @@ public:
160 /// Shutdown the emulated system. 160 /// Shutdown the emulated system.
161 void Shutdown(); 161 void Shutdown();
162 162
163 void stallForGPU(bool pause);
164
163 /** 165 /**
164 * Load an executable application. 166 * Load an executable application.
165 * @param emu_window Reference to the host-system window used for video output and keyboard 167 * @param emu_window Reference to the host-system window used for video output and keyboard
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 8bbb2c06e..b59eae55c 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -150,8 +150,9 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
150 params.value |= event_id; 150 params.value |= event_id;
151 event.event->GetWritableEvent().Clear(); 151 event.event->GetWritableEvent().Clear();
152 if (events_interface.failed[event_id]) { 152 if (events_interface.failed[event_id]) {
153 lock.unlock(); 153 system.stallForGPU(true);
154 gpu.WaitFence(params.syncpt_id, target_value); 154 gpu.WaitFence(params.syncpt_id, target_value);
155 system.stallForGPU(false);
155 std::memcpy(output.data(), &params, sizeof(params)); 156 std::memcpy(output.data(), &params, sizeof(params));
156 events_interface.failed[event_id] = false; 157 events_interface.failed[event_id] = false;
157 return NvResult::Success; 158 return NvResult::Success;