From ad92865497f83fe4c19cd9ab78cce9da1a8c3a6c Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 3 Apr 2020 11:58:43 -0400 Subject: [PATCH] General: Correct rebase, sync gpu and context management. --- src/core/core.cpp | 3 +-- src/core/cpu_manager.cpp | 11 ++--------- src/core/cpu_manager.h | 7 ------- src/video_core/gpu.h | 6 ++++++ src/video_core/gpu_asynch.cpp | 9 ++++++++- src/video_core/gpu_asynch.h | 2 ++ src/video_core/gpu_synch.cpp | 8 +++++++- src/video_core/gpu_synch.h | 2 ++ src/yuzu/bootmanager.cpp | 29 +++++++++++++++++------------ 9 files changed, 45 insertions(+), 32 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 40eea297e..3393c33eb 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -151,7 +151,6 @@ struct System::Impl { cpu_manager.SetMulticore(is_multicore); cpu_manager.SetAsyncGpu(is_async_gpu); core_timing.SetMulticore(is_multicore); - cpu_manager.SetRenderWindow(emu_window); core_timing.Initialize([&system]() { system.RegisterHostThread(); }); kernel.Initialize(); @@ -435,7 +434,7 @@ bool System::IsPoweredOn() const { } void System::PrepareReschedule() { - //impl->CurrentPhysicalCore().Stop(); + // impl->CurrentPhysicalCore().Stop(); } void System::PrepareReschedule(const u32 core_index) { diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index b7c2a7832..63c578852 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp @@ -9,12 +9,12 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/cpu_manager.h" -#include "core/frontend/emu_window.h" #include "core/gdbstub/gdbstub.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" +#include "video_core/gpu.h" namespace Core { @@ -25,10 +25,6 @@ void CpuManager::ThreadStart(CpuManager& cpu_manager, std::size_t core) { cpu_manager.RunThread(core); } -void CpuManager::SetRenderWindow(Core::Frontend::EmuWindow& render_window) { - this->render_window = &render_window; -} - void CpuManager::Initialize() { running_mode = true; if (is_multicore) { @@ -354,7 +350,7 @@ void CpuManager::RunThread(std::size_t core) { data.is_running = false; data.enter_barrier->Wait(); if (sc_sync_first_use) { - render_window->MakeCurrent(); + system.GPU().ObtainContext(); sc_sync_first_use = false; } auto& scheduler = system.Kernel().CurrentScheduler(); @@ -366,9 +362,6 @@ void CpuManager::RunThread(std::size_t core) { data.exit_barrier->Wait(); data.is_paused = false; } - if (sc_sync) { - render_window->DoneCurrent(); - } /// Time to cleanup data.host_context->Exit(); data.enter_barrier.reset(); diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h index ae55d6427..35929ed94 100644 --- a/src/core/cpu_manager.h +++ b/src/core/cpu_manager.h @@ -16,10 +16,6 @@ class Event; class Fiber; } // namespace Common -namespace Core::Frontend { -class EmuWindow; -} // namespace Core::Frontend - namespace Core { class System; @@ -61,8 +57,6 @@ public: return current_core.load(); } - void SetRenderWindow(Core::Frontend::EmuWindow& render_window); - private: static void GuestThreadFunction(void* cpu_manager); static void GuestRewindFunction(void* cpu_manager); @@ -106,7 +100,6 @@ private: std::size_t preemption_count{}; std::size_t idle_count{}; static constexpr std::size_t max_cycle_runs = 5; - Core::Frontend::EmuWindow* render_window; System& system; }; diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index a1b4c305c..2c42483bd 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -284,6 +284,12 @@ public: /// core timing events. virtual void Start() = 0; + /// Obtain the CPU Context + virtual void ObtainContext() = 0; + + /// Release the CPU Context + virtual void ReleaseContext() = 0; + /// Push GPU command entries to be processed virtual void PushGPUEntries(Tegra::CommandList&& entries) = 0; diff --git a/src/video_core/gpu_asynch.cpp b/src/video_core/gpu_asynch.cpp index 53305ab43..7b855f63e 100644 --- a/src/video_core/gpu_asynch.cpp +++ b/src/video_core/gpu_asynch.cpp @@ -19,10 +19,17 @@ GPUAsynch::GPUAsynch(Core::System& system, std::unique_ptrMakeCurrent(); gpu_thread.StartThread(*renderer, *gpu_context, *dma_pusher); } +void GPUAsynch::ObtainContext() { + cpu_context->MakeCurrent(); +} + +void GPUAsynch::ReleaseContext() { + cpu_context->DoneCurrent(); +} + void GPUAsynch::PushGPUEntries(Tegra::CommandList&& entries) { gpu_thread.SubmitList(std::move(entries)); } diff --git a/src/video_core/gpu_asynch.h b/src/video_core/gpu_asynch.h index 517658612..15e9f1d38 100644 --- a/src/video_core/gpu_asynch.h +++ b/src/video_core/gpu_asynch.h @@ -25,6 +25,8 @@ public: ~GPUAsynch() override; void Start() override; + void ObtainContext() override; + void ReleaseContext() override; void PushGPUEntries(Tegra::CommandList&& entries) override; void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override; void FlushRegion(VAddr addr, u64 size) override; diff --git a/src/video_core/gpu_synch.cpp b/src/video_core/gpu_synch.cpp index 6f38a672a..aaeb9811d 100644 --- a/src/video_core/gpu_synch.cpp +++ b/src/video_core/gpu_synch.cpp @@ -13,10 +13,16 @@ GPUSynch::GPUSynch(Core::System& system, std::unique_ptrMakeCurrent(); } +void GPUSynch::ReleaseContext() { + context->DoneCurrent(); +} + void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) { dma_pusher->Push(std::move(entries)); dma_pusher->DispatchCalls(); diff --git a/src/video_core/gpu_synch.h b/src/video_core/gpu_synch.h index 4a6e9a01d..762c20aa5 100644 --- a/src/video_core/gpu_synch.h +++ b/src/video_core/gpu_synch.h @@ -24,6 +24,8 @@ public: ~GPUSynch() override; void Start() override; + void ObtainContext() override; + void ReleaseContext() override; void PushGPUEntries(Tegra::CommandList&& entries) override; void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override; void FlushRegion(VAddr addr, u64 size) override; diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 6aa161e99..5f93bd432 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -48,24 +48,29 @@ void EmuThread::run() { MicroProfileOnThreadCreate(name.c_str()); Common::SetCurrentThreadName(name.c_str()); + auto& system = Core::System::GetInstance(); + + system.RegisterHostThread(); + + auto& gpu = system.GPU(); + // Main process has been loaded. Make the context current to this thread and begin GPU and CPU // execution. - Core::System::GetInstance().GPU().Start(); + gpu.Start(); + + gpu.ObtainContext(); emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); - Core::System::GetInstance().RegisterHostThread(); - - context.MakeCurrent(); - - Core::System::GetInstance().Renderer().Rasterizer().LoadDiskResources( + system.Renderer().Rasterizer().LoadDiskResources( stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { emit LoadProgress(stage, value, total); }); emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); - context.DoneCurrent(); + gpu.ReleaseContext(); + // Holds whether the cpu was running during the last iteration, // so that the DebugModeLeft signal can be emitted before the @@ -78,18 +83,18 @@ void EmuThread::run() { } running_guard = true; - Core::System::ResultStatus result = Core::System::GetInstance().Run(); + Core::System::ResultStatus result = system.Run(); if (result != Core::System::ResultStatus::Success) { running_guard = false; this->SetRunning(false); - emit ErrorThrown(result, Core::System::GetInstance().GetStatusDetails()); + emit ErrorThrown(result, system.GetStatusDetails()); } running_wait.Wait(); - result = Core::System::GetInstance().Pause(); + result = system.Pause(); if (result != Core::System::ResultStatus::Success) { running_guard = false; this->SetRunning(false); - emit ErrorThrown(result, Core::System::GetInstance().GetStatusDetails()); + emit ErrorThrown(result, system.GetStatusDetails()); } running_guard = false; @@ -106,7 +111,7 @@ void EmuThread::run() { } // Shutdown the core emulation - Core::System::GetInstance().Shutdown(); + system.Shutdown(); #if MICROPROFILE_ENABLED MicroProfileOnThreadExit();