Skip to content

Commit

Permalink
Merge pull request dolphin-emu#11407 from AdmiralCurtiss/globals-gpfifo
Browse files Browse the repository at this point in the history
HW/GPFifo: Refactor to class, move to Core::System.
  • Loading branch information
AdmiralCurtiss authored Jan 9, 2023
2 parents eeeab3c + d33416f commit 21c29ba
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 102 deletions.
51 changes: 34 additions & 17 deletions Source/Core/Core/FifoPlayer/FifoPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,9 @@ void FifoPlayer::WriteFifo(const u8* data, u32 start, u32 end)
u32 written = start;
u32 lastBurstEnd = end - 1;

auto& core_timing = Core::System::GetInstance().GetCoreTiming();
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
auto& gpfifo = system.GetGPFifo();

// Write up to 256 bytes at a time
while (written < end)
Expand All @@ -530,7 +532,7 @@ void FifoPlayer::WriteFifo(const u8* data, u32 start, u32 end)
PowerPC::ppcState.gather_pipe_ptr += burstEnd - written;
written = burstEnd;

GPFifo::Write8(data[written++]);
gpfifo.Write8(data[written++]);

// Advance core timing
u32 elapsedCycles = u32(((u64)written * m_CyclesPerFrame) / m_FrameFifoSize);
Expand Down Expand Up @@ -706,13 +708,16 @@ void FifoPlayer::WritePI(u32 address, u32 value)

void FifoPlayer::FlushWGP()
{
auto& system = Core::System::GetInstance();
auto& gpfifo = system.GetGPFifo();

// Send 31 0s through the WGP
for (int i = 0; i < 7; ++i)
GPFifo::Write32(0);
GPFifo::Write16(0);
GPFifo::Write8(0);
gpfifo.Write32(0);
gpfifo.Write16(0);
gpfifo.Write8(0);

GPFifo::ResetGatherPipe();
gpfifo.ResetGatherPipe();
}

void FifoPlayer::WaitForGPUInactive()
Expand All @@ -729,34 +734,46 @@ void FifoPlayer::WaitForGPUInactive()

void FifoPlayer::LoadBPReg(u8 reg, u32 value)
{
GPFifo::Write8(0x61); // load BP reg
auto& system = Core::System::GetInstance();
auto& gpfifo = system.GetGPFifo();

gpfifo.Write8(0x61); // load BP reg

u32 cmd = (reg << 24) & 0xff000000;
cmd |= (value & 0x00ffffff);
GPFifo::Write32(cmd);
gpfifo.Write32(cmd);
}

void FifoPlayer::LoadCPReg(u8 reg, u32 value)
{
GPFifo::Write8(0x08); // load CP reg
GPFifo::Write8(reg);
GPFifo::Write32(value);
auto& system = Core::System::GetInstance();
auto& gpfifo = system.GetGPFifo();

gpfifo.Write8(0x08); // load CP reg
gpfifo.Write8(reg);
gpfifo.Write32(value);
}

void FifoPlayer::LoadXFReg(u16 reg, u32 value)
{
GPFifo::Write8(0x10); // load XF reg
GPFifo::Write32((reg & 0x0fff) | 0x1000); // load 4 bytes into reg
GPFifo::Write32(value);
auto& system = Core::System::GetInstance();
auto& gpfifo = system.GetGPFifo();

gpfifo.Write8(0x10); // load XF reg
gpfifo.Write32((reg & 0x0fff) | 0x1000); // load 4 bytes into reg
gpfifo.Write32(value);
}

void FifoPlayer::LoadXFMem16(u16 address, const u32* data)
{
auto& system = Core::System::GetInstance();
auto& gpfifo = system.GetGPFifo();

// Loads 16 * 4 bytes in xf memory starting at address
GPFifo::Write8(0x10); // load XF reg
GPFifo::Write32(0x000f0000 | (address & 0xffff)); // load 16 * 4 bytes into address
gpfifo.Write8(0x10); // load XF reg
gpfifo.Write32(0x000f0000 | (address & 0xffff)); // load 16 * 4 bytes into address
for (int i = 0; i < 16; ++i)
GPFifo::Write32(data[i]);
gpfifo.Write32(data[i]);
}

bool FifoPlayer::ShouldLoadBP(u8 address)
Expand Down
66 changes: 38 additions & 28 deletions Source/Core/Core/HW/GPFifo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

namespace GPFifo
{
GPFifoManager::GPFifoManager(Core::System& system) : m_system(system)
{
}

// 32 Byte gather pipe with extra space
// Overfilling is no problem (up to the real limit), CheckGatherPipe will blast the
// contents in nicely sized chunks
Expand All @@ -29,35 +33,32 @@ namespace GPFifo
// Both of these should actually work! Only problem is that we have to decide at run time,
// the same function could use both methods. Compile 2 different versions of each such block?

// More room for the fastmodes
alignas(GATHER_PIPE_SIZE) static u8 s_gather_pipe[GATHER_PIPE_EXTRA_SIZE];

static size_t GetGatherPipeCount()
size_t GPFifoManager::GetGatherPipeCount()
{
return PowerPC::ppcState.gather_pipe_ptr - s_gather_pipe;
return PowerPC::ppcState.gather_pipe_ptr - m_gather_pipe;
}

static void SetGatherPipeCount(size_t size)
void GPFifoManager::SetGatherPipeCount(size_t size)
{
PowerPC::ppcState.gather_pipe_ptr = s_gather_pipe + size;
PowerPC::ppcState.gather_pipe_ptr = m_gather_pipe + size;
}

void DoState(PointerWrap& p)
void GPFifoManager::DoState(PointerWrap& p)
{
p.Do(s_gather_pipe);
p.Do(m_gather_pipe);
u32 pipe_count = static_cast<u32>(GetGatherPipeCount());
p.Do(pipe_count);
SetGatherPipeCount(pipe_count);
}

void Init()
void GPFifoManager::Init()
{
ResetGatherPipe();
PowerPC::ppcState.gather_pipe_base_ptr = s_gather_pipe;
memset(s_gather_pipe, 0, sizeof(s_gather_pipe));
PowerPC::ppcState.gather_pipe_base_ptr = m_gather_pipe;
memset(m_gather_pipe, 0, sizeof(m_gather_pipe));
}

bool IsBNE()
bool GPFifoManager::IsBNE() const
{
// TODO: It's not clear exactly when the BNE (buffer not empty) bit is set.
// The PPC 750cl manual says in section 2.1.2.12 "Write Pipe Address Register (WPAR)" (page 78):
Expand All @@ -76,14 +77,14 @@ bool IsBNE()
return false;
}

void ResetGatherPipe()
void GPFifoManager::ResetGatherPipe()
{
SetGatherPipeCount(0);
}

void UpdateGatherPipe()
void GPFifoManager::UpdateGatherPipe()
{
auto& system = Core::System::GetInstance();
auto& system = m_system;
auto& memory = system.GetMemory();
auto& processor_interface = system.GetProcessorInterface();

Expand All @@ -93,7 +94,7 @@ void UpdateGatherPipe()
for (processed = 0; pipe_count >= GATHER_PIPE_SIZE; processed += GATHER_PIPE_SIZE)
{
// copy the GatherPipe
memcpy(cur_mem, s_gather_pipe + processed, GATHER_PIPE_SIZE);
memcpy(cur_mem, m_gather_pipe + processed, GATHER_PIPE_SIZE);
pipe_count -= GATHER_PIPE_SIZE;

// increase the CPUWritePointer
Expand All @@ -112,19 +113,19 @@ void UpdateGatherPipe()
}

// move back the spill bytes
memmove(s_gather_pipe, s_gather_pipe + processed, pipe_count);
memmove(m_gather_pipe, m_gather_pipe + processed, pipe_count);
SetGatherPipeCount(pipe_count);
}

void FastCheckGatherPipe()
void GPFifoManager::FastCheckGatherPipe()
{
if (GetGatherPipeCount() >= GATHER_PIPE_SIZE)
{
UpdateGatherPipe();
}
}

void CheckGatherPipe()
void GPFifoManager::CheckGatherPipe()
{
if (GetGatherPipeCount() >= GATHER_PIPE_SIZE)
{
Expand All @@ -135,55 +136,64 @@ void CheckGatherPipe()
}
}

void Write8(const u8 value)
void GPFifoManager::Write8(const u8 value)
{
FastWrite8(value);
CheckGatherPipe();
}

void Write16(const u16 value)
void GPFifoManager::Write16(const u16 value)
{
FastWrite16(value);
CheckGatherPipe();
}

void Write32(const u32 value)
void GPFifoManager::Write32(const u32 value)
{
FastWrite32(value);
CheckGatherPipe();
}

void Write64(const u64 value)
void GPFifoManager::Write64(const u64 value)
{
FastWrite64(value);
CheckGatherPipe();
}

void FastWrite8(const u8 value)
void GPFifoManager::FastWrite8(const u8 value)
{
*PowerPC::ppcState.gather_pipe_ptr = value;
PowerPC::ppcState.gather_pipe_ptr += sizeof(u8);
}

void FastWrite16(u16 value)
void GPFifoManager::FastWrite16(u16 value)
{
value = Common::swap16(value);
std::memcpy(PowerPC::ppcState.gather_pipe_ptr, &value, sizeof(u16));
PowerPC::ppcState.gather_pipe_ptr += sizeof(u16);
}

void FastWrite32(u32 value)
void GPFifoManager::FastWrite32(u32 value)
{
value = Common::swap32(value);
std::memcpy(PowerPC::ppcState.gather_pipe_ptr, &value, sizeof(u32));
PowerPC::ppcState.gather_pipe_ptr += sizeof(u32);
}

void FastWrite64(u64 value)
void GPFifoManager::FastWrite64(u64 value)
{
value = Common::swap64(value);
std::memcpy(PowerPC::ppcState.gather_pipe_ptr, &value, sizeof(u64));
PowerPC::ppcState.gather_pipe_ptr += sizeof(u64);
}

void UpdateGatherPipe(GPFifoManager& gpfifo)
{
gpfifo.UpdateGatherPipe();
}

void FastCheckGatherPipe(GPFifoManager& gpfifo)
{
gpfifo.FastCheckGatherPipe();
}
} // namespace GPFifo
74 changes: 49 additions & 25 deletions Source/Core/Core/HW/GPFifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

class PointerWrap;

namespace Core
{
class System;
}

namespace GPFifo
{
// This address is configurable in the WPAR SPR, but all games put it at this address
Expand All @@ -16,29 +21,48 @@ constexpr u32 GATHER_PIPE_PHYSICAL_ADDRESS = 0x0C008000;
constexpr u32 GATHER_PIPE_SIZE = 32;
constexpr u32 GATHER_PIPE_EXTRA_SIZE = GATHER_PIPE_SIZE * 16;

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

// ResetGatherPipe
void ResetGatherPipe();
void UpdateGatherPipe();
void CheckGatherPipe();
void FastCheckGatherPipe();

bool IsBNE();

// Write
void Write8(u8 value);
void Write16(u16 value);
void Write32(u32 value);
void Write64(u64 value);

// These expect pre-byteswapped values
// Also there's an upper limit of about 512 per batch
// Most likely these should be inlined into JIT instead
void FastWrite8(u8 value);
void FastWrite16(u16 value);
void FastWrite32(u32 value);
void FastWrite64(u64 value);
class GPFifoManager final
{
public:
explicit GPFifoManager(Core::System& system);

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

// ResetGatherPipe
void ResetGatherPipe();
void UpdateGatherPipe();
void CheckGatherPipe();
void FastCheckGatherPipe();

bool IsBNE() const;

// Write
void Write8(u8 value);
void Write16(u16 value);
void Write32(u32 value);
void Write64(u64 value);

// These expect pre-byteswapped values
// Also there's an upper limit of about 512 per batch
// Most likely these should be inlined into JIT instead
void FastWrite8(u8 value);
void FastWrite16(u16 value);
void FastWrite32(u32 value);
void FastWrite64(u64 value);

private:
size_t GetGatherPipeCount();
void SetGatherPipeCount(size_t size);

// More room for the fastmodes
alignas(GATHER_PIPE_SIZE) u8 m_gather_pipe[GATHER_PIPE_EXTRA_SIZE];

Core::System& m_system;
};

// For use from the JIT.
void UpdateGatherPipe(GPFifoManager& gpfifo);
void FastCheckGatherPipe(GPFifoManager& gpfifo);
} // namespace GPFifo
4 changes: 2 additions & 2 deletions Source/Core/Core/HW/HW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void Init(const Sram* override_sram)
MemoryInterface::Init();
DSP::Init(Config::Get(Config::MAIN_DSP_HLE));
DVDInterface::Init();
GPFifo::Init();
system.GetGPFifo().Init();
CPU::Init(Config::Get(Config::MAIN_CPU_CORE));
SystemTimers::Init();

Expand Down Expand Up @@ -103,7 +103,7 @@ void DoState(PointerWrap& p)
p.DoMarker("DSP");
DVDInterface::DoState(p);
p.DoMarker("DVDInterface");
GPFifo::DoState(p);
system.GetGPFifo().DoState(p);
p.DoMarker("GPFifo");
ExpansionInterface::DoState(p);
p.DoMarker("ExpansionInterface");
Expand Down
Loading

0 comments on commit 21c29ba

Please sign in to comment.