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_GatherPipeBursted = 0;
|
||||||
Video_WaitForFrameFinish = 0;
|
Video_WaitForFrameFinish = 0;
|
||||||
Video_IsFifoBusy = 0;
|
Video_IsFifoBusy = 0;
|
||||||
|
Video_AbortFrame = 0;
|
||||||
|
|
||||||
Video_Prepare = reinterpret_cast<TVideo_Prepare>
|
Video_Prepare = reinterpret_cast<TVideo_Prepare>
|
||||||
(LoadSymbol("Video_Prepare"));
|
(LoadSymbol("Video_Prepare"));
|
||||||
|
@ -74,6 +75,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo
|
||||||
(LoadSymbol("Video_WaitForFrameFinish"));
|
(LoadSymbol("Video_WaitForFrameFinish"));
|
||||||
Video_IsFifoBusy = reinterpret_cast<TVideo_IsFifoBusy>
|
Video_IsFifoBusy = reinterpret_cast<TVideo_IsFifoBusy>
|
||||||
(LoadSymbol("Video_IsFifoBusy"));
|
(LoadSymbol("Video_IsFifoBusy"));
|
||||||
|
Video_AbortFrame = reinterpret_cast<TVideo_AbortFrame>
|
||||||
|
(LoadSymbol("Video_AbortFrame"));
|
||||||
if ((Video_Prepare != 0) &&
|
if ((Video_Prepare != 0) &&
|
||||||
(Video_BeginField != 0) &&
|
(Video_BeginField != 0) &&
|
||||||
(Video_EndField != 0) &&
|
(Video_EndField != 0) &&
|
||||||
|
@ -91,7 +94,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo
|
||||||
(Video_PixelEngineWrite32 != 0) &&
|
(Video_PixelEngineWrite32 != 0) &&
|
||||||
(Video_GatherPipeBursted != 0) &&
|
(Video_GatherPipeBursted != 0) &&
|
||||||
(Video_WaitForFrameFinish != 0) &&
|
(Video_WaitForFrameFinish != 0) &&
|
||||||
(Video_IsFifoBusy != 0))
|
(Video_IsFifoBusy != 0) &&
|
||||||
|
(Video_AbortFrame != 0))
|
||||||
validVideo = true;
|
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_GatherPipeBursted)();
|
||||||
typedef void (__cdecl* TVideo_WaitForFrameFinish)();
|
typedef void (__cdecl* TVideo_WaitForFrameFinish)();
|
||||||
typedef bool (__cdecl* TVideo_IsFifoBusy)();
|
typedef bool (__cdecl* TVideo_IsFifoBusy)();
|
||||||
|
typedef void (__cdecl* TVideo_AbortFrame)();
|
||||||
|
|
||||||
class PluginVideo : public CPlugin
|
class PluginVideo : public CPlugin
|
||||||
{
|
{
|
||||||
|
@ -68,6 +69,7 @@ public:
|
||||||
TVideo_GatherPipeBursted Video_GatherPipeBursted;
|
TVideo_GatherPipeBursted Video_GatherPipeBursted;
|
||||||
TVideo_WaitForFrameFinish Video_WaitForFrameFinish;
|
TVideo_WaitForFrameFinish Video_WaitForFrameFinish;
|
||||||
TVideo_IsFifoBusy Video_IsFifoBusy;
|
TVideo_IsFifoBusy Video_IsFifoBusy;
|
||||||
|
TVideo_AbortFrame Video_AbortFrame;
|
||||||
private:
|
private:
|
||||||
bool validVideo;
|
bool validVideo;
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "../CoreTiming.h"
|
#include "../CoreTiming.h"
|
||||||
#include "ProcessorInterface.h"
|
#include "ProcessorInterface.h"
|
||||||
#include "GPFifo.h"
|
#include "GPFifo.h"
|
||||||
|
#include "../PluginManager.h"
|
||||||
namespace ProcessorInterface
|
namespace ProcessorInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -181,6 +181,8 @@ void Write32(const u32 _uValue, const u32 _iAddress)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PI_FIFO_RESET:
|
case PI_FIFO_RESET:
|
||||||
|
//Abort the actual frame
|
||||||
|
CPluginManager::GetInstance().GetVideo()->Video_AbortFrame();
|
||||||
//Fifo_CPUWritePointer = Fifo_CPUBase; ??
|
//Fifo_CPUWritePointer = Fifo_CPUBase; ??
|
||||||
//PanicAlert("Unknown write to PI_FIFO_RESET (%08x)", _uValue);
|
//PanicAlert("Unknown write to PI_FIFO_RESET (%08x)", _uValue);
|
||||||
WARN_LOG(PROCESSORINTERFACE, "Fifo reset (%08x)", _uValue);
|
WARN_LOG(PROCESSORINTERFACE, "Fifo reset (%08x)", _uValue);
|
||||||
|
|
|
@ -701,4 +701,18 @@ void SetFifoIdleFromVideoPlugin()
|
||||||
s_fifoIdleEvent.Set();
|
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
|
} // end of namespace CommandProcessor
|
||||||
|
|
|
@ -162,6 +162,7 @@ void WaitForFrameFinish();
|
||||||
void FifoCriticalEnter();
|
void FifoCriticalEnter();
|
||||||
void FifoCriticalLeave();
|
void FifoCriticalLeave();
|
||||||
|
|
||||||
|
void AbortFrame();
|
||||||
} // namespace CommandProcessor
|
} // namespace CommandProcessor
|
||||||
|
|
||||||
#endif // _COMMANDPROCESSOR_H
|
#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
|
} // 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 SetToken(const u16 _token, const int _bSetTokenAcknowledge);
|
||||||
void SetFinish(void);
|
void SetFinish(void);
|
||||||
void ResetSetFinish(void);
|
void ResetSetFinish(void);
|
||||||
|
void ResetSetToken(void);
|
||||||
bool AllowIdleSkipping();
|
bool AllowIdleSkipping();
|
||||||
|
|
||||||
// Bounding box functionality. Paper Mario (both) are a couple of the few games that use it.
|
// 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 bool CALL Video_IsFifoBusy(void);
|
||||||
|
|
||||||
|
EXPORT void CALL Video_AbortFrame(void);
|
||||||
|
|
||||||
#include "ExportEpilog.h"
|
#include "ExportEpilog.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -453,3 +453,8 @@ bool Video_IsFifoBusy(void)
|
||||||
{
|
{
|
||||||
return CommandProcessor::isFifoBusy;
|
return CommandProcessor::isFifoBusy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Video_AbortFrame(void)
|
||||||
|
{
|
||||||
|
CommandProcessor::AbortFrame();
|
||||||
|
}
|
|
@ -479,3 +479,8 @@ bool Video_IsFifoBusy(void)
|
||||||
{
|
{
|
||||||
return CommandProcessor::isFifoBusy;
|
return CommandProcessor::isFifoBusy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Video_AbortFrame(void)
|
||||||
|
{
|
||||||
|
CommandProcessor::AbortFrame();
|
||||||
|
}
|
||||||
|
|
|
@ -510,3 +510,8 @@ bool Video_IsFifoBusy(void)
|
||||||
{
|
{
|
||||||
return CommandProcessor::isFifoBusy;
|
return CommandProcessor::isFifoBusy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Video_AbortFrame(void)
|
||||||
|
{
|
||||||
|
CommandProcessor::AbortFrame();
|
||||||
|
}
|
|
@ -220,3 +220,7 @@ bool Video_IsFifoBusy(void)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Video_AbortFrame(void)
|
||||||
|
{
|
||||||
|
}
|
Loading…
Reference in New Issue