summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/Src/CommandProcessor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/Src/CommandProcessor.cpp')
-rw-r--r--Source/Core/VideoCommon/Src/CommandProcessor.cpp48
1 files changed, 38 insertions, 10 deletions
diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp
index e63c079795..1b1e7e4d4e 100644
--- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp
+++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp
@@ -98,6 +98,8 @@ UCPStatusReg m_CPStatusReg;
UCPCtrlReg m_CPCtrlReg;
UCPClearReg m_CPClearReg;
+u32 HiWatermark_Tighter;
+
int m_bboxleft;
int m_bboxtop;
int m_bboxright;
@@ -129,6 +131,7 @@ void DoState(PointerWrap &p)
p.Do(m_bboxbottom);
p.Do(m_tokenReg);
p.Do(fifo);
+ p.Do(HiWatermark_Tighter);
}
//inline void WriteLow (u32& _reg, u16 lowbits) {_reg = (_reg & 0xFFFF0000) | lowbits;}
@@ -489,6 +492,8 @@ void Write16(const u16 _Value, const u32 _Address)
break;
case FIFO_HI_WATERMARK_HI:
WriteHigh((u32 &)fifo.CPHiWatermark, _Value);
+ // Tune this when you see lots of FIFO overflown by GatherPipe
+ HiWatermark_Tighter = fifo.CPHiWatermark - 32 * 50;
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_HI_WATERMARK_HI : %04x", _Value);
break;
@@ -581,9 +586,6 @@ void STACKALIGN GatherPipeBursted()
return;
}
- _assert_msg_(COMMANDPROCESSOR, fifo.CPReadWriteDistance <= fifo.CPEnd - fifo.CPBase,
- "FIFO is overflown by GatherPipe !\nCPU thread is too fast, lower the HiWatermark may help.");
-
// update the fifo-pointer
if (fifo.CPWritePointer >= fifo.CPEnd)
fifo.CPWritePointer = fifo.CPBase;
@@ -592,17 +594,43 @@ void STACKALIGN GatherPipeBursted()
Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE);
- if (!g_VideoInitialize.bOnThread)
+ if (g_VideoInitialize.bOnThread)
+ {
+ // The interrupt latency in Dolphin is much longer than Hardware, so we must be more vigilant on Watermark
+ if (!m_CPStatusReg.OverflowHiWatermark && fifo.CPReadWriteDistance >= HiWatermark_Tighter)
+ {
+ m_CPStatusReg.OverflowHiWatermark = true;
+ if (m_CPCtrlReg.FifoOverflowIntEnable)
+ UpdateInterrupts();
+ }
+ // A little trick to prevent FIFO from overflown in dual core mode
+ // Unfortunately we cannot do the same for single core
+ int cnt = 0;
+ while (fifo.CPReadWriteDistance > fifo.CPEnd - fifo.CPBase)
+ {
+ // Avoid deadlock
+ if (cnt >= 100)
+ break;
+ cnt++;
+ SwitchToThread();
+ }
+ }
+ else
+ {
CatchUpGPU();
- // The interrupt latency in Dolphin is much longer than Hardware, so we must be more vigilant on Watermark
- if (fifo.CPReadWriteDistance >= fifo.CPHiWatermark - 32 * 20)
- {
- m_CPStatusReg.OverflowHiWatermark = true;
- if (m_CPCtrlReg.FifoOverflowIntEnable)
- UpdateInterrupts();
+ // The interrupt latency in Dolphin is much longer than Hardware, so we must be more vigilant on Watermark
+ if (!m_CPStatusReg.OverflowHiWatermark && fifo.CPReadWriteDistance >= HiWatermark_Tighter)
+ {
+ m_CPStatusReg.OverflowHiWatermark = true;
+ if (m_CPCtrlReg.FifoOverflowIntEnable)
+ UpdateInterrupts();
+ }
}
+ _assert_msg_(COMMANDPROCESSOR, fifo.CPReadWriteDistance <= fifo.CPEnd - fifo.CPBase,
+ "FIFO is overflown by GatherPipe !\nCPU thread is too fast, lower the HiWatermark may help.");
+
// check if we are in sync
_assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == *(g_VideoInitialize.Fifo_CPUWritePointer), "FIFOs linked but out of sync");
_assert_msg_(COMMANDPROCESSOR, fifo.CPBase == *(g_VideoInitialize.Fifo_CPUBase), "FIFOs linked but out of sync");