From 695010520ff004844c8137a75868dd8b046eb8f3 Mon Sep 17 00:00:00 2001 From: Marcos Vitali Date: Mon, 27 Dec 2010 02:55:35 +0000 Subject: [PATCH] More FIFO work, HACK Solution for extreme overflow on breakpoints. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1) What is the FIFO? The fifo is a ring queue for write (CPU) and read (GPU) the graphics commands. 2) What is the Brakpoints? The breakpoint is the FIFO mark to allow parallel work (CPU-GPU) When the GPU reached the breakpoint must stop read immediately until this Breakpoint will be removed for the CPU. 3) What is an overflow? The CPU write all room FIFO possible, and like a ring overwrite commands not processed yet. 4) ¿Why you have an overflow? In theory should not have an overflow never because the fifo has another mark (High Watermark) When the CPU Write reach this mark raise a CP interruption and the FIFO CPU WRITES should stop write until distance between READ POINTER AND WRITE POINTER will be equal to another mark (LO Watemark to prevent and overflow. 5) ¡So if impossible why you have overflows? Simple, the CP interruption is processed later and the Overflow happens. (there is a lot of theories about this) 6) ¿Why is no so simple like when CPU WRITE POINTER is near to the end of the FIFO only process pending graphics command? Because when this happens sometimes we are in BREAKPOINT and is IMPOSIBLE process the graphics commands. - This HACK process the pending data when CPU WRITE POINTER is 32 bytes before the end of the fifo, and if there is a Breakpoint force the situation to process the commands and prevent an overflown. In theory you have not see "FIFO is overflown by GatherPipe nCPU thread is too fast!" anymore. But if you have a hang in game where you had this please read the NOTICE LOG in user\logs, I've added this message "FIFO is almost in overflown, BreakPoint" when the hack is activated. (I will delete this message very soon) Good Luck!! PD: Shuffle sorry for the large commit description :P git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6662 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Core/VideoCommon/Src/CommandProcessor.cpp | 21 +++++++++++++++++++ .../Core/VideoCommon/Src/CommandProcessor.h | 1 + Source/Core/VideoCommon/Src/Fifo.cpp | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index e6a0589ba5..0adbf42b9b 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -118,6 +118,7 @@ volatile bool interruptSet= false; volatile bool interruptWaiting= false; volatile bool interruptTokenWaiting = false; volatile bool interruptFinishWaiting = false; +volatile bool OnOverflow = false; void FifoCriticalEnter() { @@ -669,6 +670,26 @@ void STACKALIGN GatherPipeBursted() UpdateInterruptsScMode(); } } + else + { + if(fifo.CPReadWriteDistance == fifo.CPEnd - fifo.CPBase - 32) + { + if(!OnOverflow) + NOTICE_LOG(COMMANDPROCESSOR,"FIFO is almost in overflown, BreakPoint: %i", fifo.bFF_Breakpoint); + OnOverflow = true; + while (!CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && + fifo.CPReadWriteDistance > fifo.CPEnd - fifo.CPBase - 64) + Common::YieldCPU(); + + + + + } + else + { + OnOverflow = false; + } + } _assert_msg_(COMMANDPROCESSOR, fifo.CPReadWriteDistance <= fifo.CPEnd - fifo.CPBase, diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.h b/Source/Core/VideoCommon/Src/CommandProcessor.h index 9d98c802d2..cd39d4b0c4 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.h +++ b/Source/Core/VideoCommon/Src/CommandProcessor.h @@ -35,6 +35,7 @@ extern volatile bool interruptSet; extern volatile bool interruptWaiting; extern volatile bool interruptTokenWaiting; extern volatile bool interruptFinishWaiting; +extern volatile bool OnOverflow; // internal hardware addresses enum diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index 1259b5c51a..72bb2e7ca0 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -150,7 +150,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) CommandProcessor::SetStatus(); while (!CommandProcessor::interruptWaiting && _fifo.bFF_GPReadEnable && - _fifo.CPReadWriteDistance && !AtBreakpoint()) + (_fifo.CPReadWriteDistance && !AtBreakpoint() || CommandProcessor::OnOverflow)) { // while the FIFO is processing data we activate this for sync with emulator thread.