From ce2b9e30fc7056d85c37354478e39f35161d9a9c Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Sat, 17 Jul 2010 00:14:41 +0000 Subject: [PATCH] ReorderingMTGS: threading bugfixes, ringbuffer would do bad things when it got full (GS load 80%+), or when vsyncs wrapped around the edge of the ring. git-svn-id: http://pcsx2.googlecode.com/svn/branches/ReorderingMTGS@3507 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/MTGS.cpp | 25 +++++++++++++++++++------ pcsx2/ps2/GIFpath.cpp | 2 +- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/pcsx2/MTGS.cpp b/pcsx2/MTGS.cpp index fc70d9cf77..06b841dacb 100644 --- a/pcsx2/MTGS.cpp +++ b/pcsx2/MTGS.cpp @@ -639,7 +639,6 @@ void SysMtgsThread::GenericStall( uint size ) // the block about to be written (writepos + size) uint readpos = volatize(m_ReadPos); - //uint endpos = writepos+size; uint freeroom; if (writepos < readpos) @@ -647,7 +646,7 @@ void SysMtgsThread::GenericStall( uint size ) else freeroom = RingBufferSize - (writepos - readpos); - if (freeroom < size) + if (freeroom <= size) { // writepos will overlap readpos if we commit the data, so we need to wait until // readpos is out past the end of the future write pos, or until it wraps around @@ -671,13 +670,20 @@ void SysMtgsThread::GenericStall( uint size ) //Console.WriteLn( Color_Blue, "(EEcore Sleep) PrepDataPacker \tringpos=0x%06x, writepos=0x%06x, signalpos=0x%06x", readpos, writepos, m_SignalRingPosition ); - do { + while(true) { AtomicExchange( m_SignalRingEnable, 1 ); SetEvent(); m_sem_OnRingReset.WaitWithoutYield(); readpos = volatize(m_ReadPos); //Console.WriteLn( Color_Blue, "(EEcore Awake) Report!\tringpos=0x%06x", readpos ); - } while( (writepos < readpos) && (writepos+size >= readpos) ); + + if (writepos < readpos) + freeroom = readpos - writepos; + else + freeroom = RingBufferSize - (writepos - readpos); + + if (freeroom > size) break; + } pxAssertDev( m_SignalRingPosition <= 0, "MTGS Thread Synchronization Error" ); } @@ -685,10 +691,17 @@ void SysMtgsThread::GenericStall( uint size ) { //Console.WriteLn( Color_StrongGray, "(EEcore Spin) PrepDataPacket!" ); SetEvent(); - do { + while(true) { SpinWait(); readpos = volatize(m_ReadPos); - } while( (writepos < readpos) && (writepos+size >= readpos) ); + + if (writepos < readpos) + freeroom = readpos - writepos; + else + freeroom = RingBufferSize - (writepos - readpos); + + if (freeroom > size) break; + } } } } diff --git a/pcsx2/ps2/GIFpath.cpp b/pcsx2/ps2/GIFpath.cpp index 843b0605eb..049fbb566b 100644 --- a/pcsx2/ps2/GIFpath.cpp +++ b/pcsx2/ps2/GIFpath.cpp @@ -558,7 +558,7 @@ __forceinline void MemCopy_WrappedSrc( const u128* srcBase, uint& srcStart, uint uint firstcopylen = srcSize - srcStart; memcpy_qwc(dest, &srcBase[srcStart], firstcopylen ); - srcStart = endpos & srcSize; + srcStart = endpos % srcSize; memcpy_qwc(dest+firstcopylen, srcBase, srcStart ); } }