From 3b7a6ce33686ad91b68dae455cb023c769514b9d Mon Sep 17 00:00:00 2001 From: Marcos Vitali Date: Tue, 10 Aug 2010 07:25:35 +0000 Subject: [PATCH] I've observed that "FIFO is overflown by GatherPipe" is not real overflow. Really that happens because the fifo.CPReadWriteDistance is negative. Example: CPReadWriteDistance: -864 CPEnd: 10092672 fifo.CPBase: 9568416 In SMG this is because PI_FIFO_RESET is writing and after fifo.CPReadWriteDistance will be setted to 0. To Prevent that, I've Implemented AbortFrame function in the CommmandProcessor. It should fix overflown because of that. Note: There is other issue (Issue 2846) where the fifo.CPReadWriteDistance is negative too but the effect is different. I'm working to solve this. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6083 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/PluginVideo.cpp | 6 +++++- Source/Core/Common/Src/PluginVideo.h | 2 ++ Source/Core/Core/Src/HW/ProcessorInterface.cpp | 4 +++- Source/Core/VideoCommon/Src/CommandProcessor.cpp | 14 ++++++++++++++ Source/Core/VideoCommon/Src/CommandProcessor.h | 1 + Source/Core/VideoCommon/Src/PixelEngine.cpp | 12 ++++++++++++ Source/Core/VideoCommon/Src/PixelEngine.h | 1 + Source/PluginSpecs/pluginspecs_video.h | 2 ++ Source/Plugins/Plugin_VideoDX11/Src/main.cpp | 5 +++++ Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 5 +++++ Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 5 +++++ Source/Plugins/Plugin_VideoSoftware/Src/main.cpp | 4 ++++ 12 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Source/Core/Common/Src/PluginVideo.cpp b/Source/Core/Common/Src/PluginVideo.cpp index 08174fefcb..394d21d5ee 100644 --- a/Source/Core/Common/Src/PluginVideo.cpp +++ b/Source/Core/Common/Src/PluginVideo.cpp @@ -39,6 +39,7 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo Video_GatherPipeBursted = 0; Video_WaitForFrameFinish = 0; Video_IsFifoBusy = 0; + Video_AbortFrame = 0; Video_Prepare = reinterpret_cast (LoadSymbol("Video_Prepare")); @@ -74,6 +75,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo (LoadSymbol("Video_WaitForFrameFinish")); Video_IsFifoBusy = reinterpret_cast (LoadSymbol("Video_IsFifoBusy")); + Video_AbortFrame = reinterpret_cast + (LoadSymbol("Video_AbortFrame")); if ((Video_Prepare != 0) && (Video_BeginField != 0) && (Video_EndField != 0) && @@ -91,7 +94,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo (Video_PixelEngineWrite32 != 0) && (Video_GatherPipeBursted != 0) && (Video_WaitForFrameFinish != 0) && - (Video_IsFifoBusy != 0)) + (Video_IsFifoBusy != 0) && + (Video_AbortFrame != 0)) validVideo = true; } diff --git a/Source/Core/Common/Src/PluginVideo.h b/Source/Core/Common/Src/PluginVideo.h index 04a69aec92..43e4dc00fc 100644 --- a/Source/Core/Common/Src/PluginVideo.h +++ b/Source/Core/Common/Src/PluginVideo.h @@ -40,6 +40,7 @@ typedef void (__cdecl* TVideo_Write32)(const u32 _Data, const u32 _Address); typedef void (__cdecl* TVideo_GatherPipeBursted)(); typedef void (__cdecl* TVideo_WaitForFrameFinish)(); typedef bool (__cdecl* TVideo_IsFifoBusy)(); +typedef void (__cdecl* TVideo_AbortFrame)(); class PluginVideo : public CPlugin { @@ -68,6 +69,7 @@ public: TVideo_GatherPipeBursted Video_GatherPipeBursted; TVideo_WaitForFrameFinish Video_WaitForFrameFinish; TVideo_IsFifoBusy Video_IsFifoBusy; + TVideo_AbortFrame Video_AbortFrame; private: bool validVideo; }; diff --git a/Source/Core/Core/Src/HW/ProcessorInterface.cpp b/Source/Core/Core/Src/HW/ProcessorInterface.cpp index 97efc1245e..f3fa5b72d6 100644 --- a/Source/Core/Core/Src/HW/ProcessorInterface.cpp +++ b/Source/Core/Core/Src/HW/ProcessorInterface.cpp @@ -24,7 +24,7 @@ #include "../CoreTiming.h" #include "ProcessorInterface.h" #include "GPFifo.h" - +#include "../PluginManager.h" namespace ProcessorInterface { @@ -181,6 +181,8 @@ void Write32(const u32 _uValue, const u32 _iAddress) break; case PI_FIFO_RESET: + //Abort the actual frame + CPluginManager::GetInstance().GetVideo()->Video_AbortFrame(); //Fifo_CPUWritePointer = Fifo_CPUBase; ?? //PanicAlert("Unknown write to PI_FIFO_RESET (%08x)", _uValue); WARN_LOG(PROCESSORINTERFACE, "Fifo reset (%08x)", _uValue); diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index 0bc11714b5..d3394c4840 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -701,4 +701,18 @@ void SetFifoIdleFromVideoPlugin() s_fifoIdleEvent.Set(); } +// This is called by the ProcessorInterface when PI_FIFO_RESET is writed, +// the general idea is abort all commands in the FIFO. +// This prevent Negative fifo.CPReadWriteDistance because when PI_FIFO_RESET happens +// the fifo.CPReadWriteDistance is writed to 0 +void AbortFrame() +{ + Fifo_SetRendering(false); + while(!fifo.CPCmdIdle) + Common::YieldCPU(); + Fifo_SetRendering(true); + PixelEngine::ResetSetToken(); + PixelEngine::ResetSetFinish(); +} + } // end of namespace CommandProcessor diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.h b/Source/Core/VideoCommon/Src/CommandProcessor.h index 4c29d46ca6..d84c1866fe 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.h +++ b/Source/Core/VideoCommon/Src/CommandProcessor.h @@ -162,6 +162,7 @@ void WaitForFrameFinish(); void FifoCriticalEnter(); void FifoCriticalLeave(); +void AbortFrame(); } // namespace CommandProcessor #endif // _COMMANDPROCESSOR_H diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp index 12f353f7e7..06ceeef88e 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.cpp +++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp @@ -393,4 +393,16 @@ void ResetSetFinish() } } +void ResetSetToken() +{ + if (g_bSignalTokenInterrupt) + { + g_VideoInitialize.pSetInterrupt(INT_CAUSE_PE_TOKEN, false); + g_bSignalTokenInterrupt = false; + + }else + { + g_VideoInitialize.pRemoveEvent(et_SetTokenOnMainThread); + } +} } // end of namespace PixelEngine diff --git a/Source/Core/VideoCommon/Src/PixelEngine.h b/Source/Core/VideoCommon/Src/PixelEngine.h index 6124c7b6e3..5b773c6c9b 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.h +++ b/Source/Core/VideoCommon/Src/PixelEngine.h @@ -68,6 +68,7 @@ void Write32(const u32 _iValue, const u32 _iAddress); void SetToken(const u16 _token, const int _bSetTokenAcknowledge); void SetFinish(void); void ResetSetFinish(void); +void ResetSetToken(void); bool AllowIdleSkipping(); // Bounding box functionality. Paper Mario (both) are a couple of the few games that use it. diff --git a/Source/PluginSpecs/pluginspecs_video.h b/Source/PluginSpecs/pluginspecs_video.h index 6388db13a0..7fde0e43fa 100644 --- a/Source/PluginSpecs/pluginspecs_video.h +++ b/Source/PluginSpecs/pluginspecs_video.h @@ -189,5 +189,7 @@ EXPORT void CALL Video_WaitForFrameFinish(void); // EXPORT bool CALL Video_IsFifoBusy(void); +EXPORT void CALL Video_AbortFrame(void); + #include "ExportEpilog.h" #endif diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index c6585b3909..ab61173daf 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -453,3 +453,8 @@ bool Video_IsFifoBusy(void) { return CommandProcessor::isFifoBusy; } + +void Video_AbortFrame(void) +{ + CommandProcessor::AbortFrame(); +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index e745bd4e56..93c78d542a 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -479,3 +479,8 @@ bool Video_IsFifoBusy(void) { return CommandProcessor::isFifoBusy; } + +void Video_AbortFrame(void) +{ + CommandProcessor::AbortFrame(); +} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 10cc1a283b..f886e1111b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -510,3 +510,8 @@ bool Video_IsFifoBusy(void) { return CommandProcessor::isFifoBusy; } + +void Video_AbortFrame(void) +{ + CommandProcessor::AbortFrame(); +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp index 9a6d84bab3..9cd89d1787 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp @@ -220,3 +220,7 @@ bool Video_IsFifoBusy(void) { return false; } + +void Video_AbortFrame(void) +{ +} \ No newline at end of file