mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-05-04 15:58:04 +03:00
156 lines
3.5 KiB
C++
156 lines
3.5 KiB
C++
// Copyright 2008 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <cstring>
|
|
|
|
#include "Common/ChunkFile.h"
|
|
#include "Common/CommonFuncs.h"
|
|
#include "Common/CommonTypes.h"
|
|
#include "Core/HW/GPFifo.h"
|
|
#include "Core/HW/Memmap.h"
|
|
#include "Core/HW/ProcessorInterface.h"
|
|
#include "Core/PowerPC/JitInterface.h"
|
|
#include "VideoCommon/CommandProcessor.h"
|
|
|
|
namespace GPFifo
|
|
{
|
|
// 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
|
|
//
|
|
// Other optimizations to think about:
|
|
// - If the GP is NOT linked to the FIFO, just blast to memory byte by word
|
|
// - If the GP IS linked to the FIFO, use a fast wrapping buffer and skip writing to memory
|
|
//
|
|
// 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(32) u8 m_gatherPipe[GATHER_PIPE_SIZE * 16];
|
|
|
|
// pipe counter
|
|
u32 m_gatherPipeCount = 0;
|
|
|
|
void DoState(PointerWrap& p)
|
|
{
|
|
p.Do(m_gatherPipe);
|
|
p.Do(m_gatherPipeCount);
|
|
}
|
|
|
|
void Init()
|
|
{
|
|
ResetGatherPipe();
|
|
memset(m_gatherPipe, 0, sizeof(m_gatherPipe));
|
|
}
|
|
|
|
bool IsEmpty()
|
|
{
|
|
return m_gatherPipeCount == 0;
|
|
}
|
|
|
|
void ResetGatherPipe()
|
|
{
|
|
m_gatherPipeCount = 0;
|
|
}
|
|
|
|
static void UpdateGatherPipe()
|
|
{
|
|
u32 cnt;
|
|
u8* curMem = Memory::GetPointer(ProcessorInterface::Fifo_CPUWritePointer);
|
|
for (cnt = 0; m_gatherPipeCount >= GATHER_PIPE_SIZE; cnt += GATHER_PIPE_SIZE)
|
|
{
|
|
// copy the GatherPipe
|
|
memcpy(curMem, m_gatherPipe + cnt, GATHER_PIPE_SIZE);
|
|
m_gatherPipeCount -= GATHER_PIPE_SIZE;
|
|
|
|
// increase the CPUWritePointer
|
|
if (ProcessorInterface::Fifo_CPUWritePointer == ProcessorInterface::Fifo_CPUEnd)
|
|
{
|
|
ProcessorInterface::Fifo_CPUWritePointer = ProcessorInterface::Fifo_CPUBase;
|
|
curMem = Memory::GetPointer(ProcessorInterface::Fifo_CPUWritePointer);
|
|
}
|
|
else
|
|
{
|
|
curMem += GATHER_PIPE_SIZE;
|
|
ProcessorInterface::Fifo_CPUWritePointer += GATHER_PIPE_SIZE;
|
|
}
|
|
|
|
CommandProcessor::GatherPipeBursted();
|
|
}
|
|
|
|
// move back the spill bytes
|
|
memmove(m_gatherPipe, m_gatherPipe + cnt, m_gatherPipeCount);
|
|
}
|
|
|
|
void FastCheckGatherPipe()
|
|
{
|
|
if (m_gatherPipeCount >= GATHER_PIPE_SIZE)
|
|
{
|
|
UpdateGatherPipe();
|
|
}
|
|
}
|
|
|
|
void CheckGatherPipe()
|
|
{
|
|
if (m_gatherPipeCount >= GATHER_PIPE_SIZE)
|
|
{
|
|
UpdateGatherPipe();
|
|
|
|
// Profile where slow FIFO writes are occurring.
|
|
JitInterface::CompileExceptionCheck(JitInterface::ExceptionType::EXCEPTIONS_FIFO_WRITE);
|
|
}
|
|
}
|
|
|
|
void Write8(const u8 value)
|
|
{
|
|
FastWrite8(value);
|
|
CheckGatherPipe();
|
|
}
|
|
|
|
void Write16(const u16 value)
|
|
{
|
|
FastWrite16(value);
|
|
CheckGatherPipe();
|
|
}
|
|
|
|
void Write32(const u32 value)
|
|
{
|
|
FastWrite32(value);
|
|
CheckGatherPipe();
|
|
}
|
|
|
|
void Write64(const u64 value)
|
|
{
|
|
FastWrite64(value);
|
|
CheckGatherPipe();
|
|
}
|
|
|
|
void FastWrite8(const u8 value)
|
|
{
|
|
m_gatherPipe[m_gatherPipeCount] = value;
|
|
++m_gatherPipeCount;
|
|
}
|
|
|
|
void FastWrite16(u16 value)
|
|
{
|
|
value = Common::swap16(value);
|
|
std::memcpy(&m_gatherPipe[m_gatherPipeCount], &value, sizeof(u16));
|
|
m_gatherPipeCount += sizeof(u16);
|
|
}
|
|
|
|
void FastWrite32(u32 value)
|
|
{
|
|
value = Common::swap32(value);
|
|
std::memcpy(&m_gatherPipe[m_gatherPipeCount], &value, sizeof(u32));
|
|
m_gatherPipeCount += sizeof(u32);
|
|
}
|
|
|
|
void FastWrite64(u64 value)
|
|
{
|
|
value = Common::swap64(value);
|
|
std::memcpy(&m_gatherPipe[m_gatherPipeCount], &value, sizeof(u64));
|
|
m_gatherPipeCount += sizeof(u64);
|
|
}
|
|
|
|
} // end of namespace GPFifo
|