MTGS: Combine init/read FIFO and remove several MTGS waits

This commit is contained in:
Connor McLaughlin 2022-04-24 20:09:55 +10:00 committed by refractionpcsx2
parent 3b043250b6
commit 185ed3ce0b
9 changed files with 22 additions and 84 deletions

View File

@ -54,10 +54,7 @@ void __fastcall ReadFIFO_VIF1(mem128_t* out)
}
if (vif1Regs.stat.FQC > 0)
{
GetMTGS().WaitGS();
GetMTGS().SendPointerPacket(GS_RINGTYPE_INIT_READ_FIFO1, 0, out);
GetMTGS().WaitGS(false); // wait without reg sync
GSreadFIFO((u8*)out);
GetMTGS().InitAndReadFIFO(reinterpret_cast<u8*>(out), 1);
vif1.GSLastDownloadSize--;
GUNIT_LOG("ReadFIFO_VIF1");
if (vif1.GSLastDownloadSize <= 16)

View File

@ -248,17 +248,7 @@ void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value )
GUNIT_LOG("Busdir - EE->GS Upload");
}
//=========================================================================
// BUSDIR INSANITY !! MTGS FLUSH NEEDED
//
// Yup folks. BUSDIR is evil. The only safe way to handle it is to flush the whole MTGS
// and ensure complete MTGS and EEcore thread synchronization This is very slow, no doubt,
// but on the bright side BUSDIR is used quite rarely, indeed.
// Important: writeback to gsRegs area *prior* to flushing the MTGS. The flush will sync
// the GS and MTGS register states, and upload our screwy busdir register in the process. :)
gsWrite64_generic( mem, value );
GetMTGS().WaitGS();
return;
case GS_CSR:

View File

@ -294,8 +294,7 @@ enum MTGS_RingCommand
GS_RINGTYPE_CRC,
GS_RINGTYPE_GSPACKET,
GS_RINGTYPE_MTVU_GSPACKET,
GS_RINGTYPE_INIT_READ_FIFO1,
GS_RINGTYPE_INIT_READ_FIFO2,
GS_RINGTYPE_INIT_AND_READ_FIFO,
GS_RINGTYPE_ASYNC_CALL,
};
@ -384,6 +383,7 @@ public:
u8* GetDataPacketPtr() const;
void SetEvent();
void PostVsyncStart(bool registers_written);
void InitAndReadFIFO(u8* mem, u32 qwc);
bool IsGSOpened() const { return m_Opened; }

View File

@ -403,57 +403,12 @@ void GSwriteCSR(u32 csr)
}
}
void GSinitReadFIFO(u8* mem)
void GSInitAndReadFIFO(u8* mem, u32 size)
{
GL_PERF("Init Read FIFO1");
try
{
s_gs->InitReadFIFO(mem, 1);
}
catch (GSRecoverableError)
{
}
catch (const std::bad_alloc&)
{
fprintf(stderr, "GS: Memory allocation error\n");
}
}
void GSreadFIFO(u8* mem)
{
try
{
s_gs->ReadFIFO(mem, 1);
}
catch (GSRecoverableError)
{
}
catch (const std::bad_alloc&)
{
fprintf(stderr, "GS: Memory allocation error\n");
}
}
void GSinitReadFIFO2(u8* mem, u32 size)
{
GL_PERF("Init Read FIFO2");
GL_PERF("Init and read FIFO %u qwc", size);
try
{
s_gs->InitReadFIFO(mem, size);
}
catch (GSRecoverableError)
{
}
catch (const std::bad_alloc&)
{
fprintf(stderr, "GS: Memory allocation error\n");
}
}
void GSreadFIFO2(u8* mem, u32 size)
{
try
{
s_gs->ReadFIFO(mem, size);
}
catch (GSRecoverableError)

View File

@ -60,10 +60,7 @@ void GSreset();
void GSclose();
void GSgifSoftReset(u32 mask);
void GSwriteCSR(u32 csr);
void GSinitReadFIFO(u8* mem);
void GSreadFIFO(u8* mem);
void GSinitReadFIFO2(u8* mem, u32 size);
void GSreadFIFO2(u8* mem, u32 size);
void GSInitAndReadFIFO(u8* mem, u32 size);
void GSgifTransfer(const u8* mem, u32 size);
void GSgifTransfer1(u8* mem, u32 addr);
void GSgifTransfer2(u8* mem, u32 size);

View File

@ -276,10 +276,8 @@ void GSDumpReplayerCpuStep()
u32 size;
std::memcpy(&size, packet.data, sizeof(size));
std::unique_ptr<u8[]> arr(new u8[size]);
GetMTGS().WaitGS();
GetMTGS().SendPointerPacket(GS_RINGTYPE_INIT_READ_FIFO2, size, arr.get());
GetMTGS().WaitGS(false); // wait without reg sync
std::unique_ptr<u8[]> arr(new u8[size * 16]);
GetMTGS().InitAndReadFIFO(arr.get(), size);
}
break;

View File

@ -179,6 +179,15 @@ void SysMtgsThread::PostVsyncStart(bool registers_written)
m_sem_Vsync.WaitNoCancel();
}
void SysMtgsThread::InitAndReadFIFO(u8* mem, u32 qwc)
{
if (GSConfig.HWDisableReadbacks && GSConfig.UseHardwareRenderer())
return;
SendPointerPacket(GS_RINGTYPE_INIT_AND_READ_FIFO, qwc, mem);
WaitGS(false, false, false);
}
union PacketTagType
{
struct
@ -448,14 +457,9 @@ void SysMtgsThread::ExecuteTaskInThread()
GSsetGameCRC(tag.data[0], 0);
break;
case GS_RINGTYPE_INIT_READ_FIFO1:
MTGS_LOG("(MTGS Packet Read) ringtype=Fifo1");
GSinitReadFIFO((u8*)tag.pointer);
break;
case GS_RINGTYPE_INIT_READ_FIFO2:
case GS_RINGTYPE_INIT_AND_READ_FIFO:
MTGS_LOG("(MTGS Packet Read) ringtype=Fifo2, size=%d", tag.data[0]);
GSinitReadFIFO2((u8*)tag.pointer, tag.data[0]);
GSInitAndReadFIFO((u8*)tag.pointer, tag.data[0]);
break;
#ifdef PCSX2_DEVBUILD

View File

@ -69,10 +69,7 @@ void vif1TransferToMemory()
pxAssert(p3.isDone() || !p3.gifTag.isValid);
}
GetMTGS().WaitGS();
GetMTGS().SendPointerPacket(GS_RINGTYPE_INIT_READ_FIFO2, size, pMem);
GetMTGS().WaitGS(false); // wait without reg sync
GSreadFIFO2((u8*)pMem, size);
GetMTGS().InitAndReadFIFO(reinterpret_cast<u8*>(pMem), size);
// pMem += size;
//Some games such as Alex Ferguson's Player Manager 2001 reads less than GSLastDownloadSize by VIF then reads the remainder by FIFO

View File

@ -775,8 +775,8 @@ void Dialogs::GSDumpDialog::ProcessDumpEvent(const GSDumpFile::GSData& event, u8
}
case GSType::ReadFIFO2:
{
std::unique_ptr<char[]> arr(new char[*((int*)event.data)]);
GSreadFIFO2((u8*)arr.get(), *((int*)event.data));
std::unique_ptr<u8[]> arr(new u8[*((int*)event.data) * 16]);
GetMTGS().InitAndReadFIFO(arr.get(), *((int*)event.data));
break;
}
case GSType::Registers: