General: Correct rebase, sync gpu and context management.
This commit is contained in:
parent
bfb5244cf8
commit
ad92865497
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Reference in New Issue