ReorderingMTGS: Some cleanups and minor fixes to thread benching.

git-svn-id: http://pcsx2.googlecode.com/svn/branches/ReorderingMTGS@3478 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-07-13 16:34:27 +00:00
parent d1e0922417
commit 168a60ad13
3 changed files with 33 additions and 68 deletions

View File

@ -256,9 +256,9 @@ __forceinline void memcpy_amd_qwc(void *dest, const void *src, size_t qwc)
__asm
{
mov ecx, [dest]
mov edx, [src]
mov eax, [qwc] ; keep a copy of count
mov ecx, dest
mov edx, src
mov eax, qwc ; keep a copy of count
shr eax, 1
jz $memcpy_qwc_1 ; only one 16 byte block to copy?
@ -306,7 +306,7 @@ $memcpy_qwc_loop1:
jnz $memcpy_qwc_loop1 ; last 64-byte block?
$memcpy_qwc_1:
test [qwc],1
test qwc,1
jz $memcpy_qwc_final
movq mm0,[edx]
movq mm1,[edx+8]

View File

@ -258,7 +258,6 @@ enum MTGS_RingCommand
GS_RINGTYPE_P1
, GS_RINGTYPE_P2
, GS_RINGTYPE_P3
, GS_RINGTYPE_RESTART
, GS_RINGTYPE_VSYNC
, GS_RINGTYPE_FRAMESKIP
, GS_RINGTYPE_FREEZE
@ -291,10 +290,12 @@ public:
volatile u32 m_SignalRingEnable;
volatile s32 m_SignalRingPosition;
int m_QueuedFrameCount;
volatile s32 m_QueuedFrameCount;
volatile u32 m_VsyncSignalListener;
Mutex m_lock_RingBufferBusy;
Mutex m_mtx_RingBufferBusy;
Semaphore m_sem_OnRingReset;
Semaphore m_sem_Vsync;
// used to keep multiple threads from sending packets to the ringbuffer concurrently.
// (currently not used or implemented -- is a planned feature for a future threaded VU1)

View File

@ -77,6 +77,7 @@ void SysMtgsThread::OnStart()
m_packet_ringpos = 0;
m_QueuedFrameCount = 0;
m_VsyncSignalListener = false;
m_SignalRingEnable = 0;
m_SignalRingPosition= 0;
@ -106,6 +107,7 @@ void SysMtgsThread::ResetGS()
m_RingPos = m_WritePos;
m_QueuedFrameCount = 0;
m_VsyncSignalListener = false;
MTGS_LOG( "MTGS: Sending Reset..." );
SendSimplePacket( GS_RINGTYPE_RESET, 0, 0, 0 );
@ -142,33 +144,19 @@ void SysMtgsThread::PostVsyncEnd()
SendDataPacket();
// Vsyncs should always start the GS thread, regardless of how little has actually be queued.
if (m_CopyDataTally != 0) SetEvent();
// If the MTGS is allowed to queue a lot of frames in advance, it creates input lag.
// Use the Queued FrameCount to stall the EE if another vsync is already queued in
// the ringbuffer.
// Use the Queued FrameCount to stall the EE if another vsync (or two) are already queued
// in the ringbuffer. The queue limit is disabled when FrameLimiting is disabled, since
// the queue can have perverse effects on framerate benchmarking.
if( AtomicIncrement(m_QueuedFrameCount) < EmuConfig.GS.VsyncQueueSize ) return;
if ((AtomicIncrement(m_QueuedFrameCount) < EmuConfig.GS.VsyncQueueSize) || !EmuConfig.GS.FrameLimitEnable) return;
uint readpos = volatize(m_RingPos);
uint freeroom;
if (m_WritePos < readpos)
freeroom = readpos - m_WritePos;
else
freeroom = RingBufferSize - (m_WritePos - readpos);
uint totalAccum = RingBufferSize - freeroom;
uint somedone = totalAccum / 4;
m_SignalRingPosition = totalAccum;
//Console.WriteLn( Color_Blue, "(EEcore Sleep) Vsync\tringpos=0x%06x, writepos=0x%06x, signalpos=0x%06x", readpos, m_WritePos, m_SignalRingPosition );
AtomicExchange( m_SignalRingEnable, 1 );
SetEvent();
m_sem_OnRingReset.WaitWithoutYield();
readpos = volatize(m_RingPos);
pxAssertDev( m_SignalRingPosition <= 0, "MTGS Thread Synchronization Error" );
m_VsyncSignalListener = true;
//Console.WriteLn( Color_Blue, "(EEcore Sleep) Vsync\t\tringpos=0x%06x, writepos=0x%06x", volatize(m_RingPos), m_WritePos );
m_sem_Vsync.WaitNoCancel();
}
struct PacketTagType
@ -256,7 +244,7 @@ protected:
public:
RingBufferLock( SysMtgsThread& mtgs )
: ScopedLock( mtgs.m_lock_RingBufferBusy )
: ScopedLock( mtgs.m_mtx_RingBufferBusy )
, m_mtgs( mtgs )
{
m_mtgs.m_RingBufferIsBusy = true;
@ -397,11 +385,6 @@ void SysMtgsThread::ExecuteTaskInThread()
{
switch( tag.command )
{
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];
@ -426,7 +409,12 @@ void SysMtgsThread::ExecuteTaskInThread()
PADupdate(0);
AtomicDecrement( m_QueuedFrameCount );
if (!!AtomicExchange(m_VsyncSignalListener, false))
m_sem_Vsync.Post();
busy.Release();
StateCheckInThread();
busy.Acquire();
}
break;
@ -512,6 +500,9 @@ void SysMtgsThread::ExecuteTaskInThread()
m_sem_OnRingReset.Post();
}
if (!!AtomicExchange(m_VsyncSignalListener, false))
m_sem_Vsync.Post();
//Console.Warning( "(MTGS Thread) Nothing to do! ringpos=0x%06x", m_RingPos );
}
}
@ -558,7 +549,7 @@ void SysMtgsThread::WaitGS()
RethrowException();
do {
m_lock_RingBufferBusy.Wait();
m_mtx_RingBufferBusy.Wait();
RethrowException();
} while( volatize(m_RingPos) != m_WritePos );
}
@ -588,32 +579,6 @@ void SysMtgsThread::SendDataPacket()
// make sure a previous copy block has been started somewhere.
pxAssert( m_packet_size != 0 );
#if 0
uint temp = m_packet_ringpos + m_packet_size;
pxAssert( temp <= RingBufferSize );
temp &= RingBufferMask;
if( IsDebugBuild )
{
if( m_packet_ringpos + m_packet_size < RingBufferSize )
{
uint readpos = volatize(m_RingPos);
if( readpos != m_WritePos )
{
// The writepos should never leapfrog the readpos
// since that indicates a bad write.
if( m_packet_ringpos < readpos )
pxAssert( temp < readpos );
}
// Updating the writepos should never make it equal the readpos, since
// that would stop the buffer prematurely (and indicates bad code in the
// ringbuffer manager)
pxAssert( readpos != temp );
}
}
#endif
uint actualSize = ((m_packet_ringpos - m_packet_startpos) & RingBufferMask)-1;
pxAssert( actualSize <= m_packet_size );
pxAssert( m_packet_ringpos < RingBufferSize );
@ -621,7 +586,6 @@ void SysMtgsThread::SendDataPacket()
PacketTagType& tag = (PacketTagType&)RingBuffer[m_packet_startpos];
tag.data[0] = actualSize;
//Threading::StoreFence();
m_WritePos = m_packet_ringpos;
if( EmuConfig.GS.SynchronousMTGS )