mirror of https://github.com/PCSX2/pcsx2.git
More MTGS optimizations.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2250 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
d95b317082
commit
ae42481315
|
@ -100,7 +100,7 @@ public:
|
||||||
volatile u32 m_SignalRingEnable;
|
volatile u32 m_SignalRingEnable;
|
||||||
volatile s32 m_SignalRingPosition;
|
volatile s32 m_SignalRingPosition;
|
||||||
|
|
||||||
int m_alterFrameFlush;
|
int m_QueuedFrameCount;
|
||||||
u32 m_RingWrapSpot;
|
u32 m_RingWrapSpot;
|
||||||
|
|
||||||
Mutex m_lock_RingBufferBusy;
|
Mutex m_lock_RingBufferBusy;
|
||||||
|
|
|
@ -111,7 +111,7 @@ void SysMtgsThread::OnStart()
|
||||||
m_packet_size = 0;
|
m_packet_size = 0;
|
||||||
m_packet_ringpos = 0;
|
m_packet_ringpos = 0;
|
||||||
|
|
||||||
m_alterFrameFlush = 0;
|
m_QueuedFrameCount = 0;
|
||||||
m_SignalRingEnable = 0;
|
m_SignalRingEnable = 0;
|
||||||
m_SignalRingPosition= 0;
|
m_SignalRingPosition= 0;
|
||||||
m_RingWrapSpot = 0;
|
m_RingWrapSpot = 0;
|
||||||
|
@ -152,15 +152,20 @@ void SysMtgsThread::PostVsyncEnd( bool updategs )
|
||||||
{
|
{
|
||||||
SendSimplePacket( GS_RINGTYPE_VSYNC, (*(u32*)(PS2MEM_GS+0x1000)&0x2000), updategs, 0 );
|
SendSimplePacket( GS_RINGTYPE_VSYNC, (*(u32*)(PS2MEM_GS+0x1000)&0x2000), updategs, 0 );
|
||||||
|
|
||||||
// Alter-frame flush! Restarts the ringbuffer (wraps) on every other frame. This is a
|
// Alter-frame flushing! Restarts the ringbuffer (wraps) on every other frame. This is a
|
||||||
// mandatory feature that prevents the MTGS from queuing more than 2 frames at any time.
|
// mandatory feature that prevents the MTGS from queuing more than 2 frames at any time.
|
||||||
// (queued frames cause input lag and desynced audio -- bad!).
|
// (queued frames cause input lag and desynced audio -- bad!). Ring restarts work for this
|
||||||
|
// because they act as sync points where the EE must stall to wait for the GS to catch-up,
|
||||||
|
// and they also allow us to reuse the front of the ringbuffer more often, which should improve
|
||||||
|
// L2 cache performance.
|
||||||
|
|
||||||
m_alterFrameFlush ^= 1;
|
if( m_QueuedFrameCount > 0 )
|
||||||
if( !m_alterFrameFlush )
|
|
||||||
RestartRingbuffer();
|
RestartRingbuffer();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
m_QueuedFrameCount++;
|
||||||
SetEvent();
|
SetEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PacketTagType
|
struct PacketTagType
|
||||||
|
@ -445,7 +450,7 @@ void SysMtgsThread::ExecuteTaskInThread()
|
||||||
m_sem_OnRingReset.Post();
|
m_sem_OnRingReset.Post();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Console.Warning( "(MTGS Thread) Nothing to do!!" );
|
//Console.Warning( "(MTGS Thread) Nothing to do! ringpos=0x%06x", m_RingPos );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,7 +552,7 @@ void SysMtgsThread::SendDataPacket()
|
||||||
{
|
{
|
||||||
WaitGS();
|
WaitGS();
|
||||||
}
|
}
|
||||||
else if( m_RingBufferIsBusy )
|
else if( !m_RingBufferIsBusy )
|
||||||
{
|
{
|
||||||
m_CopyDataTally += m_packet_size;
|
m_CopyDataTally += m_packet_size;
|
||||||
if( m_CopyDataTally > 0x2000 ) SetEvent();
|
if( m_CopyDataTally > 0x2000 ) SetEvent();
|
||||||
|
@ -672,14 +677,14 @@ int SysMtgsThread::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size
|
||||||
pxAssertDev( m_SignalRingEnable == 0, "MTGS Thread Synchronization Error" );
|
pxAssertDev( m_SignalRingEnable == 0, "MTGS Thread Synchronization Error" );
|
||||||
m_SignalRingPosition = somedone;
|
m_SignalRingPosition = somedone;
|
||||||
|
|
||||||
//Console.WriteLn( Color_Blue, "(MTGS Sync) EEcore Sleep!\twrapspot=0x%06x, ringpos=0x%06x, writepos=0x%06x, signalpos=0x%06x", m_RingWrapSpot, readpos, writepos, m_SignalRingPosition );
|
//Console.WriteLn( Color_Blue, "(EEcore Sleep) GenStall \tringpos=0x%06x, writepos=0x%06x, wrapspot=0x%06x, signalpos=0x%06x", readpos, writepos, m_RingWrapSpot, m_SignalRingPosition );
|
||||||
|
|
||||||
do {
|
do {
|
||||||
AtomicExchange( m_SignalRingEnable, 1 );
|
AtomicExchange( m_SignalRingEnable, 1 );
|
||||||
SetEvent();
|
SetEvent();
|
||||||
m_sem_OnRingReset.WaitWithoutYield();
|
m_sem_OnRingReset.WaitWithoutYield();
|
||||||
readpos = volatize(m_RingPos);
|
readpos = volatize(m_RingPos);
|
||||||
//Console.WriteLn( Color_Blue, "(MTGS Sync) EEcore Post-sleep Report!\tringpos=0x%06x", readpos );
|
//Console.WriteLn( Color_Blue, "(EEcore Awake) Report!\tringpos=0x%06x", readpos );
|
||||||
} while( (writepos < readpos) && (writepos+size >= readpos) );
|
} while( (writepos < readpos) && (writepos+size >= readpos) );
|
||||||
|
|
||||||
pxAssertDev( m_SignalRingPosition <= 0, "MTGS Thread Synchronization Error" );
|
pxAssertDev( m_SignalRingPosition <= 0, "MTGS Thread Synchronization Error" );
|
||||||
|
@ -705,7 +710,6 @@ int SysMtgsThread::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size
|
||||||
//Console.WriteLn( "MTGS > Ringbuffer Got Filled!");
|
//Console.WriteLn( "MTGS > Ringbuffer Got Filled!");
|
||||||
RestartRingbuffer( size );
|
RestartRingbuffer( size );
|
||||||
writepos = m_WritePos;
|
writepos = m_WritePos;
|
||||||
m_alterFrameFlush = 0;
|
|
||||||
}
|
}
|
||||||
else // always true - if( writepos + size == MTGS_RINGBUFFEREND )
|
else // always true - if( writepos + size == MTGS_RINGBUFFEREND )
|
||||||
{
|
{
|
||||||
|
@ -718,7 +722,7 @@ int SysMtgsThread::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size
|
||||||
//Console.WriteLn( "MTGS > Perfect Fit!\tringpos=0x%06x, writepos=0x%06x", readpos, writepos );
|
//Console.WriteLn( "MTGS > Perfect Fit!\tringpos=0x%06x, writepos=0x%06x", readpos, writepos );
|
||||||
if( readpos > writepos || readpos == 0 )
|
if( readpos > writepos || readpos == 0 )
|
||||||
{
|
{
|
||||||
uint totalAccum = (RingBufferSize - readpos) + writepos;
|
uint totalAccum = (readpos == 0) ? RingBufferSize : ((m_RingWrapSpot - readpos) + writepos);
|
||||||
uint somedone = totalAccum / 4;
|
uint somedone = totalAccum / 4;
|
||||||
if( somedone < size+1 ) somedone = size + 1;
|
if( somedone < size+1 ) somedone = size + 1;
|
||||||
|
|
||||||
|
@ -752,7 +756,7 @@ int SysMtgsThread::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_alterFrameFlush = 0;
|
m_QueuedFrameCount = 0;
|
||||||
m_RingWrapSpot = RingBufferSize;
|
m_RingWrapSpot = RingBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,19 +795,25 @@ void SysMtgsThread::RestartRingbuffer( uint packsize )
|
||||||
// be the act of skipping PAST readpos). Stall until it loops around to the
|
// be the act of skipping PAST readpos). Stall until it loops around to the
|
||||||
// beginning of the buffer, and past the size of our packet allocation.
|
// beginning of the buffer, and past the size of our packet allocation.
|
||||||
|
|
||||||
uint somedone = (m_RingWrapSpot - readpos) + packsize + 1;
|
uint somedone;
|
||||||
|
|
||||||
|
if( readpos > m_WritePos )
|
||||||
|
somedone = (m_RingWrapSpot - readpos) + packsize + 1;
|
||||||
|
else
|
||||||
|
somedone = (packsize + 1) - readpos;
|
||||||
|
|
||||||
if( somedone > 0x80 )
|
if( somedone > 0x80 )
|
||||||
{
|
{
|
||||||
m_SignalRingPosition = somedone;
|
m_SignalRingPosition = somedone;
|
||||||
//Console.WriteLn( Color_Blue, "(MTGS Sync) EEcore Restart Sleep!\t\twrapspot=0x%06x, ringpos=0x%06x, writepos=0x%06x, signalpos=0x%06x", m_RingWrapSpot, readpos, m_WritePos, m_SignalRingPosition );
|
//Console.WriteLn( Color_Blue, "(EEcore Sleep) Restart!\tringpos=0x%06x, writepos=0x%06x, wrapspot=0x%06x, signalpos=0x%06x",
|
||||||
|
// readpos, m_WritePos, m_RingWrapSpot, m_SignalRingPosition );
|
||||||
|
|
||||||
do {
|
do {
|
||||||
AtomicExchange( m_SignalRingEnable, 1 );
|
AtomicExchange( m_SignalRingEnable, 1 );
|
||||||
SetEvent();
|
SetEvent();
|
||||||
m_sem_OnRingReset.WaitWithoutYield();
|
m_sem_OnRingReset.WaitWithoutYield();
|
||||||
readpos = volatize(m_RingPos);
|
readpos = volatize(m_RingPos);
|
||||||
//Console.WriteLn( Color_Blue, "(MTGS Sync) EEcore Restart Post-sleep Report!\tringpos=0x%06x", readpos );
|
//Console.WriteLn( Color_Blue, "(EEcore Awake) Report!\tringpos=0x%06x", readpos );
|
||||||
} while( (readpos > m_WritePos) || (readpos <= thefuture) );
|
} while( (readpos > m_WritePos) || (readpos <= thefuture) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -822,6 +832,7 @@ void SysMtgsThread::RestartRingbuffer( uint packsize )
|
||||||
|
|
||||||
m_RingWrapSpot = m_WritePos;
|
m_RingWrapSpot = m_WritePos;
|
||||||
m_WritePos = 0;
|
m_WritePos = 0;
|
||||||
|
m_QueuedFrameCount = 0;
|
||||||
|
|
||||||
if( EmuConfig.Video.SynchronousMTGS )
|
if( EmuConfig.Video.SynchronousMTGS )
|
||||||
WaitGS();
|
WaitGS();
|
||||||
|
@ -841,7 +852,7 @@ __forceinline uint SysMtgsThread::_PrepForSimplePacket()
|
||||||
future_writepos &= RingBufferMask;
|
future_writepos &= RingBufferMask;
|
||||||
if( future_writepos == 0 )
|
if( future_writepos == 0 )
|
||||||
{
|
{
|
||||||
m_alterFrameFlush = 0;
|
m_QueuedFrameCount = 0;
|
||||||
m_RingWrapSpot = RingBufferSize;
|
m_RingWrapSpot = RingBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue