Changed cmdidle to be idle on breakpoint.
Added low watermark interrupts generated by the gather pipe. Fixes Gladius from not booting. Fixes issue 5518.
This commit is contained in:
parent
2cc1a97a66
commit
1b6240f7f9
|
@ -57,6 +57,7 @@ static bool bProcessFifoAllDistance = false;
|
||||||
|
|
||||||
volatile bool isPossibleWaitingSetDrawDone = false;
|
volatile bool isPossibleWaitingSetDrawDone = false;
|
||||||
volatile bool isHiWatermarkActive = false;
|
volatile bool isHiWatermarkActive = false;
|
||||||
|
volatile bool isLoWatermarkActive = false;
|
||||||
volatile bool interruptSet= false;
|
volatile bool interruptSet= false;
|
||||||
volatile bool interruptWaiting= false;
|
volatile bool interruptWaiting= false;
|
||||||
volatile bool interruptTokenWaiting = false;
|
volatile bool interruptTokenWaiting = false;
|
||||||
|
@ -88,6 +89,7 @@ void DoState(PointerWrap &p)
|
||||||
p.Do(bProcessFifoToLoWatermark);
|
p.Do(bProcessFifoToLoWatermark);
|
||||||
p.Do(bProcessFifoAllDistance);
|
p.Do(bProcessFifoAllDistance);
|
||||||
p.Do(isHiWatermarkActive);
|
p.Do(isHiWatermarkActive);
|
||||||
|
p.Do(isLoWatermarkActive);
|
||||||
p.Do(isPossibleWaitingSetDrawDone);
|
p.Do(isPossibleWaitingSetDrawDone);
|
||||||
p.Do(interruptSet);
|
p.Do(interruptSet);
|
||||||
p.Do(interruptWaiting);
|
p.Do(interruptWaiting);
|
||||||
|
@ -119,7 +121,7 @@ void Init()
|
||||||
m_tokenReg = 0;
|
m_tokenReg = 0;
|
||||||
|
|
||||||
memset(&fifo,0,sizeof(fifo));
|
memset(&fifo,0,sizeof(fifo));
|
||||||
fifo.CPCmdIdle = 1 ;
|
fifo.CPCmdIdle = 1;
|
||||||
fifo.CPReadIdle = 1;
|
fifo.CPReadIdle = 1;
|
||||||
fifo.bFF_Breakpoint = 0;
|
fifo.bFF_Breakpoint = 0;
|
||||||
fifo.bFF_HiWatermark = 0;
|
fifo.bFF_HiWatermark = 0;
|
||||||
|
@ -136,6 +138,7 @@ void Init()
|
||||||
bProcessFifoAllDistance = false;
|
bProcessFifoAllDistance = false;
|
||||||
isPossibleWaitingSetDrawDone = false;
|
isPossibleWaitingSetDrawDone = false;
|
||||||
isHiWatermarkActive = false;
|
isHiWatermarkActive = false;
|
||||||
|
isLoWatermarkActive = false;
|
||||||
|
|
||||||
et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper);
|
et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper);
|
||||||
}
|
}
|
||||||
|
@ -294,7 +297,6 @@ void Read16(u16& _rReturnValue, const u32 _Address)
|
||||||
|
|
||||||
void Write16(const u16 _Value, const u32 _Address)
|
void Write16(const u16 _Value, const u32 _Address)
|
||||||
{
|
{
|
||||||
|
|
||||||
INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address);
|
INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address);
|
||||||
|
|
||||||
switch (_Address & 0xFFF)
|
switch (_Address & 0xFFF)
|
||||||
|
@ -405,7 +407,8 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
{
|
{
|
||||||
GPFifo::ResetGatherPipe();
|
GPFifo::ResetGatherPipe();
|
||||||
ResetVideoBuffer();
|
ResetVideoBuffer();
|
||||||
}else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
ResetVideoBuffer();
|
ResetVideoBuffer();
|
||||||
}
|
}
|
||||||
|
@ -514,7 +517,9 @@ void AbortFrame()
|
||||||
void SetOverflowStatusFromGatherPipe()
|
void SetOverflowStatusFromGatherPipe()
|
||||||
{
|
{
|
||||||
fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
|
fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
|
||||||
|
fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark);
|
||||||
isHiWatermarkActive = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt && m_CPCtrlReg.GPReadEnable;
|
isHiWatermarkActive = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt && m_CPCtrlReg.GPReadEnable;
|
||||||
|
isLoWatermarkActive = fifo.bFF_LoWatermark && fifo.bFF_LoWatermarkInt && m_CPCtrlReg.GPReadEnable;
|
||||||
|
|
||||||
if (isHiWatermarkActive)
|
if (isHiWatermarkActive)
|
||||||
{
|
{
|
||||||
|
@ -522,6 +527,12 @@ void SetOverflowStatusFromGatherPipe()
|
||||||
INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
|
INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
|
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
|
||||||
}
|
}
|
||||||
|
else if (isLoWatermarkActive)
|
||||||
|
{
|
||||||
|
interruptSet = true;
|
||||||
|
INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
|
||||||
|
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCpStatus()
|
void SetCpStatus()
|
||||||
|
@ -562,7 +573,8 @@ void SetCpStatus()
|
||||||
|
|
||||||
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
|
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
|
||||||
|
|
||||||
isHiWatermarkActive = ovfInt && m_CPCtrlReg.GPReadEnable;
|
isHiWatermarkActive = ovfInt && m_CPCtrlReg.GPReadEnable;
|
||||||
|
isLoWatermarkActive = undfInt && m_CPCtrlReg.GPReadEnable;
|
||||||
|
|
||||||
if (interrupt != interruptSet && !interruptWaiting)
|
if (interrupt != interruptSet && !interruptWaiting)
|
||||||
{
|
{
|
||||||
|
@ -618,7 +630,7 @@ void SetCpStatusRegister()
|
||||||
// Here always there is one fifo attached to the GPU
|
// Here always there is one fifo attached to the GPU
|
||||||
m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint;
|
m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint;
|
||||||
m_CPStatusReg.ReadIdle = !fifo.CPReadWriteDistance || (fifo.CPReadPointer == fifo.CPWritePointer) || (fifo.CPReadPointer == fifo.CPBreakpoint) ;
|
m_CPStatusReg.ReadIdle = !fifo.CPReadWriteDistance || (fifo.CPReadPointer == fifo.CPWritePointer) || (fifo.CPReadPointer == fifo.CPBreakpoint) ;
|
||||||
m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance;
|
m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance || AtBreakpoint();
|
||||||
m_CPStatusReg.UnderflowLoWatermark = fifo.bFF_LoWatermark;
|
m_CPStatusReg.UnderflowLoWatermark = fifo.bFF_LoWatermark;
|
||||||
m_CPStatusReg.OverflowHiWatermark = fifo.bFF_HiWatermark;
|
m_CPStatusReg.OverflowHiWatermark = fifo.bFF_HiWatermark;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace CommandProcessor
|
||||||
extern SCPFifoStruct fifo; //This one is shared between gfx thread and emulator thread.
|
extern SCPFifoStruct fifo; //This one is shared between gfx thread and emulator thread.
|
||||||
extern volatile bool isPossibleWaitingSetDrawDone; //This one is used for sync gfx thread and emulator thread.
|
extern volatile bool isPossibleWaitingSetDrawDone; //This one is used for sync gfx thread and emulator thread.
|
||||||
extern volatile bool isHiWatermarkActive;
|
extern volatile bool isHiWatermarkActive;
|
||||||
|
extern volatile bool isLoWatermarkActive;
|
||||||
extern volatile bool interruptSet;
|
extern volatile bool interruptSet;
|
||||||
extern volatile bool interruptWaiting;
|
extern volatile bool interruptWaiting;
|
||||||
extern volatile bool interruptTokenWaiting;
|
extern volatile bool interruptTokenWaiting;
|
||||||
|
|
|
@ -155,6 +155,7 @@ void RunGpuLoop()
|
||||||
VideoFifo_CheckAsyncRequest();
|
VideoFifo_CheckAsyncRequest();
|
||||||
|
|
||||||
CommandProcessor::SetCpStatus();
|
CommandProcessor::SetCpStatus();
|
||||||
|
|
||||||
// check if we are able to run this buffer
|
// check if we are able to run this buffer
|
||||||
while (GpuRunningState && !CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint() && !PixelEngine::WaitingForPEInterrupt())
|
while (GpuRunningState && !CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint() && !PixelEngine::WaitingForPEInterrupt())
|
||||||
{
|
{
|
||||||
|
@ -172,7 +173,7 @@ void RunGpuLoop()
|
||||||
_assert_msg_(COMMANDPROCESSOR, (s32)fifo.CPReadWriteDistance - 32 >= 0 ,
|
_assert_msg_(COMMANDPROCESSOR, (s32)fifo.CPReadWriteDistance - 32 >= 0 ,
|
||||||
"Negative fifo.CPReadWriteDistance = %i in FIFO Loop !\nThat can produce inestabilty in the game. Please report it.", fifo.CPReadWriteDistance - 32);
|
"Negative fifo.CPReadWriteDistance = %i in FIFO Loop !\nThat can produce inestabilty in the game. Please report it.", fifo.CPReadWriteDistance - 32);
|
||||||
|
|
||||||
ReadDataFromFifo(uData, 32);
|
ReadDataFromFifo(uData, 32);
|
||||||
|
|
||||||
OpcodeDecoder_Run(g_bSkipCurrentFrame);
|
OpcodeDecoder_Run(g_bSkipCurrentFrame);
|
||||||
|
|
||||||
|
@ -180,6 +181,7 @@ void RunGpuLoop()
|
||||||
Common::AtomicAdd(fifo.CPReadWriteDistance, -32);
|
Common::AtomicAdd(fifo.CPReadWriteDistance, -32);
|
||||||
if((GetVideoBufferEndPtr() - g_pVideoData) == 0)
|
if((GetVideoBufferEndPtr() - g_pVideoData) == 0)
|
||||||
Common::AtomicStore(fifo.SafeCPReadPointer, fifo.CPReadPointer);
|
Common::AtomicStore(fifo.SafeCPReadPointer, fifo.CPReadPointer);
|
||||||
|
|
||||||
CommandProcessor::SetCpStatus();
|
CommandProcessor::SetCpStatus();
|
||||||
|
|
||||||
// This call is pretty important in DualCore mode and must be called in the FIFO Loop.
|
// This call is pretty important in DualCore mode and must be called in the FIFO Loop.
|
||||||
|
|
Loading…
Reference in New Issue