mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
d1e0922417
commit
168a60ad13
|
@ -256,9 +256,9 @@ __forceinline void memcpy_amd_qwc(void *dest, const void *src, size_t qwc)
|
||||||
|
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
mov ecx, [dest]
|
mov ecx, dest
|
||||||
mov edx, [src]
|
mov edx, src
|
||||||
mov eax, [qwc] ; keep a copy of count
|
mov eax, qwc ; keep a copy of count
|
||||||
shr eax, 1
|
shr eax, 1
|
||||||
jz $memcpy_qwc_1 ; only one 16 byte block to copy?
|
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?
|
jnz $memcpy_qwc_loop1 ; last 64-byte block?
|
||||||
|
|
||||||
$memcpy_qwc_1:
|
$memcpy_qwc_1:
|
||||||
test [qwc],1
|
test qwc,1
|
||||||
jz $memcpy_qwc_final
|
jz $memcpy_qwc_final
|
||||||
movq mm0,[edx]
|
movq mm0,[edx]
|
||||||
movq mm1,[edx+8]
|
movq mm1,[edx+8]
|
||||||
|
|
|
@ -258,7 +258,6 @@ enum MTGS_RingCommand
|
||||||
GS_RINGTYPE_P1
|
GS_RINGTYPE_P1
|
||||||
, GS_RINGTYPE_P2
|
, GS_RINGTYPE_P2
|
||||||
, GS_RINGTYPE_P3
|
, GS_RINGTYPE_P3
|
||||||
, GS_RINGTYPE_RESTART
|
|
||||||
, GS_RINGTYPE_VSYNC
|
, GS_RINGTYPE_VSYNC
|
||||||
, GS_RINGTYPE_FRAMESKIP
|
, GS_RINGTYPE_FRAMESKIP
|
||||||
, GS_RINGTYPE_FREEZE
|
, GS_RINGTYPE_FREEZE
|
||||||
|
@ -291,10 +290,12 @@ public:
|
||||||
volatile u32 m_SignalRingEnable;
|
volatile u32 m_SignalRingEnable;
|
||||||
volatile s32 m_SignalRingPosition;
|
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_OnRingReset;
|
||||||
|
Semaphore m_sem_Vsync;
|
||||||
|
|
||||||
// used to keep multiple threads from sending packets to the ringbuffer concurrently.
|
// 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)
|
// (currently not used or implemented -- is a planned feature for a future threaded VU1)
|
||||||
|
|
|
@ -77,6 +77,7 @@ void SysMtgsThread::OnStart()
|
||||||
m_packet_ringpos = 0;
|
m_packet_ringpos = 0;
|
||||||
|
|
||||||
m_QueuedFrameCount = 0;
|
m_QueuedFrameCount = 0;
|
||||||
|
m_VsyncSignalListener = false;
|
||||||
m_SignalRingEnable = 0;
|
m_SignalRingEnable = 0;
|
||||||
m_SignalRingPosition= 0;
|
m_SignalRingPosition= 0;
|
||||||
|
|
||||||
|
@ -106,6 +107,7 @@ void SysMtgsThread::ResetGS()
|
||||||
|
|
||||||
m_RingPos = m_WritePos;
|
m_RingPos = m_WritePos;
|
||||||
m_QueuedFrameCount = 0;
|
m_QueuedFrameCount = 0;
|
||||||
|
m_VsyncSignalListener = false;
|
||||||
|
|
||||||
MTGS_LOG( "MTGS: Sending Reset..." );
|
MTGS_LOG( "MTGS: Sending Reset..." );
|
||||||
SendSimplePacket( GS_RINGTYPE_RESET, 0, 0, 0 );
|
SendSimplePacket( GS_RINGTYPE_RESET, 0, 0, 0 );
|
||||||
|
@ -142,33 +144,19 @@ void SysMtgsThread::PostVsyncEnd()
|
||||||
|
|
||||||
SendDataPacket();
|
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.
|
// 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
|
// Use the Queued FrameCount to stall the EE if another vsync (or two) are already queued
|
||||||
// the ringbuffer.
|
// 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);
|
m_VsyncSignalListener = true;
|
||||||
uint freeroom;
|
//Console.WriteLn( Color_Blue, "(EEcore Sleep) Vsync\t\tringpos=0x%06x, writepos=0x%06x", volatize(m_RingPos), m_WritePos );
|
||||||
|
m_sem_Vsync.WaitNoCancel();
|
||||||
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" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PacketTagType
|
struct PacketTagType
|
||||||
|
@ -256,7 +244,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RingBufferLock( SysMtgsThread& mtgs )
|
RingBufferLock( SysMtgsThread& mtgs )
|
||||||
: ScopedLock( mtgs.m_lock_RingBufferBusy )
|
: ScopedLock( mtgs.m_mtx_RingBufferBusy )
|
||||||
, m_mtgs( mtgs )
|
, m_mtgs( mtgs )
|
||||||
{
|
{
|
||||||
m_mtgs.m_RingBufferIsBusy = true;
|
m_mtgs.m_RingBufferIsBusy = true;
|
||||||
|
@ -397,11 +385,6 @@ void SysMtgsThread::ExecuteTaskInThread()
|
||||||
{
|
{
|
||||||
switch( tag.command )
|
switch( tag.command )
|
||||||
{
|
{
|
||||||
case GS_RINGTYPE_RESTART:
|
|
||||||
//MTGS_LOG( "(MTGS Packet Read) ringtype=Restart" );
|
|
||||||
m_RingPos = 0;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case GS_RINGTYPE_VSYNC:
|
case GS_RINGTYPE_VSYNC:
|
||||||
{
|
{
|
||||||
const int qsize = tag.data[0];
|
const int qsize = tag.data[0];
|
||||||
|
@ -426,7 +409,12 @@ void SysMtgsThread::ExecuteTaskInThread()
|
||||||
PADupdate(0);
|
PADupdate(0);
|
||||||
|
|
||||||
AtomicDecrement( m_QueuedFrameCount );
|
AtomicDecrement( m_QueuedFrameCount );
|
||||||
|
if (!!AtomicExchange(m_VsyncSignalListener, false))
|
||||||
|
m_sem_Vsync.Post();
|
||||||
|
|
||||||
|
busy.Release();
|
||||||
StateCheckInThread();
|
StateCheckInThread();
|
||||||
|
busy.Acquire();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -512,6 +500,9 @@ void SysMtgsThread::ExecuteTaskInThread()
|
||||||
m_sem_OnRingReset.Post();
|
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 );
|
//Console.Warning( "(MTGS Thread) Nothing to do! ringpos=0x%06x", m_RingPos );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -558,7 +549,7 @@ void SysMtgsThread::WaitGS()
|
||||||
RethrowException();
|
RethrowException();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
m_lock_RingBufferBusy.Wait();
|
m_mtx_RingBufferBusy.Wait();
|
||||||
RethrowException();
|
RethrowException();
|
||||||
} while( volatize(m_RingPos) != m_WritePos );
|
} while( volatize(m_RingPos) != m_WritePos );
|
||||||
}
|
}
|
||||||
|
@ -588,32 +579,6 @@ void SysMtgsThread::SendDataPacket()
|
||||||
// make sure a previous copy block has been started somewhere.
|
// make sure a previous copy block has been started somewhere.
|
||||||
pxAssert( m_packet_size != 0 );
|
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;
|
uint actualSize = ((m_packet_ringpos - m_packet_startpos) & RingBufferMask)-1;
|
||||||
pxAssert( actualSize <= m_packet_size );
|
pxAssert( actualSize <= m_packet_size );
|
||||||
pxAssert( m_packet_ringpos < RingBufferSize );
|
pxAssert( m_packet_ringpos < RingBufferSize );
|
||||||
|
@ -621,7 +586,6 @@ void SysMtgsThread::SendDataPacket()
|
||||||
PacketTagType& tag = (PacketTagType&)RingBuffer[m_packet_startpos];
|
PacketTagType& tag = (PacketTagType&)RingBuffer[m_packet_startpos];
|
||||||
tag.data[0] = actualSize;
|
tag.data[0] = actualSize;
|
||||||
|
|
||||||
//Threading::StoreFence();
|
|
||||||
m_WritePos = m_packet_ringpos;
|
m_WritePos = m_packet_ringpos;
|
||||||
|
|
||||||
if( EmuConfig.GS.SynchronousMTGS )
|
if( EmuConfig.GS.SynchronousMTGS )
|
||||||
|
|
Loading…
Reference in New Issue