Ver Fonte

Suspend temporally

FernandoS27 há 4 anos atrás
pai
commit
198c6ad0d7
3 ficheiros alterados com 31 adições e 1 exclusões
  1. 27 0
      src/core/core.cpp
  2. 2 0
      src/core/core.h
  3. 2 1
      src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp

+ 27 - 0
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);

+ 2 - 0
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

+ 2 - 1
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;