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
This commit is contained in:
parent
2b45e87b3e
commit
3b7a6ce336
|
@ -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<TVideo_Prepare>
|
||||
(LoadSymbol("Video_Prepare"));
|
||||
|
@ -74,6 +75,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo
|
|||
(LoadSymbol("Video_WaitForFrameFinish"));
|
||||
Video_IsFifoBusy = reinterpret_cast<TVideo_IsFifoBusy>
|
||||
(LoadSymbol("Video_IsFifoBusy"));
|
||||
Video_AbortFrame = reinterpret_cast<TVideo_AbortFrame>
|
||||
(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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -162,6 +162,7 @@ void WaitForFrameFinish();
|
|||
void FifoCriticalEnter();
|
||||
void FifoCriticalLeave();
|
||||
|
||||
void AbortFrame();
|
||||
} // namespace CommandProcessor
|
||||
|
||||
#endif // _COMMANDPROCESSOR_H
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -453,3 +453,8 @@ bool Video_IsFifoBusy(void)
|
|||
{
|
||||
return CommandProcessor::isFifoBusy;
|
||||
}
|
||||
|
||||
void Video_AbortFrame(void)
|
||||
{
|
||||
CommandProcessor::AbortFrame();
|
||||
}
|
|
@ -479,3 +479,8 @@ bool Video_IsFifoBusy(void)
|
|||
{
|
||||
return CommandProcessor::isFifoBusy;
|
||||
}
|
||||
|
||||
void Video_AbortFrame(void)
|
||||
{
|
||||
CommandProcessor::AbortFrame();
|
||||
}
|
||||
|
|
|
@ -510,3 +510,8 @@ bool Video_IsFifoBusy(void)
|
|||
{
|
||||
return CommandProcessor::isFifoBusy;
|
||||
}
|
||||
|
||||
void Video_AbortFrame(void)
|
||||
{
|
||||
CommandProcessor::AbortFrame();
|
||||
}
|
|
@ -220,3 +220,7 @@ bool Video_IsFifoBusy(void)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Video_AbortFrame(void)
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue