summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-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 {
cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
SystemResultStatus Run() {
+ std::unique_lock<std::mutex> lk(suspend_guard);
status = SystemResultStatus::Success;
kernel.Suspend(false);
core_timing.SyncPause(false);
cpu_manager.Pause(false);
+ is_paused = false;
return status;
}
SystemResultStatus Pause() {
+ std::unique_lock<std::mutex> lk(suspend_guard);
status = SystemResultStatus::Success;
core_timing.SyncPause(true);
kernel.Suspend(true);
cpu_manager.Pause(true);
+ is_paused = true;
return status;
}
+ void stallForGPU(bool pause) {
+ if (pause) {
+ suspend_guard.lock();
+ kernel.Suspend(pause);
+ core_timing.SyncPause(pause);
+ cpu_manager.Pause(pause);
+ } else {
+ if (!is_paused) {
+ core_timing.SyncPause(pause);
+ kernel.Suspend(pause);
+ cpu_manager.Pause(pause);
+ }
+ suspend_guard.unlock();
+ }
+ }
+
SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
LOG_DEBUG(Core, "initialized OK");
@@ -367,6 +387,9 @@ struct System::Impl {
return perf_stats->GetAndResetStats(core_timing.GetGlobalTimeUs());
}
+ std::mutex suspend_guard;
+ bool is_paused{};
+
Timing::CoreTiming core_timing;
Kernel::KernelCore kernel;
/// RealVfsFilesystem instance
@@ -464,6 +487,10 @@ void System::Shutdown() {
impl->Shutdown();
}
+void System::stallForGPU(bool pause) {
+ impl->stallForGPU(pause);
+}
+
SystemResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
u64 program_id, std::size_t program_index) {
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:
/// Shutdown the emulated system.
void Shutdown();
+ void stallForGPU(bool pause);
+
/**
* Load an executable application.
* @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
params.value |= event_id;
event.event->GetWritableEvent().Clear();
if (events_interface.failed[event_id]) {
- lock.unlock();
+ system.stallForGPU(true);
gpu.WaitFence(params.syncpt_id, target_value);
+ system.stallForGPU(false);
std::memcpy(output.data(), &params, sizeof(params));
events_interface.failed[event_id] = false;
return NvResult::Success;