early-access version 2113
This commit is contained in:
		| @@ -1,7 +1,7 @@ | ||||
| yuzu emulator early access | ||||
| ============= | ||||
|  | ||||
| This is the source code for early-access 2112. | ||||
| This is the source code for early-access 2113. | ||||
|  | ||||
| ## Legal Notice | ||||
|  | ||||
|   | ||||
| @@ -140,25 +140,45 @@ struct System::Impl { | ||||
|           cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {} | ||||
|  | ||||
|     ResultStatus Run() { | ||||
|         std::unique_lock<std::mutex> lk(suspend_guard); | ||||
|         status = ResultStatus::Success; | ||||
|  | ||||
|         kernel.Suspend(false); | ||||
|         core_timing.SyncPause(false); | ||||
|         cpu_manager.Pause(false); | ||||
|         is_paused = false; | ||||
|  | ||||
|         return status; | ||||
|     } | ||||
|  | ||||
|     ResultStatus Pause() { | ||||
|         std::unique_lock<std::mutex> lk(suspend_guard); | ||||
|         status = ResultStatus::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(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) { | ||||
|         LOG_DEBUG(Core, "initialized OK"); | ||||
|  | ||||
| @@ -366,6 +386,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 | ||||
| @@ -476,6 +499,10 @@ void System::Shutdown() { | ||||
|     impl->Shutdown(); | ||||
| } | ||||
|  | ||||
| void System::stallForGPU(bool pause) { | ||||
|     impl->stallForGPU(pause); | ||||
| } | ||||
|  | ||||
| System::ResultStatus 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); | ||||
|   | ||||
| @@ -166,6 +166,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 | ||||
|   | ||||
| @@ -92,6 +92,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector | ||||
|     if (syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) { | ||||
|         params.value = syncpoint_manager.GetSyncpointMin(params.syncpt_id); | ||||
|         std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|         events_interface.failed[event_id] = false; | ||||
|         return NvResult::Success; | ||||
|     } | ||||
|  | ||||
| @@ -99,6 +100,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector | ||||
|         syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) { | ||||
|         params.value = new_value; | ||||
|         std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|         events_interface.failed[event_id] = false; | ||||
|         return NvResult::Success; | ||||
|     } | ||||
|  | ||||
| @@ -117,6 +119,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector | ||||
|         event.event->GetWritableEvent().Signal(); | ||||
|         params.value = current_syncpoint_value; | ||||
|         std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|         events_interface.failed[event_id] = false; | ||||
|         return NvResult::Success; | ||||
|     } | ||||
|     const u32 target_value = current_syncpoint_value - diff; | ||||
| @@ -146,6 +149,14 @@ 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]) { | ||||
|         system.stallForGPU(true); | ||||
|         gpu.WaitFence(params.syncpt_id, target_value); | ||||
|         system.stallForGPU(false); | ||||
|         std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|         events_interface.failed[event_id] = false; | ||||
|         return NvResult::Success; | ||||
|     } | ||||
|     gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value); | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return NvResult::Timeout; | ||||
| @@ -201,6 +212,7 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::v | ||||
|     if (events_interface.status[event_id] == EventState::Waiting) { | ||||
|         events_interface.LiberateEvent(event_id); | ||||
|     } | ||||
|     events_interface.failed[event_id] = true; | ||||
|  | ||||
|     syncpoint_manager.RefreshSyncpoint(events_interface.events[event_id].fence.id); | ||||
|  | ||||
|   | ||||
| @@ -49,6 +49,8 @@ struct EventInterface { | ||||
|     std::array<EventState, MaxNvEvents> status{}; | ||||
|     // Tells if an NVEvent is registered or not | ||||
|     std::array<bool, MaxNvEvents> registered{}; | ||||
|     // Tells the NVEvent that it has failed. | ||||
|     std::array<bool, MaxNvEvents> failed{}; | ||||
|     // When an NVEvent is waiting on GPU interrupt, this is the sync_point | ||||
|     // associated with it. | ||||
|     std::array<u32, MaxNvEvents> assigned_syncpt{}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user