VideoCommon/Fifo: Pass system instance through FifoManager constructor

Given how many member functions make use of the system instance,
it's likely just better to pass the system instance in on construction.

Makes the interface a little less noisy to use.
This commit is contained in:
Lioncache 2023-12-18 21:31:32 -05:00
parent 186b2f4e92
commit b0d244b772
10 changed files with 99 additions and 95 deletions

View File

@ -660,7 +660,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
wiifs_guard.Dismiss(); wiifs_guard.Dismiss();
// This adds the SyncGPU handler to CoreTiming, so now CoreTiming::Advance might block. // This adds the SyncGPU handler to CoreTiming, so now CoreTiming::Advance might block.
system.GetFifo().Prepare(system); system.GetFifo().Prepare();
// Setup our core // Setup our core
if (Config::Get(Config::MAIN_CPU_CORE) != PowerPC::CPUCore::Interpreter) if (Config::Get(Config::MAIN_CPU_CORE) != PowerPC::CPUCore::Interpreter)
@ -687,7 +687,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
s_cpu_thread = std::thread(cpuThreadFunc, savestate_path, delete_savestate); s_cpu_thread = std::thread(cpuThreadFunc, savestate_path, delete_savestate);
// become the GPU thread // become the GPU thread
system.GetFifo().RunGpuLoop(system); system.GetFifo().RunGpuLoop();
// We have now exited the Video Loop // We have now exited the Video Loop
INFO_LOG_FMT(CONSOLE, "{}", StopMessage(false, "Video Loop Ended")); INFO_LOG_FMT(CONSOLE, "{}", StopMessage(false, "Video Loop Ended"));
@ -834,7 +834,7 @@ static bool PauseAndLock(Core::System& system, bool do_lock, bool unpause_on_unl
// video has to come after CPU, because CPU thread can wait for video thread // video has to come after CPU, because CPU thread can wait for video thread
// (s_efbAccessRequested). // (s_efbAccessRequested).
system.GetFifo().PauseAndLock(system, do_lock, false); system.GetFifo().PauseAndLock(do_lock, false);
ResetRumble(); ResetRumble();
@ -1029,7 +1029,7 @@ void UpdateWantDeterminism(bool initial)
ios->UpdateWantDeterminism(new_want_determinism); ios->UpdateWantDeterminism(new_want_determinism);
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
system.GetFifo().UpdateWantDeterminism(system, new_want_determinism); system.GetFifo().UpdateWantDeterminism(new_want_determinism);
// We need to clear the cache because some parts of the JIT depend on want_determinism, // We need to clear the cache because some parts of the JIT depend on want_determinism,
// e.g. use of FMA. // e.g. use of FMA.

View File

@ -466,17 +466,15 @@ void CoreTimingManager::AdjustEventQueueTimes(u32 new_ppc_clock, u32 old_ppc_clo
void CoreTimingManager::Idle() void CoreTimingManager::Idle()
{ {
auto& system = m_system;
auto& ppc_state = m_system.GetPPCState();
if (m_config_sync_on_skip_idle) if (m_config_sync_on_skip_idle)
{ {
// When the FIFO is processing data we must not advance because in this way // When the FIFO is processing data we must not advance because in this way
// the VI will be desynchronized. So, We are waiting until the FIFO finish and // the VI will be desynchronized. So, We are waiting until the FIFO finish and
// while we process only the events required by the FIFO. // while we process only the events required by the FIFO.
system.GetFifo().FlushGpu(system); m_system.GetFifo().FlushGpu();
} }
auto& ppc_state = m_system.GetPPCState();
PowerPC::UpdatePerformanceMonitor(ppc_state.downcount, 0, 0, ppc_state); PowerPC::UpdatePerformanceMonitor(ppc_state.downcount, 0, 0, ppc_state);
m_idled_cycles += DowncountToCycles(ppc_state.downcount); m_idled_cycles += DowncountToCycles(ppc_state.downcount);
ppc_state.downcount = 0; ppc_state.downcount = 0;

View File

@ -42,9 +42,9 @@ struct System::Impl
{ {
explicit Impl(System& system) explicit Impl(System& system)
: m_audio_interface(system), m_core_timing(system), m_cpu(system), m_dsp(system), : m_audio_interface(system), m_core_timing(system), m_cpu(system), m_dsp(system),
m_dvd_interface(system), m_dvd_thread(system), m_expansion_interface(system), m_dvd_interface(system), m_dvd_thread(system),
m_gp_fifo(system), m_memory(system), m_power_pc(system), m_expansion_interface(system), m_fifo{system}, m_gp_fifo(system), m_memory(system),
m_mmu(system, m_memory, m_power_pc), m_processor_interface(system), m_power_pc(system), m_mmu(system, m_memory, m_power_pc), m_processor_interface(system),
m_serial_interface(system), m_video_interface(system), m_serial_interface(system), m_video_interface(system),
m_interpreter(system, m_power_pc.GetPPCState(), m_mmu), m_jit_interface(system) m_interpreter(system, m_power_pc.GetPPCState(), m_mmu), m_jit_interface(system)
{ {

View File

@ -106,9 +106,9 @@ static void RunWithGPUThreadInactive(std::function<void()> f)
const bool was_running = Core::GetState() == Core::State::Running; const bool was_running = Core::GetState() == Core::State::Running;
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
auto& fifo = system.GetFifo(); auto& fifo = system.GetFifo();
fifo.PauseAndLock(system, true, was_running); fifo.PauseAndLock(true, was_running);
f(); f();
fifo.PauseAndLock(system, false, was_running); fifo.PauseAndLock(false, was_running);
} }
else else
{ {

View File

@ -96,7 +96,7 @@ void AsyncRequests::PushEvent(const AsyncRequests::Event& event, bool blocking)
m_queue.push(event); m_queue.push(event);
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
system.GetFifo().RunGpu(system); system.GetFifo().RunGpu();
if (blocking) if (blocking)
{ {
m_cond.wait(lock, [this] { return m_queue.empty(); }); m_cond.wait(lock, [this] { return m_queue.empty(); });

View File

@ -224,7 +224,7 @@ void CommandProcessorManager::RegisterMMIO(Core::System& system, MMIO::Mapping*
mmio->Register(base | STATUS_REGISTER, MMIO::ComplexRead<u16>([](Core::System& system_, u32) { mmio->Register(base | STATUS_REGISTER, MMIO::ComplexRead<u16>([](Core::System& system_, u32) {
auto& cp = system_.GetCommandProcessor(); auto& cp = system_.GetCommandProcessor();
system_.GetFifo().SyncGPUForRegisterAccess(system_); system_.GetFifo().SyncGPUForRegisterAccess();
cp.SetCpStatusRegister(system_); cp.SetCpStatusRegister(system_);
return cp.m_cp_status_reg.Hex; return cp.m_cp_status_reg.Hex;
}), }),
@ -236,7 +236,7 @@ void CommandProcessorManager::RegisterMMIO(Core::System& system, MMIO::Mapping*
UCPCtrlReg tmp(val); UCPCtrlReg tmp(val);
cp.m_cp_ctrl_reg.Hex = tmp.Hex; cp.m_cp_ctrl_reg.Hex = tmp.Hex;
cp.SetCpControlRegister(system_); cp.SetCpControlRegister(system_);
system_.GetFifo().RunGpu(system_); system_.GetFifo().RunGpu();
})); }));
mmio->Register(base | CLEAR_REGISTER, MMIO::DirectRead<u16>(&m_cp_clear_reg.Hex), mmio->Register(base | CLEAR_REGISTER, MMIO::DirectRead<u16>(&m_cp_clear_reg.Hex),
@ -245,7 +245,7 @@ void CommandProcessorManager::RegisterMMIO(Core::System& system, MMIO::Mapping*
UCPClearReg tmp(val); UCPClearReg tmp(val);
cp.m_cp_clear_reg.Hex = tmp.Hex; cp.m_cp_clear_reg.Hex = tmp.Hex;
cp.SetCpClearRegister(); cp.SetCpClearRegister();
system_.GetFifo().RunGpu(system_); system_.GetFifo().RunGpu();
})); }));
mmio->Register(base | PERF_SELECT, MMIO::InvalidRead<u16>(), MMIO::Nop<u16>()); mmio->Register(base | PERF_SELECT, MMIO::InvalidRead<u16>(), MMIO::Nop<u16>());
@ -285,7 +285,7 @@ void CommandProcessorManager::RegisterMMIO(Core::System& system, MMIO::Mapping*
{ {
fifo_rw_distance_hi_r = MMIO::ComplexRead<u16>([](Core::System& system_, u32) { fifo_rw_distance_hi_r = MMIO::ComplexRead<u16>([](Core::System& system_, u32) {
const auto& fifo_ = system_.GetCommandProcessor().GetFifo(); const auto& fifo_ = system_.GetCommandProcessor().GetFifo();
system_.GetFifo().SyncGPUForRegisterAccess(system_); system_.GetFifo().SyncGPUForRegisterAccess();
if (fifo_.CPWritePointer.load(std::memory_order_relaxed) >= if (fifo_.CPWritePointer.load(std::memory_order_relaxed) >=
fifo_.SafeCPReadPointer.load(std::memory_order_relaxed)) fifo_.SafeCPReadPointer.load(std::memory_order_relaxed))
{ {
@ -307,16 +307,16 @@ void CommandProcessorManager::RegisterMMIO(Core::System& system, MMIO::Mapping*
{ {
fifo_rw_distance_hi_r = MMIO::ComplexRead<u16>([](Core::System& system_, u32) { fifo_rw_distance_hi_r = MMIO::ComplexRead<u16>([](Core::System& system_, u32) {
const auto& fifo_ = system_.GetCommandProcessor().GetFifo(); const auto& fifo_ = system_.GetCommandProcessor().GetFifo();
system_.GetFifo().SyncGPUForRegisterAccess(system_); system_.GetFifo().SyncGPUForRegisterAccess();
return fifo_.CPReadWriteDistance.load(std::memory_order_relaxed) >> 16; return fifo_.CPReadWriteDistance.load(std::memory_order_relaxed) >> 16;
}); });
} }
mmio->Register(base | FIFO_RW_DISTANCE_HI, fifo_rw_distance_hi_r, mmio->Register(base | FIFO_RW_DISTANCE_HI, fifo_rw_distance_hi_r,
MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](Core::System& system_, u32, u16 val) { MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](Core::System& system_, u32, u16 val) {
auto& fifo_ = system_.GetCommandProcessor().GetFifo(); auto& fifo_ = system_.GetCommandProcessor().GetFifo();
system_.GetFifo().SyncGPUForRegisterAccess(system_); system_.GetFifo().SyncGPUForRegisterAccess();
WriteHigh(fifo_.CPReadWriteDistance, val & WMASK_HI_RESTRICT); WriteHigh(fifo_.CPReadWriteDistance, val & WMASK_HI_RESTRICT);
system_.GetFifo().RunGpu(system_); system_.GetFifo().RunGpu();
})); }));
mmio->Register( mmio->Register(
@ -331,13 +331,13 @@ void CommandProcessorManager::RegisterMMIO(Core::System& system, MMIO::Mapping*
{ {
fifo_read_hi_r = MMIO::ComplexRead<u16>([](Core::System& system_, u32) { fifo_read_hi_r = MMIO::ComplexRead<u16>([](Core::System& system_, u32) {
auto& fifo_ = system_.GetCommandProcessor().GetFifo(); auto& fifo_ = system_.GetCommandProcessor().GetFifo();
system_.GetFifo().SyncGPUForRegisterAccess(system_); system_.GetFifo().SyncGPUForRegisterAccess();
return fifo_.SafeCPReadPointer.load(std::memory_order_relaxed) >> 16; return fifo_.SafeCPReadPointer.load(std::memory_order_relaxed) >> 16;
}); });
fifo_read_hi_w = fifo_read_hi_w =
MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](Core::System& system_, u32, u16 val) { MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](Core::System& system_, u32, u16 val) {
auto& fifo_ = system_.GetCommandProcessor().GetFifo(); auto& fifo_ = system_.GetCommandProcessor().GetFifo();
system_.GetFifo().SyncGPUForRegisterAccess(system_); system_.GetFifo().SyncGPUForRegisterAccess();
WriteHigh(fifo_.CPReadPointer, val & WMASK_HI_RESTRICT); WriteHigh(fifo_.CPReadPointer, val & WMASK_HI_RESTRICT);
fifo_.SafeCPReadPointer.store(fifo_.CPReadPointer.load(std::memory_order_relaxed), fifo_.SafeCPReadPointer.store(fifo_.CPReadPointer.load(std::memory_order_relaxed),
std::memory_order_relaxed); std::memory_order_relaxed);
@ -347,13 +347,13 @@ void CommandProcessorManager::RegisterMMIO(Core::System& system, MMIO::Mapping*
{ {
fifo_read_hi_r = MMIO::ComplexRead<u16>([](Core::System& system_, u32) { fifo_read_hi_r = MMIO::ComplexRead<u16>([](Core::System& system_, u32) {
const auto& fifo_ = system_.GetCommandProcessor().GetFifo(); const auto& fifo_ = system_.GetCommandProcessor().GetFifo();
system_.GetFifo().SyncGPUForRegisterAccess(system_); system_.GetFifo().SyncGPUForRegisterAccess();
return fifo_.CPReadPointer.load(std::memory_order_relaxed) >> 16; return fifo_.CPReadPointer.load(std::memory_order_relaxed) >> 16;
}); });
fifo_read_hi_w = fifo_read_hi_w =
MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](Core::System& system_, u32, u16 val) { MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](Core::System& system_, u32, u16 val) {
auto& fifo_ = system_.GetCommandProcessor().GetFifo(); auto& fifo_ = system_.GetCommandProcessor().GetFifo();
system_.GetFifo().SyncGPUForRegisterAccess(system_); system_.GetFifo().SyncGPUForRegisterAccess();
WriteHigh(fifo_.CPReadPointer, val & WMASK_HI_RESTRICT); WriteHigh(fifo_.CPReadPointer, val & WMASK_HI_RESTRICT);
}); });
} }
@ -379,10 +379,10 @@ void CommandProcessorManager::GatherPipeBursted(Core::System& system)
(processor_interface.m_fifo_cpu_base == fifo.CPBase.load(std::memory_order_relaxed)) && (processor_interface.m_fifo_cpu_base == fifo.CPBase.load(std::memory_order_relaxed)) &&
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) > 0) fifo.CPReadWriteDistance.load(std::memory_order_relaxed) > 0)
{ {
system.GetFifo().FlushGpu(system); system.GetFifo().FlushGpu();
} }
} }
system.GetFifo().RunGpu(system); system.GetFifo().RunGpu();
return; return;
} }
@ -411,7 +411,7 @@ void CommandProcessorManager::GatherPipeBursted(Core::System& system)
fifo.CPReadWriteDistance.fetch_add(GPFifo::GATHER_PIPE_SIZE, std::memory_order_seq_cst); fifo.CPReadWriteDistance.fetch_add(GPFifo::GATHER_PIPE_SIZE, std::memory_order_seq_cst);
system.GetFifo().RunGpu(system); system.GetFifo().RunGpu();
ASSERT_MSG(COMMANDPROCESSOR, ASSERT_MSG(COMMANDPROCESSOR,
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) <= fifo.CPReadWriteDistance.load(std::memory_order_relaxed) <=
@ -448,7 +448,7 @@ void CommandProcessorManager::UpdateInterrupts(Core::System& system, u64 userdat
} }
system.GetCoreTiming().ForceExceptionCheck(0); system.GetCoreTiming().ForceExceptionCheck(0);
m_interrupt_waiting.Clear(); m_interrupt_waiting.Clear();
system.GetFifo().RunGpu(system); system.GetFifo().RunGpu();
} }
void CommandProcessorManager::UpdateInterruptsFromVideoBackend(Core::System& system, u64 userdata) void CommandProcessorManager::UpdateInterruptsFromVideoBackend(Core::System& system, u64 userdata)
@ -616,7 +616,7 @@ void CommandProcessorManager::SetCpControlRegister(Core::System& system)
if (fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && !m_cp_ctrl_reg.GPReadEnable) if (fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && !m_cp_ctrl_reg.GPReadEnable)
{ {
fifo.bFF_GPReadEnable.store(m_cp_ctrl_reg.GPReadEnable, std::memory_order_relaxed); fifo.bFF_GPReadEnable.store(m_cp_ctrl_reg.GPReadEnable, std::memory_order_relaxed);
system.GetFifo().FlushGpu(system); system.GetFifo().FlushGpu();
} }
else else
{ {

View File

@ -36,7 +36,10 @@ namespace Fifo
{ {
static constexpr int GPU_TIME_SLOT_SIZE = 1000; static constexpr int GPU_TIME_SLOT_SIZE = 1000;
FifoManager::FifoManager() = default; FifoManager::FifoManager(Core::System& system) : m_system{system}
{
}
FifoManager::~FifoManager() = default; FifoManager::~FifoManager() = default;
void FifoManager::RefreshConfig() void FifoManager::RefreshConfig()
@ -64,26 +67,26 @@ void FifoManager::DoState(PointerWrap& p)
p.Do(m_syncing_suspended); p.Do(m_syncing_suspended);
} }
void FifoManager::PauseAndLock(Core::System& system, bool doLock, bool unpauseOnUnlock) void FifoManager::PauseAndLock(bool do_lock, bool unpause_on_unlock)
{ {
if (doLock) if (do_lock)
{ {
SyncGPU(SyncGPUReason::Other); SyncGPU(SyncGPUReason::Other);
EmulatorState(false); EmulatorState(false);
if (!system.IsDualCoreMode() || m_use_deterministic_gpu_thread) if (!m_system.IsDualCoreMode() || m_use_deterministic_gpu_thread)
return; return;
m_gpu_mainloop.WaitYield(std::chrono::milliseconds(100), Host_YieldToUI); m_gpu_mainloop.WaitYield(std::chrono::milliseconds(100), Host_YieldToUI);
} }
else else
{ {
if (unpauseOnUnlock) if (unpause_on_unlock)
EmulatorState(true); EmulatorState(true);
} }
} }
void FifoManager::Init(Core::System& system) void FifoManager::Init()
{ {
if (!m_config_callback_id) if (!m_config_callback_id)
m_config_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); }); m_config_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); });
@ -92,7 +95,7 @@ void FifoManager::Init(Core::System& system)
// Padded so that SIMD overreads in the vertex loader are safe // Padded so that SIMD overreads in the vertex loader are safe
m_video_buffer = static_cast<u8*>(Common::AllocateMemoryPages(FIFO_SIZE + 4)); m_video_buffer = static_cast<u8*>(Common::AllocateMemoryPages(FIFO_SIZE + 4));
ResetVideoBuffer(); ResetVideoBuffer();
if (system.IsDualCoreMode()) if (m_system.IsDualCoreMode())
m_gpu_mainloop.Prepare(); m_gpu_mainloop.Prepare();
m_sync_ticks.store(0); m_sync_ticks.store(0);
} }
@ -120,14 +123,14 @@ void FifoManager::Shutdown()
// May be executed from any thread, even the graphics thread. // May be executed from any thread, even the graphics thread.
// Created to allow for self shutdown. // Created to allow for self shutdown.
void FifoManager::ExitGpuLoop(Core::System& system) void FifoManager::ExitGpuLoop()
{ {
auto& command_processor = system.GetCommandProcessor(); auto& command_processor = m_system.GetCommandProcessor();
auto& fifo = command_processor.GetFifo(); auto& fifo = command_processor.GetFifo();
// This should break the wait loop in CPU thread // This should break the wait loop in CPU thread
fifo.bFF_GPReadEnable.store(0, std::memory_order_relaxed); fifo.bFF_GPReadEnable.store(0, std::memory_order_relaxed);
FlushGpu(system); FlushGpu();
// Terminate GPU thread loop // Terminate GPU thread loop
m_emu_running_state.Set(); m_emu_running_state.Set();
@ -211,7 +214,7 @@ void* FifoManager::PopFifoAuxBuffer(size_t size)
} }
// Description: RunGpuLoop() sends data through this function. // Description: RunGpuLoop() sends data through this function.
void FifoManager::ReadDataFromFifo(Core::System& system, u32 readPtr) void FifoManager::ReadDataFromFifo(u32 read_ptr)
{ {
if (GPFifo::GATHER_PIPE_SIZE > if (GPFifo::GATHER_PIPE_SIZE >
static_cast<size_t>(m_video_buffer + FIFO_SIZE - m_video_buffer_write_ptr)) static_cast<size_t>(m_video_buffer + FIFO_SIZE - m_video_buffer_write_ptr))
@ -228,13 +231,13 @@ void FifoManager::ReadDataFromFifo(Core::System& system, u32 readPtr)
m_video_buffer_read_ptr = m_video_buffer; m_video_buffer_read_ptr = m_video_buffer;
} }
// Copy new video instructions to m_video_buffer for future use in rendering the new picture // Copy new video instructions to m_video_buffer for future use in rendering the new picture
auto& memory = system.GetMemory(); auto& memory = m_system.GetMemory();
memory.CopyFromEmu(m_video_buffer_write_ptr, readPtr, GPFifo::GATHER_PIPE_SIZE); memory.CopyFromEmu(m_video_buffer_write_ptr, read_ptr, GPFifo::GATHER_PIPE_SIZE);
m_video_buffer_write_ptr += GPFifo::GATHER_PIPE_SIZE; m_video_buffer_write_ptr += GPFifo::GATHER_PIPE_SIZE;
} }
// The deterministic_gpu_thread version. // The deterministic_gpu_thread version.
void FifoManager::ReadDataFromFifoOnCPU(Core::System& system, u32 readPtr) void FifoManager::ReadDataFromFifoOnCPU(u32 read_ptr)
{ {
u8* write_ptr = m_video_buffer_write_ptr; u8* write_ptr = m_video_buffer_write_ptr;
if (GPFifo::GATHER_PIPE_SIZE > static_cast<size_t>(m_video_buffer + FIFO_SIZE - write_ptr)) if (GPFifo::GATHER_PIPE_SIZE > static_cast<size_t>(m_video_buffer + FIFO_SIZE - write_ptr))
@ -262,8 +265,8 @@ void FifoManager::ReadDataFromFifoOnCPU(Core::System& system, u32 readPtr)
return; return;
} }
} }
auto& memory = system.GetMemory(); auto& memory = m_system.GetMemory();
memory.CopyFromEmu(m_video_buffer_write_ptr, readPtr, GPFifo::GATHER_PIPE_SIZE); memory.CopyFromEmu(m_video_buffer_write_ptr, read_ptr, GPFifo::GATHER_PIPE_SIZE);
m_video_buffer_pp_read_ptr = OpcodeDecoder::RunFifo<true>( m_video_buffer_pp_read_ptr = OpcodeDecoder::RunFifo<true>(
DataReader(m_video_buffer_pp_read_ptr, write_ptr + GPFifo::GATHER_PIPE_SIZE), nullptr); DataReader(m_video_buffer_pp_read_ptr, write_ptr + GPFifo::GATHER_PIPE_SIZE), nullptr);
// This would have to be locked if the GPU thread didn't spin. // This would have to be locked if the GPU thread didn't spin.
@ -282,13 +285,13 @@ void FifoManager::ResetVideoBuffer()
// Description: Main FIFO update loop // Description: Main FIFO update loop
// Purpose: Keep the Core HW updated about the CPU-GPU distance // Purpose: Keep the Core HW updated about the CPU-GPU distance
void FifoManager::RunGpuLoop(Core::System& system) void FifoManager::RunGpuLoop()
{ {
AsyncRequests::GetInstance()->SetEnable(true); AsyncRequests::GetInstance()->SetEnable(true);
AsyncRequests::GetInstance()->SetPassthrough(false); AsyncRequests::GetInstance()->SetPassthrough(false);
m_gpu_mainloop.Run( m_gpu_mainloop.Run(
[this, &system] { [this] {
// Run events from the CPU thread. // Run events from the CPU thread.
AsyncRequests::GetInstance()->PullEvents(); AsyncRequests::GetInstance()->PullEvents();
@ -311,21 +314,22 @@ void FifoManager::RunGpuLoop(Core::System& system)
} }
else else
{ {
auto& command_processor = system.GetCommandProcessor(); auto& command_processor = m_system.GetCommandProcessor();
auto& fifo = command_processor.GetFifo(); auto& fifo = command_processor.GetFifo();
command_processor.SetCPStatusFromGPU(system); command_processor.SetCPStatusFromGPU(m_system);
// check if we are able to run this buffer // check if we are able to run this buffer
while (!command_processor.IsInterruptWaiting() && while (!command_processor.IsInterruptWaiting() &&
fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) &&
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) && !AtBreakpoint(system)) fifo.CPReadWriteDistance.load(std::memory_order_relaxed) &&
!AtBreakpoint(m_system))
{ {
if (m_config_sync_gpu && m_sync_ticks.load() < m_config_sync_gpu_min_distance) if (m_config_sync_gpu && m_sync_ticks.load() < m_config_sync_gpu_min_distance)
break; break;
u32 cyclesExecuted = 0; u32 cyclesExecuted = 0;
u32 readPtr = fifo.CPReadPointer.load(std::memory_order_relaxed); u32 readPtr = fifo.CPReadPointer.load(std::memory_order_relaxed);
ReadDataFromFifo(system, readPtr); ReadDataFromFifo(readPtr);
if (readPtr == fifo.CPEnd.load(std::memory_order_relaxed)) if (readPtr == fifo.CPEnd.load(std::memory_order_relaxed))
readPtr = fifo.CPBase.load(std::memory_order_relaxed); readPtr = fifo.CPBase.load(std::memory_order_relaxed);
@ -352,7 +356,7 @@ void FifoManager::RunGpuLoop(Core::System& system)
std::memory_order_relaxed); std::memory_order_relaxed);
} }
command_processor.SetCPStatusFromGPU(system); command_processor.SetCPStatusFromGPU(m_system);
if (m_config_sync_gpu) if (m_config_sync_gpu)
{ {
@ -392,9 +396,9 @@ void FifoManager::RunGpuLoop(Core::System& system)
AsyncRequests::GetInstance()->SetPassthrough(true); AsyncRequests::GetInstance()->SetPassthrough(true);
} }
void FifoManager::FlushGpu(Core::System& system) void FifoManager::FlushGpu()
{ {
if (!system.IsDualCoreMode() || m_use_deterministic_gpu_thread) if (!m_system.IsDualCoreMode() || m_use_deterministic_gpu_thread)
return; return;
m_gpu_mainloop.Wait(); m_gpu_mainloop.Wait();
@ -414,9 +418,9 @@ bool AtBreakpoint(Core::System& system)
fifo.CPBreakpoint.load(std::memory_order_relaxed)); fifo.CPBreakpoint.load(std::memory_order_relaxed));
} }
void FifoManager::RunGpu(Core::System& system) void FifoManager::RunGpu()
{ {
const bool is_dual_core = system.IsDualCoreMode(); const bool is_dual_core = m_system.IsDualCoreMode();
// wake up GPU thread // wake up GPU thread
if (is_dual_core && !m_use_deterministic_gpu_thread) if (is_dual_core && !m_use_deterministic_gpu_thread)
@ -430,25 +434,25 @@ void FifoManager::RunGpu(Core::System& system)
if (m_syncing_suspended) if (m_syncing_suspended)
{ {
m_syncing_suspended = false; m_syncing_suspended = false;
system.GetCoreTiming().ScheduleEvent(GPU_TIME_SLOT_SIZE, m_event_sync_gpu, m_system.GetCoreTiming().ScheduleEvent(GPU_TIME_SLOT_SIZE, m_event_sync_gpu,
GPU_TIME_SLOT_SIZE); GPU_TIME_SLOT_SIZE);
} }
} }
} }
int FifoManager::RunGpuOnCpu(Core::System& system, int ticks) int FifoManager::RunGpuOnCpu(int ticks)
{ {
auto& command_processor = system.GetCommandProcessor(); auto& command_processor = m_system.GetCommandProcessor();
auto& fifo = command_processor.GetFifo(); auto& fifo = command_processor.GetFifo();
bool reset_simd_state = false; bool reset_simd_state = false;
int available_ticks = int(ticks * m_config_sync_gpu_overclock) + m_sync_ticks.load(); int available_ticks = int(ticks * m_config_sync_gpu_overclock) + m_sync_ticks.load();
while (fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && while (fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) &&
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) && !AtBreakpoint(system) && fifo.CPReadWriteDistance.load(std::memory_order_relaxed) && !AtBreakpoint(m_system) &&
available_ticks >= 0) available_ticks >= 0)
{ {
if (m_use_deterministic_gpu_thread) if (m_use_deterministic_gpu_thread)
{ {
ReadDataFromFifoOnCPU(system, fifo.CPReadPointer.load(std::memory_order_relaxed)); ReadDataFromFifoOnCPU(fifo.CPReadPointer.load(std::memory_order_relaxed));
m_gpu_mainloop.Wakeup(); m_gpu_mainloop.Wakeup();
} }
else else
@ -459,7 +463,7 @@ int FifoManager::RunGpuOnCpu(Core::System& system, int ticks)
Common::FPU::LoadDefaultSIMDState(); Common::FPU::LoadDefaultSIMDState();
reset_simd_state = true; reset_simd_state = true;
} }
ReadDataFromFifo(system, fifo.CPReadPointer.load(std::memory_order_relaxed)); ReadDataFromFifo(fifo.CPReadPointer.load(std::memory_order_relaxed));
u32 cycles = 0; u32 cycles = 0;
m_video_buffer_read_ptr = OpcodeDecoder::RunFifo( m_video_buffer_read_ptr = OpcodeDecoder::RunFifo(
DataReader(m_video_buffer_read_ptr, m_video_buffer_write_ptr), &cycles); DataReader(m_video_buffer_read_ptr, m_video_buffer_write_ptr), &cycles);
@ -480,7 +484,7 @@ int FifoManager::RunGpuOnCpu(Core::System& system, int ticks)
fifo.CPReadWriteDistance.fetch_sub(GPFifo::GATHER_PIPE_SIZE, std::memory_order_relaxed); fifo.CPReadWriteDistance.fetch_sub(GPFifo::GATHER_PIPE_SIZE, std::memory_order_relaxed);
} }
command_processor.SetCPStatusFromGPU(system); command_processor.SetCPStatusFromGPU(m_system);
if (reset_simd_state) if (reset_simd_state)
{ {
@ -498,7 +502,7 @@ int FifoManager::RunGpuOnCpu(Core::System& system, int ticks)
return -available_ticks + GPU_TIME_SLOT_SIZE; return -available_ticks + GPU_TIME_SLOT_SIZE;
} }
void FifoManager::UpdateWantDeterminism(Core::System& system, bool want) void FifoManager::UpdateWantDeterminism(bool want)
{ {
// We are paused (or not running at all yet), so // We are paused (or not running at all yet), so
// it should be safe to change this. // it should be safe to change this.
@ -516,7 +520,7 @@ void FifoManager::UpdateWantDeterminism(Core::System& system, bool want)
break; break;
} }
gpu_thread = gpu_thread && system.IsDualCoreMode(); gpu_thread = gpu_thread && m_system.IsDualCoreMode();
if (m_use_deterministic_gpu_thread != gpu_thread) if (m_use_deterministic_gpu_thread != gpu_thread)
{ {
@ -536,7 +540,7 @@ void FifoManager::UpdateWantDeterminism(Core::System& system, bool want)
* @ticks The gone emulated CPU time. * @ticks The gone emulated CPU time.
* @return A good time to call WaitForGpuThread() next. * @return A good time to call WaitForGpuThread() next.
*/ */
int FifoManager::WaitForGpuThread(Core::System& system, int ticks) int FifoManager::WaitForGpuThread(int ticks)
{ {
int old = m_sync_ticks.fetch_add(ticks); int old = m_sync_ticks.fetch_add(ticks);
int now = old + ticks; int now = old + ticks;
@ -547,7 +551,7 @@ int FifoManager::WaitForGpuThread(Core::System& system, int ticks)
// Wakeup GPU // Wakeup GPU
if (old < m_config_sync_gpu_min_distance && now >= m_config_sync_gpu_min_distance) if (old < m_config_sync_gpu_min_distance && now >= m_config_sync_gpu_min_distance)
RunGpu(system); RunGpu();
// If the GPU is still sleeping, wait for a longer time // If the GPU is still sleeping, wait for a longer time
if (now < m_config_sync_gpu_min_distance) if (now < m_config_sync_gpu_min_distance)
@ -568,11 +572,11 @@ void FifoManager::SyncGPUCallback(Core::System& system, u64 ticks, s64 cyclesLat
auto& fifo = system.GetFifo(); auto& fifo = system.GetFifo();
if (!system.IsDualCoreMode() || fifo.m_use_deterministic_gpu_thread) if (!system.IsDualCoreMode() || fifo.m_use_deterministic_gpu_thread)
{ {
next = fifo.RunGpuOnCpu(system, (int)ticks); next = fifo.RunGpuOnCpu(int(ticks));
} }
else if (fifo.m_config_sync_gpu) else if (fifo.m_config_sync_gpu)
{ {
next = fifo.WaitForGpuThread(system, (int)ticks); next = fifo.WaitForGpuThread(int(ticks));
} }
fifo.m_syncing_suspended = next < 0; fifo.m_syncing_suspended = next < 0;
@ -580,20 +584,20 @@ void FifoManager::SyncGPUCallback(Core::System& system, u64 ticks, s64 cyclesLat
system.GetCoreTiming().ScheduleEvent(next, fifo.m_event_sync_gpu, next); system.GetCoreTiming().ScheduleEvent(next, fifo.m_event_sync_gpu, next);
} }
void FifoManager::SyncGPUForRegisterAccess(Core::System& system) void FifoManager::SyncGPUForRegisterAccess()
{ {
SyncGPU(SyncGPUReason::Other); SyncGPU(SyncGPUReason::Other);
if (!system.IsDualCoreMode() || m_use_deterministic_gpu_thread) if (!m_system.IsDualCoreMode() || m_use_deterministic_gpu_thread)
RunGpuOnCpu(system, GPU_TIME_SLOT_SIZE); RunGpuOnCpu(GPU_TIME_SLOT_SIZE);
else if (m_config_sync_gpu) else if (m_config_sync_gpu)
WaitForGpuThread(system, GPU_TIME_SLOT_SIZE); WaitForGpuThread(GPU_TIME_SLOT_SIZE);
} }
// Initialize GPU - CPU thread syncing, this gives us a deterministic way to start the GPU thread. // Initialize GPU - CPU thread syncing, this gives us a deterministic way to start the GPU thread.
void FifoManager::Prepare(Core::System& system) void FifoManager::Prepare()
{ {
m_event_sync_gpu = system.GetCoreTiming().RegisterEvent("SyncGPUCallback", SyncGPUCallback); m_event_sync_gpu = m_system.GetCoreTiming().RegisterEvent("SyncGPUCallback", SyncGPUCallback);
m_syncing_suspended = true; m_syncing_suspended = true;
} }
} // namespace Fifo } // namespace Fifo

View File

@ -41,19 +41,19 @@ enum class SyncGPUReason
class FifoManager final class FifoManager final
{ {
public: public:
FifoManager(); explicit FifoManager(Core::System& system);
FifoManager(const FifoManager& other) = delete; FifoManager(const FifoManager& other) = delete;
FifoManager(FifoManager&& other) = delete; FifoManager(FifoManager&& other) = delete;
FifoManager& operator=(const FifoManager& other) = delete; FifoManager& operator=(const FifoManager& other) = delete;
FifoManager& operator=(FifoManager&& other) = delete; FifoManager& operator=(FifoManager&& other) = delete;
~FifoManager(); ~FifoManager();
void Init(Core::System& system); void Init();
void Shutdown(); void Shutdown();
void Prepare(Core::System& system); // Must be called from the CPU thread. void Prepare(); // Must be called from the CPU thread.
void DoState(PointerWrap& f); void DoState(PointerWrap& f);
void PauseAndLock(Core::System& system, bool doLock, bool unpauseOnUnlock); void PauseAndLock(bool do_lock, bool unpause_on_unlock);
void UpdateWantDeterminism(Core::System& system, bool want); void UpdateWantDeterminism(bool want);
bool UseDeterministicGPUThread() const { return m_use_deterministic_gpu_thread; } bool UseDeterministicGPUThread() const { return m_use_deterministic_gpu_thread; }
bool UseSyncGPU() const { return m_config_sync_gpu; } bool UseSyncGPU() const { return m_config_sync_gpu; }
@ -62,25 +62,25 @@ public:
// In single core mode, this runs the GPU for a single slice. // In single core mode, this runs the GPU for a single slice.
// In dual core mode, this synchronizes with the GPU thread. // In dual core mode, this synchronizes with the GPU thread.
void SyncGPUForRegisterAccess(Core::System& system); void SyncGPUForRegisterAccess();
void PushFifoAuxBuffer(const void* ptr, size_t size); void PushFifoAuxBuffer(const void* ptr, size_t size);
void* PopFifoAuxBuffer(size_t size); void* PopFifoAuxBuffer(size_t size);
void FlushGpu(Core::System& system); void FlushGpu();
void RunGpu(Core::System& system); void RunGpu();
void GpuMaySleep(); void GpuMaySleep();
void RunGpuLoop(Core::System& system); void RunGpuLoop();
void ExitGpuLoop(Core::System& system); void ExitGpuLoop();
void EmulatorState(bool running); void EmulatorState(bool running);
void ResetVideoBuffer(); void ResetVideoBuffer();
private: private:
void RefreshConfig(); void RefreshConfig();
void ReadDataFromFifo(Core::System& system, u32 readPtr); void ReadDataFromFifo(u32 read_ptr);
void ReadDataFromFifoOnCPU(Core::System& system, u32 readPtr); void ReadDataFromFifoOnCPU(u32 read_ptr);
int RunGpuOnCpu(Core::System& system, int ticks); int RunGpuOnCpu(int ticks);
int WaitForGpuThread(Core::System& system, int ticks); int WaitForGpuThread(int ticks);
static void SyncGPUCallback(Core::System& system, u64 ticks, s64 cyclesLate); static void SyncGPUCallback(Core::System& system, u64 ticks, s64 cyclesLate);
static constexpr u32 FIFO_SIZE = 2 * 1024 * 1024; static constexpr u32 FIFO_SIZE = 2 * 1024 * 1024;
@ -127,6 +127,8 @@ private:
int m_config_sync_gpu_max_distance = 0; int m_config_sync_gpu_max_distance = 0;
int m_config_sync_gpu_min_distance = 0; int m_config_sync_gpu_min_distance = 0;
float m_config_sync_gpu_overclock = 0.0f; float m_config_sync_gpu_overclock = 0.0f;
Core::System& m_system;
}; };
bool AtBreakpoint(Core::System& system); bool AtBreakpoint(Core::System& system);

View File

@ -93,7 +93,7 @@ std::string VideoBackendBase::BadShaderFilename(const char* shader_stage, int co
void VideoBackendBase::Video_ExitLoop() void VideoBackendBase::Video_ExitLoop()
{ {
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
system.GetFifo().ExitGpuLoop(system); system.GetFifo().ExitGpuLoop();
} }
// Run from the CPU thread (from VideoInterface.cpp) // Run from the CPU thread (from VideoInterface.cpp)
@ -379,7 +379,7 @@ bool VideoBackendBase::InitializeShared(std::unique_ptr<AbstractGfx> gfx,
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
auto& command_processor = system.GetCommandProcessor(); auto& command_processor = system.GetCommandProcessor();
command_processor.Init(system); command_processor.Init(system);
system.GetFifo().Init(system); system.GetFifo().Init();
system.GetPixelEngine().Init(system); system.GetPixelEngine().Init(system);
BPInit(); BPInit();
VertexLoaderManager::Init(); VertexLoaderManager::Init();

View File

@ -67,13 +67,13 @@ void VideoConfig::Refresh()
const bool lock_gpu_thread = Core::IsRunningAndStarted(); const bool lock_gpu_thread = Core::IsRunningAndStarted();
if (lock_gpu_thread) if (lock_gpu_thread)
system.GetFifo().PauseAndLock(system, true, false); system.GetFifo().PauseAndLock(true, false);
g_Config.Refresh(); g_Config.Refresh();
g_Config.VerifyValidity(); g_Config.VerifyValidity();
if (lock_gpu_thread) if (lock_gpu_thread)
system.GetFifo().PauseAndLock(system, false, true); system.GetFifo().PauseAndLock(false, true);
}); });
s_has_registered_callback = true; s_has_registered_callback = true;
} }