General: Correct rebase, sync gpu and context management.

This commit is contained in:
Fernando Sahmkow 2020-04-03 11:58:43 -04:00
parent bfb5244cf8
commit ad92865497
9 changed files with 45 additions and 32 deletions

View file

@ -151,7 +151,6 @@ struct System::Impl {
cpu_manager.SetMulticore(is_multicore); cpu_manager.SetMulticore(is_multicore);
cpu_manager.SetAsyncGpu(is_async_gpu); cpu_manager.SetAsyncGpu(is_async_gpu);
core_timing.SetMulticore(is_multicore); core_timing.SetMulticore(is_multicore);
cpu_manager.SetRenderWindow(emu_window);
core_timing.Initialize([&system]() { system.RegisterHostThread(); }); core_timing.Initialize([&system]() { system.RegisterHostThread(); });
kernel.Initialize(); kernel.Initialize();
@ -435,7 +434,7 @@ bool System::IsPoweredOn() const {
} }
void System::PrepareReschedule() { void System::PrepareReschedule() {
//impl->CurrentPhysicalCore().Stop(); // impl->CurrentPhysicalCore().Stop();
} }
void System::PrepareReschedule(const u32 core_index) { void System::PrepareReschedule(const u32 core_index) {

View file

@ -9,12 +9,12 @@
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/cpu_manager.h" #include "core/cpu_manager.h"
#include "core/frontend/emu_window.h"
#include "core/gdbstub/gdbstub.h" #include "core/gdbstub/gdbstub.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/scheduler.h"
#include "core/hle/kernel/thread.h" #include "core/hle/kernel/thread.h"
#include "video_core/gpu.h"
namespace Core { namespace Core {
@ -25,10 +25,6 @@ void CpuManager::ThreadStart(CpuManager& cpu_manager, std::size_t core) {
cpu_manager.RunThread(core); cpu_manager.RunThread(core);
} }
void CpuManager::SetRenderWindow(Core::Frontend::EmuWindow& render_window) {
this->render_window = &render_window;
}
void CpuManager::Initialize() { void CpuManager::Initialize() {
running_mode = true; running_mode = true;
if (is_multicore) { if (is_multicore) {
@ -354,7 +350,7 @@ void CpuManager::RunThread(std::size_t core) {
data.is_running = false; data.is_running = false;
data.enter_barrier->Wait(); data.enter_barrier->Wait();
if (sc_sync_first_use) { if (sc_sync_first_use) {
render_window->MakeCurrent(); system.GPU().ObtainContext();
sc_sync_first_use = false; sc_sync_first_use = false;
} }
auto& scheduler = system.Kernel().CurrentScheduler(); auto& scheduler = system.Kernel().CurrentScheduler();
@ -366,9 +362,6 @@ void CpuManager::RunThread(std::size_t core) {
data.exit_barrier->Wait(); data.exit_barrier->Wait();
data.is_paused = false; data.is_paused = false;
} }
if (sc_sync) {
render_window->DoneCurrent();
}
/// Time to cleanup /// Time to cleanup
data.host_context->Exit(); data.host_context->Exit();
data.enter_barrier.reset(); data.enter_barrier.reset();

View file

@ -16,10 +16,6 @@ class Event;
class Fiber; class Fiber;
} // namespace Common } // namespace Common
namespace Core::Frontend {
class EmuWindow;
} // namespace Core::Frontend
namespace Core { namespace Core {
class System; class System;
@ -61,8 +57,6 @@ public:
return current_core.load(); return current_core.load();
} }
void SetRenderWindow(Core::Frontend::EmuWindow& render_window);
private: private:
static void GuestThreadFunction(void* cpu_manager); static void GuestThreadFunction(void* cpu_manager);
static void GuestRewindFunction(void* cpu_manager); static void GuestRewindFunction(void* cpu_manager);
@ -106,7 +100,6 @@ private:
std::size_t preemption_count{}; std::size_t preemption_count{};
std::size_t idle_count{}; std::size_t idle_count{};
static constexpr std::size_t max_cycle_runs = 5; static constexpr std::size_t max_cycle_runs = 5;
Core::Frontend::EmuWindow* render_window;
System& system; System& system;
}; };

View file

@ -284,6 +284,12 @@ public:
/// core timing events. /// core timing events.
virtual void Start() = 0; 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 /// Push GPU command entries to be processed
virtual void PushGPUEntries(Tegra::CommandList&& entries) = 0; virtual void PushGPUEntries(Tegra::CommandList&& entries) = 0;

View file

@ -19,10 +19,17 @@ GPUAsynch::GPUAsynch(Core::System& system, std::unique_ptr<VideoCore::RendererBa
GPUAsynch::~GPUAsynch() = default; GPUAsynch::~GPUAsynch() = default;
void GPUAsynch::Start() { void GPUAsynch::Start() {
cpu_context->MakeCurrent();
gpu_thread.StartThread(*renderer, *gpu_context, *dma_pusher); 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) { void GPUAsynch::PushGPUEntries(Tegra::CommandList&& entries) {
gpu_thread.SubmitList(std::move(entries)); gpu_thread.SubmitList(std::move(entries));
} }

View file

@ -25,6 +25,8 @@ public:
~GPUAsynch() override; ~GPUAsynch() override;
void Start() override; void Start() override;
void ObtainContext() override;
void ReleaseContext() override;
void PushGPUEntries(Tegra::CommandList&& entries) override; void PushGPUEntries(Tegra::CommandList&& entries) override;
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override; void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
void FlushRegion(VAddr addr, u64 size) override; void FlushRegion(VAddr addr, u64 size) override;

View file

@ -13,10 +13,16 @@ GPUSynch::GPUSynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase
GPUSynch::~GPUSynch() = default; GPUSynch::~GPUSynch() = default;
void GPUSynch::Start() { void GPUSynch::Start() {}
void GPUSynch::ObtainContext() {
context->MakeCurrent(); context->MakeCurrent();
} }
void GPUSynch::ReleaseContext() {
context->DoneCurrent();
}
void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) { void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) {
dma_pusher->Push(std::move(entries)); dma_pusher->Push(std::move(entries));
dma_pusher->DispatchCalls(); dma_pusher->DispatchCalls();

View file

@ -24,6 +24,8 @@ public:
~GPUSynch() override; ~GPUSynch() override;
void Start() override; void Start() override;
void ObtainContext() override;
void ReleaseContext() override;
void PushGPUEntries(Tegra::CommandList&& entries) override; void PushGPUEntries(Tegra::CommandList&& entries) override;
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override; void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
void FlushRegion(VAddr addr, u64 size) override; void FlushRegion(VAddr addr, u64 size) override;

View file

@ -48,24 +48,29 @@ void EmuThread::run() {
MicroProfileOnThreadCreate(name.c_str()); MicroProfileOnThreadCreate(name.c_str());
Common::SetCurrentThreadName(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 // Main process has been loaded. Make the context current to this thread and begin GPU and CPU
// execution. // execution.
Core::System::GetInstance().GPU().Start(); gpu.Start();
gpu.ObtainContext();
emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
Core::System::GetInstance().RegisterHostThread(); system.Renderer().Rasterizer().LoadDiskResources(
context.MakeCurrent();
Core::System::GetInstance().Renderer().Rasterizer().LoadDiskResources(
stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
emit LoadProgress(stage, value, total); emit LoadProgress(stage, value, total);
}); });
emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
context.DoneCurrent(); gpu.ReleaseContext();
// Holds whether the cpu was running during the last iteration, // Holds whether the cpu was running during the last iteration,
// so that the DebugModeLeft signal can be emitted before the // so that the DebugModeLeft signal can be emitted before the
@ -78,18 +83,18 @@ void EmuThread::run() {
} }
running_guard = true; running_guard = true;
Core::System::ResultStatus result = Core::System::GetInstance().Run(); Core::System::ResultStatus result = system.Run();
if (result != Core::System::ResultStatus::Success) { if (result != Core::System::ResultStatus::Success) {
running_guard = false; running_guard = false;
this->SetRunning(false); this->SetRunning(false);
emit ErrorThrown(result, Core::System::GetInstance().GetStatusDetails()); emit ErrorThrown(result, system.GetStatusDetails());
} }
running_wait.Wait(); running_wait.Wait();
result = Core::System::GetInstance().Pause(); result = system.Pause();
if (result != Core::System::ResultStatus::Success) { if (result != Core::System::ResultStatus::Success) {
running_guard = false; running_guard = false;
this->SetRunning(false); this->SetRunning(false);
emit ErrorThrown(result, Core::System::GetInstance().GetStatusDetails()); emit ErrorThrown(result, system.GetStatusDetails());
} }
running_guard = false; running_guard = false;
@ -106,7 +111,7 @@ void EmuThread::run() {
} }
// Shutdown the core emulation // Shutdown the core emulation
Core::System::GetInstance().Shutdown(); system.Shutdown();
#if MICROPROFILE_ENABLED #if MICROPROFILE_ENABLED
MicroProfileOnThreadExit(); MicroProfileOnThreadExit();