291 changes: 148 additions & 143 deletions Source/Core/VideoCommon/CommandProcessor.cpp

Large diffs are not rendered by default.

103 changes: 68 additions & 35 deletions Source/Core/VideoCommon/CommandProcessor.h
Expand Up @@ -6,48 +6,53 @@
#include <atomic>

#include "Common/CommonTypes.h"
#include "Common/Flag.h"

class PointerWrap;
namespace MMIO
{
class Mapping;
}
namespace Core
{
class System;
}
namespace CoreTiming
{
struct EventType;
}

namespace CommandProcessor
{
struct SCPFifoStruct
{
// fifo registers
std::atomic<u32> CPBase;
std::atomic<u32> CPEnd;
std::atomic<u32> CPBase = 0;
std::atomic<u32> CPEnd = 0;
u32 CPHiWatermark = 0;
u32 CPLoWatermark = 0;
std::atomic<u32> CPReadWriteDistance;
std::atomic<u32> CPWritePointer;
std::atomic<u32> CPReadPointer;
std::atomic<u32> CPBreakpoint;
std::atomic<u32> SafeCPReadPointer;
std::atomic<u32> CPReadWriteDistance = 0;
std::atomic<u32> CPWritePointer = 0;
std::atomic<u32> CPReadPointer = 0;
std::atomic<u32> CPBreakpoint = 0;
std::atomic<u32> SafeCPReadPointer = 0;

std::atomic<u32> bFF_GPLinkEnable;
std::atomic<u32> bFF_GPReadEnable;
std::atomic<u32> bFF_BPEnable;
std::atomic<u32> bFF_BPInt;
std::atomic<u32> bFF_Breakpoint;
std::atomic<u32> bFF_GPLinkEnable = 0;
std::atomic<u32> bFF_GPReadEnable = 0;
std::atomic<u32> bFF_BPEnable = 0;
std::atomic<u32> bFF_BPInt = 0;
std::atomic<u32> bFF_Breakpoint = 0;

std::atomic<u32> bFF_LoWatermarkInt;
std::atomic<u32> bFF_HiWatermarkInt;
std::atomic<u32> bFF_LoWatermarkInt = 0;
std::atomic<u32> bFF_HiWatermarkInt = 0;

std::atomic<u32> bFF_LoWatermark;
std::atomic<u32> bFF_HiWatermark;
std::atomic<u32> bFF_LoWatermark = 0;
std::atomic<u32> bFF_HiWatermark = 0;

void Init();
void DoState(PointerWrap& p);
};

// This one is shared between gfx thread and emulator thread.
// It is only used by the Fifo and by the CommandProcessor.
extern SCPFifoStruct fifo;

// internal hardware addresses
enum
{
Expand Down Expand Up @@ -150,26 +155,54 @@ union UCPClearReg
UCPClearReg(u16 _hex) { Hex = _hex; }
};

// Init
void Init();
void DoState(PointerWrap& p);
u32 GetPhysicalAddressMask();

void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
class CommandProcessorManager
{
public:
void Init(Core::System& system);
void DoState(PointerWrap& p);

void SetCPStatusFromGPU();
void SetCPStatusFromCPU();
void GatherPipeBursted();
void UpdateInterrupts(u64 userdata);
void UpdateInterruptsFromVideoBackend(u64 userdata);
void RegisterMMIO(Core::System& system, MMIO::Mapping* mmio, u32 base);

bool IsInterruptWaiting();
void SetCPStatusFromGPU(Core::System& system);
void SetCPStatusFromCPU(Core::System& system);
void GatherPipeBursted(Core::System& system);
void UpdateInterrupts(Core::System& system, u64 userdata);
void UpdateInterruptsFromVideoBackend(Core::System& system, u64 userdata);

void SetCpClearRegister();
void SetCpControlRegister();
void SetCpStatusRegister();
bool IsInterruptWaiting() const;

void HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess);
void SetCpClearRegister();
void SetCpControlRegister();
void SetCpStatusRegister();

u32 GetPhysicalAddressMask();
void HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess);

// This one is shared between gfx thread and emulator thread.
// It is only used by the Fifo and by the CommandProcessor.
SCPFifoStruct& GetFifo() { return m_fifo; }

private:
SCPFifoStruct m_fifo;

CoreTiming::EventType* m_event_type_update_interrupts = nullptr;

// STATE_TO_SAVE
UCPStatusReg m_cp_status_reg;
UCPCtrlReg m_cp_ctrl_reg;
UCPClearReg m_cp_clear_reg;

u16 m_bbox_left = 0;
u16 m_bbox_top = 0;
u16 m_bbox_right = 0;
u16 m_bbox_bottom = 0;
u16 m_token_reg = 0;

Common::Flag m_interrupt_set;
Common::Flag m_interrupt_waiting;

bool m_is_fifo_error_seen = false;
};

} // namespace CommandProcessor
26 changes: 18 additions & 8 deletions Source/Core/VideoCommon/Fifo.cpp
Expand Up @@ -163,8 +163,12 @@ void Shutdown()
// Created to allow for self shutdown.
void ExitGpuLoop()
{
auto& system = Core::System::GetInstance();
auto& command_processor = system.GetCommandProcessor();
auto& fifo = command_processor.GetFifo();

// This should break the wait loop in CPU thread
CommandProcessor::fifo.bFF_GPReadEnable.store(0, std::memory_order_relaxed);
fifo.bFF_GPReadEnable.store(0, std::memory_order_relaxed);
FlushGpu();

// Terminate GPU thread loop
Expand Down Expand Up @@ -347,11 +351,13 @@ void RunGpuLoop()
}
else
{
CommandProcessor::SCPFifoStruct& fifo = CommandProcessor::fifo;
CommandProcessor::SetCPStatusFromGPU();
auto& system = Core::System::GetInstance();
auto& command_processor = system.GetCommandProcessor();
auto& fifo = command_processor.GetFifo();
command_processor.SetCPStatusFromGPU(system);

// check if we are able to run this buffer
while (!CommandProcessor::IsInterruptWaiting() &&
while (!command_processor.IsInterruptWaiting() &&
fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) &&
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) && !AtBreakpoint())
{
Expand Down Expand Up @@ -387,7 +393,7 @@ void RunGpuLoop()
std::memory_order_relaxed);
}

CommandProcessor::SetCPStatusFromGPU();
command_processor.SetCPStatusFromGPU(system);

if (s_config_sync_gpu)
{
Expand Down Expand Up @@ -440,7 +446,9 @@ void GpuMaySleep()

bool AtBreakpoint()
{
CommandProcessor::SCPFifoStruct& fifo = CommandProcessor::fifo;
auto& system = Core::System::GetInstance();
auto& command_processor = system.GetCommandProcessor();
const auto& fifo = command_processor.GetFifo();
return fifo.bFF_BPEnable.load(std::memory_order_relaxed) &&
(fifo.CPReadPointer.load(std::memory_order_relaxed) ==
fifo.CPBreakpoint.load(std::memory_order_relaxed));
Expand Down Expand Up @@ -471,7 +479,9 @@ void RunGpu()

static int RunGpuOnCpu(int ticks)
{
CommandProcessor::SCPFifoStruct& fifo = CommandProcessor::fifo;
auto& system = Core::System::GetInstance();
auto& command_processor = system.GetCommandProcessor();
auto& fifo = command_processor.GetFifo();
bool reset_simd_state = false;
int available_ticks = int(ticks * s_config_sync_gpu_overclock) + s_sync_ticks.load();
while (fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) &&
Expand Down Expand Up @@ -512,7 +522,7 @@ static int RunGpuOnCpu(int ticks)
fifo.CPReadWriteDistance.fetch_sub(GPFifo::GATHER_PIPE_SIZE, std::memory_order_relaxed);
}

CommandProcessor::SetCPStatusFromGPU();
command_processor.SetCPStatusFromGPU(system);

if (reset_simd_state)
{
Expand Down
4 changes: 3 additions & 1 deletion Source/Core/VideoCommon/OpcodeDecoding.cpp
Expand Up @@ -18,6 +18,7 @@
#include "Common/Logging/Log.h"
#include "Core/FifoPlayer/FifoRecorder.h"
#include "Core/HW/Memmap.h"
#include "Core/System.h"
#include "VideoCommon/BPMemory.h"
#include "VideoCommon/CPMemory.h"
#include "VideoCommon/CommandProcessor.h"
Expand Down Expand Up @@ -207,7 +208,8 @@ class RunCallback final : public Callback
}
else
{
CommandProcessor::HandleUnknownOpcode(opcode, data, is_preprocess);
Core::System::GetInstance().GetCommandProcessor().HandleUnknownOpcode(opcode, data,
is_preprocess);
m_cycles += 1;
}
}
Expand Down
9 changes: 6 additions & 3 deletions Source/Core/VideoCommon/RenderBase.cpp
Expand Up @@ -51,6 +51,7 @@
#include "Core/HW/VideoInterface.h"
#include "Core/Host.h"
#include "Core/Movie.h"
#include "Core/System.h"

#include "InputCommon/ControllerInterface/ControllerInterface.h"

Expand Down Expand Up @@ -1007,9 +1008,11 @@ void Renderer::CheckFifoRecording()
RecordVideoMemory();
}

FifoRecorder::GetInstance().EndFrame(
CommandProcessor::fifo.CPBase.load(std::memory_order_relaxed),
CommandProcessor::fifo.CPEnd.load(std::memory_order_relaxed));
auto& system = Core::System::GetInstance();
auto& command_processor = system.GetCommandProcessor();
const auto& fifo = command_processor.GetFifo();
FifoRecorder::GetInstance().EndFrame(fifo.CPBase.load(std::memory_order_relaxed),
fifo.CPEnd.load(std::memory_order_relaxed));
}

void Renderer::RecordVideoMemory()
Expand Down
4 changes: 3 additions & 1 deletion Source/Core/VideoCommon/VideoBackendBase.cpp
Expand Up @@ -316,7 +316,9 @@ void VideoBackendBase::InitializeShared()
// do not initialize again for the config window
m_initialized = true;

CommandProcessor::Init();
auto& system = Core::System::GetInstance();
auto& command_processor = system.GetCommandProcessor();
command_processor.Init(system);
Fifo::Init();
PixelEngine::Init();
BPInit();
Expand Down
5 changes: 4 additions & 1 deletion Source/Core/VideoCommon/VideoState.cpp
Expand Up @@ -6,6 +6,7 @@
#include <cstring>

#include "Common/ChunkFile.h"
#include "Core/System.h"
#include "VideoCommon/BPMemory.h"
#include "VideoCommon/CPMemory.h"
#include "VideoCommon/CommandProcessor.h"
Expand Down Expand Up @@ -62,7 +63,9 @@ void VideoCommon_DoState(PointerWrap& p)
Fifo::DoState(p);
p.DoMarker("Fifo");

CommandProcessor::DoState(p);
auto& system = Core::System::GetInstance();
auto& command_processor = system.GetCommandProcessor();
command_processor.DoState(p);
p.DoMarker("CommandProcessor");

PixelEngine::DoState(p);
Expand Down