(minor optimization) Let's not even use the GS plugin's Path1 or Path3 parsers anymore. All GIFtags can be sent safely through the GS's hack-free Path2 instead.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3310 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-06-26 07:48:16 +00:00
parent e8f5468491
commit 04e89783cd
4 changed files with 72 additions and 106 deletions

View File

@ -195,7 +195,7 @@ void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value)
nloop0_packet[2] = psHu32(GIF_FIFO + 8); nloop0_packet[2] = psHu32(GIF_FIFO + 8);
nloop0_packet[3] = psHu32(GIF_FIFO + 12); nloop0_packet[3] = psHu32(GIF_FIFO + 12);
Registers::Freeze(); Registers::Freeze();
GetMTGS().PrepDataPacket(GIF_PATH_3, nloop0_packet, 1); GetMTGS().PrepDataPacket(GIF_PATH_3, (u8*)nloop0_packet, 1);
u64* data = (u64*)GetMTGS().GetDataPacketPtr(); u64* data = (u64*)GetMTGS().GetDataPacketPtr();
data[0] = value[0]; data[0] = value[0];
data[1] = value[1]; data[1] = value[1];

View File

@ -245,9 +245,7 @@ extern GS_RegionMode gsRegionMode;
enum MTGS_RingCommand enum MTGS_RingCommand
{ {
GS_RINGTYPE_P1 GS_RINGTYPE_PATH // GIFpaths 1, 2, and 3
, GS_RINGTYPE_P2
, GS_RINGTYPE_P3
, GS_RINGTYPE_RESTART , GS_RINGTYPE_RESTART
, GS_RINGTYPE_VSYNC , GS_RINGTYPE_VSYNC
, GS_RINGTYPE_FRAMESKIP , GS_RINGTYPE_FRAMESKIP
@ -319,7 +317,6 @@ public:
int PrepDataPacket( MTGS_RingCommand cmd, u32 size ); int PrepDataPacket( MTGS_RingCommand cmd, u32 size );
int PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size ); int PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size );
int PrepDataPacket( GIF_PATH pathidx, const u32* srcdata, u32 size );
void SendDataPacket(); void SendDataPacket();
void SendGameCRC( u32 crc ); void SendGameCRC( u32 crc );
void WaitForOpen(); void WaitForOpen();

View File

@ -143,7 +143,7 @@ __forceinline void gsInterrupt()
static u32 WRITERING_DMA(u32 *pMem, u32 qwc) static u32 WRITERING_DMA(u32 *pMem, u32 qwc)
{ {
int size = GetMTGS().PrepDataPacket(GIF_PATH_3, pMem, qwc); int size = GetMTGS().PrepDataPacket(GIF_PATH_3, (u8*)pMem, qwc);
u8* pgsmem = GetMTGS().GetDataPacketPtr(); u8* pgsmem = GetMTGS().GetDataPacketPtr();
memcpy_aligned(pgsmem, pMem, size<<4); memcpy_aligned(pgsmem, pMem, size<<4);

View File

@ -326,126 +326,100 @@ void SysMtgsThread::ExecuteTaskInThread()
switch( tag.command ) switch( tag.command )
{ {
case GS_RINGTYPE_P1: case GS_RINGTYPE_PATH:
{
const int qsize = tag.data[0];
const u128* data = &RingBuffer[m_RingPos+1];
MTGS_LOG( "(MTGS Packet Read) ringtype=P1, qwc=%u", qsize );
// make sure that tag>>16 is the MAX size readable
GSgifTransfer1((u32*)(data - 0x400 + qsize), 0x4000-qsize*16);
//GSgifTransfer1((u32*)data, qsize);
ringposinc += qsize;
}
break;
case GS_RINGTYPE_P2:
{ {
const int qsize = tag.data[0]; const int qsize = tag.data[0];
const u128* data = &RingBuffer[m_RingPos+1]; const u128* data = &RingBuffer[m_RingPos+1];
MTGS_LOG( "(MTGS Packet Read) ringtype=P2, qwc=%u", qsize ); MTGS_LOG( "(MTGS Packet Read) ringtype=P2, qwc=%u", qsize );
// All GIFpath data is sent through Path2, which is the hack-free giftag
// parser on the GS plugin side of the world. PCSX2 now handles *all* the
// hacks, wrap-arounds, and (soon!) partial transfers during its own internal
// GIFtag parse, so the hack-free path on the GS is the preferred one for
// all packets. -air
GSgifTransfer2((u32*)data, qsize); GSgifTransfer2((u32*)data, qsize);
ringposinc += qsize; ringposinc += qsize;
} }
break; break;
case GS_RINGTYPE_P3: case GS_RINGTYPE_RESTART:
//MTGS_LOG( "(MTGS Packet Read) ringtype=Restart" );
m_RingPos = 0;
continue;
case GS_RINGTYPE_VSYNC:
{ {
const int qsize = tag.data[0]; const int qsize = tag.data[0];
const u128* data = &RingBuffer[m_RingPos+1];
MTGS_LOG( "(MTGS Packet Read) ringtype=P3, qwc=%u", qsize );
GSgifTransfer3((u32*)data, qsize);
ringposinc += qsize; ringposinc += qsize;
MTGS_LOG( "(MTGS Packet Read) ringtype=Vsync, field=%u, skip=%s", tag.data[0], tag.data[1] ? "true" : "false" );
// Mail in the important GS registers.
RingCmdPacket_Vsync& local((RingCmdPacket_Vsync&)RingBuffer[m_RingPos+1]);
memcpy_fast( RingBuffer.Regs, local.regset1, sizeof(local.regset1));
((u32&)RingBuffer.Regs[0x1000]) = local.csr;
((u32&)RingBuffer.Regs[0x1010]) = local.imr;
((GSRegSIGBLID&)RingBuffer.Regs[0x1080]) = local.siglblid;
GSvsync(!(local.csr & 0x2000));
gsFrameSkip();
// if we're not using GSOpen2, then the GS window is on this thread (MTGS thread),
// so we need to call PADupdate from here.
if( (GSopen2 == NULL) && (PADupdate != NULL) )
PADupdate(0);
StateCheckInThread();
} }
break; break;
default: case GS_RINGTYPE_FRAMESKIP:
MTGS_LOG( "(MTGS Packet Read) ringtype=Frameskip" );
_gs_ResetFrameskip();
break;
case GS_RINGTYPE_FREEZE:
{ {
switch( tag.command ) MTGS_FreezeData* data = (MTGS_FreezeData*)(*(uptr*)&tag.data[1]);
{ int mode = tag.data[0];
case GS_RINGTYPE_RESTART: data->retval = GetCorePlugins().DoFreeze( PluginId_GS, mode, data->fdata );
//MTGS_LOG( "(MTGS Packet Read) ringtype=Restart" ); }
m_RingPos = 0; break;
continue;
case GS_RINGTYPE_VSYNC: case GS_RINGTYPE_RESET:
{ MTGS_LOG( "(MTGS Packet Read) ringtype=Reset" );
const int qsize = tag.data[0]; if( GSreset != NULL ) GSreset();
ringposinc += qsize; break;
MTGS_LOG( "(MTGS Packet Read) ringtype=Vsync, field=%u, skip=%s", tag.data[0], tag.data[1] ? "true" : "false" ); case GS_RINGTYPE_SOFTRESET:
{
// Mail in the important GS registers. int mask = tag.data[0];
RingCmdPacket_Vsync& local((RingCmdPacket_Vsync&)RingBuffer[m_RingPos+1]); MTGS_LOG( "(MTGS Packet Read) ringtype=SoftReset" );
GSgifSoftReset( mask );
memcpy_fast( RingBuffer.Regs, local.regset1, sizeof(local.regset1)); }
((u32&)RingBuffer.Regs[0x1000]) = local.csr; break;
((u32&)RingBuffer.Regs[0x1010]) = local.imr;
((GSRegSIGBLID&)RingBuffer.Regs[0x1080]) = local.siglblid;
GSvsync(!(local.csr & 0x2000));
gsFrameSkip();
// if we're not using GSOpen2, then the GS window is on this thread (MTGS thread), case GS_RINGTYPE_MODECHANGE:
// so we need to call PADupdate from here. // [TODO] some frameskip sync logic might be needed here!
if( (GSopen2 == NULL) && (PADupdate != NULL) ) break;
PADupdate(0);
StateCheckInThread(); case GS_RINGTYPE_CRC:
} GSsetGameCRC( tag.data[0], 0 );
break; break;
case GS_RINGTYPE_FRAMESKIP:
MTGS_LOG( "(MTGS Packet Read) ringtype=Frameskip" );
_gs_ResetFrameskip();
break;
case GS_RINGTYPE_FREEZE:
{
MTGS_FreezeData* data = (MTGS_FreezeData*)(*(uptr*)&tag.data[1]);
int mode = tag.data[0];
data->retval = GetCorePlugins().DoFreeze( PluginId_GS, mode, data->fdata );
}
break;
case GS_RINGTYPE_RESET:
MTGS_LOG( "(MTGS Packet Read) ringtype=Reset" );
if( GSreset != NULL ) GSreset();
break;
case GS_RINGTYPE_SOFTRESET:
{
int mask = tag.data[0];
MTGS_LOG( "(MTGS Packet Read) ringtype=SoftReset" );
GSgifSoftReset( mask );
}
break;
case GS_RINGTYPE_MODECHANGE:
// [TODO] some frameskip sync logic might be needed here!
break;
case GS_RINGTYPE_CRC:
GSsetGameCRC( tag.data[0], 0 );
break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
default: default:
Console.Error("GSThreadProc, bad packet (%x) at m_RingPos: %x, m_WritePos: %x", tag.command, m_RingPos, m_WritePos); Console.Error("GSThreadProc, bad packet (%x) at m_RingPos: %x, m_WritePos: %x", tag.command, m_RingPos, m_WritePos);
pxFail( "Bad packet encountered in the MTGS Ringbuffer." ); pxFail( "Bad packet encountered in the MTGS Ringbuffer." );
m_RingPos = m_WritePos; m_RingPos = m_WritePos;
continue; continue;
#else #else
// Optimized performance in non-Dev builds. // Optimized performance in non-Dev builds.
jNO_DEFAULT; jNO_DEFAULT;
#endif #endif
}
}
} }
uint newringpos = m_RingPos + ringposinc; uint newringpos = m_RingPos + ringposinc;
@ -594,11 +568,6 @@ void SysMtgsThread::SendDataPacket()
//m_PacketLocker.Release(); //m_PacketLocker.Release();
} }
int SysMtgsThread::PrepDataPacket( GIF_PATH pathidx, const u32* srcdata, u32 size )
{
return PrepDataPacket( pathidx, (u8*)srcdata, size );
}
int SysMtgsThread::PrepDataPacket( MTGS_RingCommand cmd, u32 size ) int SysMtgsThread::PrepDataPacket( MTGS_RingCommand cmd, u32 size )
{ {
// Note on volatiles: m_WritePos is not modified by the GS thread, so there's no need // Note on volatiles: m_WritePos is not modified by the GS thread, so there's no need
@ -756,7 +725,7 @@ int SysMtgsThread::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size
{ {
//m_PacketLocker.Acquire(); //m_PacketLocker.Acquire();
return PrepDataPacket( (MTGS_RingCommand)pathidx, GIFPath_ParseTag(pathidx, srcdata, size) ); return PrepDataPacket( GS_RINGTYPE_PATH, GIFPath_ParseTag(pathidx, srcdata, size) );
} }
void SysMtgsThread::RestartRingbuffer( uint packsize ) void SysMtgsThread::RestartRingbuffer( uint packsize )