summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authormemberTwo.mb2 <memberTwo.mb2@gmail.com>2008-11-14 22:33:48 +0000
committermemberTwo.mb2 <memberTwo.mb2@gmail.com>2008-11-14 22:33:48 +0000
commitab1774b28a6a7cbdf52e9114ef323bee067e387c (patch)
tree2ea8697ea084d75cd126f2edc8842cb1fd1a0f5c /Source/Core/VideoCommon
parentdc123aeebf23b2c4d61c0f58ecc1a3a565ff6706 (diff)
DC fix/hack: 1) now a GP-watchdog thread on core 2 locks CPU in gatherpipe (TODO better). 2) Video_SendFifoData send full fifo to GP (should be faster by avoiding the decoder to stall).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1178 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/Src/Fifo.cpp74
1 files changed, 50 insertions, 24 deletions
diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp
index 3ba946b273..c1b1009d48 100644
--- a/Source/Core/VideoCommon/Src/Fifo.cpp
+++ b/Source/Core/VideoCommon/Src/Fifo.cpp
@@ -67,12 +67,9 @@ u8* FAKE_GetFifoEndPtr()
return &videoBuffer[size];
}
-void Video_SendFifoData(u8* _uData)
+void Video_SendFifoData(u8* _uData, u32 len)
{
- // TODO (mb2): unrolled loop faster than memcpy here?
- memcpy(videoBuffer + size, _uData, 32);
- size += 32;
- if (size + 32 >= FIFO_SIZE)
+ if (size + len >= FIFO_SIZE)
{
int pos = (int)(g_pVideoData-videoBuffer);
if (size-pos > pos)
@@ -83,12 +80,38 @@ void Video_SendFifoData(u8* _uData)
size -= pos;
g_pVideoData = FAKE_GetFifoStartPtr();
}
+ memcpy(videoBuffer + size, _uData, len);
+ size += len;
OpcodeDecoder_Run();
}
+// for GP watchdog hack
+THREAD_RETURN GPWatchdogThread(void *pArg)
+{
+ const SCPFifoStruct &_fifo = *(SCPFifoStruct*)pArg;
+ u32 token = 0;
+
+ Common::SetCurrentThreadName("GPWatchdogThread");
+ Common::Thread::SetCurrentThreadAffinity(2); //Force to second core
+ //int i=30*1000/16;
+ while (1)
+ {
+ Common::SleepCurrentThread(8); // about 1s/60/2 (less than twice a frame should be enough)
+ //if (!_fifo.bFF_GPReadIdle)
+
+ // TODO (mb2): FIX this !!!
+ //if (token == _fifo.Fake_GPWDToken)
+ {
+ InterlockedExchange((LONG*)&_fifo.Fake_GPWDInterrupt, 1);
+ //__Log(LogTypes::VIDEO,"!!! Watchdog hit",_fifo.CPReadWriteDistance);
+ }
+ token = _fifo.Fake_GPWDToken;
+ //i--;
+ }
+ return 0;
+}
+
-//TODO - turn inside out, have the "reader" ask for bytes instead
-// See Core.cpp for threading idea
void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
{
SCPFifoStruct &_fifo = *video_initialize.pCPFifo;
@@ -97,6 +120,10 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
if (hEventOnIdle==NULL) PanicAlert("Fifo_EnterLoop() -> EventOnIdle NULL");
#endif
+ // for GP watchdog hack
+ Common::Thread *watchdogThread = NULL;
+ watchdogThread = new Common::Thread(GPWatchdogThread, (void*)&_fifo);
+
#ifdef _WIN32
// TODO(ector): Don't peek so often!
while (video_initialize.pPeekMessages())
@@ -123,7 +150,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
while(_fifo.CPReadWriteDistance > 0)
#else
- while(_fifo.bFF_GPReadEnable && (_fifo.CPReadWriteDistance > 0) )// && count)
+ while(_fifo.bFF_GPReadEnable && (_fifo.CPReadWriteDistance > 0) )
#endif
{
// check if we are on a breakpoint
@@ -144,28 +171,27 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
// read the data and send it to the VideoPlugin
u8 *uData = video_initialize.pGetMemoryPointer(_fifo.CPReadPointer);
-#ifdef _WIN32
- //EnterCriticalSection(&_fifo.sync);
-#else
- // _fifo.sync->Enter();
-#endif
- Video_SendFifoData(uData);
- // increase the ReadPtr
- u32 readPtr = _fifo.CPReadPointer+32;
- if (readPtr >= _fifo.CPEnd)
- readPtr = _fifo.CPBase;
+
+ u32 dist = _fifo.CPReadWriteDistance;
+ u32 readPtr = _fifo.CPReadPointer;
+ if ( (dist+readPtr) > _fifo.CPEnd) // TODO: better
+ {
+ dist =_fifo.CPEnd - readPtr;
+ readPtr = _fifo.CPBase;
+ }
+ else
+ readPtr += dist;
+
+ Video_SendFifoData(uData, dist);
#ifdef _WIN32
InterlockedExchange((LONG*)&_fifo.CPReadPointer, readPtr);
- InterlockedExchangeAdd((LONG*)&_fifo.CPReadWriteDistance, -32);
- //LeaveCriticalSection(&_fifo.sync);
+ InterlockedExchangeAdd((LONG*)&_fifo.CPReadWriteDistance, -dist);
#else
Common::InterlockedExchange((int*)&_fifo.CPReadPointer, readPtr);
- Common::InterlockedExchangeAdd((int*)&_fifo.CPReadWriteDistance, -32);
- // _fifo.sync->Leave();
+ Common::InterlockedExchangeAdd((int*)&_fifo.CPReadWriteDistance, -dist);
#endif
- }
+ }
}
-
}
#if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32)
CloseHandle(hEventOnIdle);