This release still fixed the hangs produced by fifo overflow without sacrifice performance.

For example you can test Tutorial moves at the beginning of The last history now is fluid 30/60.
Shuffle2: I've delete the hacky line, I think is not necessary anymore. Additional some clean in CommandProcessor.
Please test The Last Story and others games affected in the previous commits and give me a feedback.
This commit is contained in:
marcosvitali 2012-03-05 02:40:10 -03:00
parent a53916ff5d
commit b0f75f17ae
10 changed files with 41 additions and 28 deletions

View File

@ -119,6 +119,7 @@ public:
virtual void Video_GatherPipeBursted() = 0;
virtual bool Video_IsPossibleWaitingSetDrawDone() = 0;
virtual bool Video_IsHiWatermarkActive() = 0;
virtual void Video_AbortFrame() = 0;
virtual readFn16 Video_CPRead16() = 0;
@ -159,6 +160,7 @@ class VideoBackendHardware : public VideoBackend
void Video_GatherPipeBursted();
bool Video_IsPossibleWaitingSetDrawDone();
bool Video_IsHiWatermarkActive();
void Video_AbortFrame();
readFn16 Video_CPRead16();

View File

@ -96,9 +96,10 @@ void STACKALIGN CheckGatherPipe()
// move back the spill bytes
memmove(m_gatherPipe, m_gatherPipe + cnt, m_gatherPipeCount);
// Profile where the FIFO writes are occurring.
if (m_gatherPipeCount == 0 && jit && (jit->js.fifoWriteAddresses.find(PC)) == (jit->js.fifoWriteAddresses.end()))
if (g_video_backend->Video_IsHiWatermarkActive() && jit && (jit->js.fifoWriteAddresses.find(PC)) == (jit->js.fifoWriteAddresses.end()))
{
jit->js.fifoWriteAddresses.insert(PC);

View File

@ -580,13 +580,10 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
FixupBranch noExtException = J_CC(CC_Z);
TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP));
FixupBranch noCPInt = J_CC(CC_Z);
TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_VI | ProcessorInterface::INT_CAUSE_PE_TOKEN | ProcessorInterface::INT_CAUSE_PE_FINISH));
FixupBranch clearInt = J_CC(CC_NZ);
MOV(32, M(&PC), Imm32(ops[i].address));
WriteExceptionExit();
SetJumpTarget(clearInt);
SetJumpTarget(noCPInt);
SetJumpTarget(noExtException);
}

View File

@ -1929,13 +1929,11 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
FixupBranch noExtException = Jit->J_CC(CC_Z);
Jit->TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP));
FixupBranch noCPInt = Jit->J_CC(CC_Z);
Jit->TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_VI | ProcessorInterface::INT_CAUSE_PE_TOKEN | ProcessorInterface::INT_CAUSE_PE_FINISH));
FixupBranch clearInt = Jit->J_CC(CC_NZ);
Jit->MOV(32, M(&PC), Imm32(InstLoc));
Jit->WriteExceptionExit();
Jit->SetJumpTarget(clearInt);
Jit->SetJumpTarget(noCPInt);
Jit->SetJumpTarget(noExtException);
break;

View File

@ -56,6 +56,7 @@ static bool bProcessFifoToLoWatermark = false;
static bool bProcessFifoAllDistance = false;
volatile bool isPossibleWaitingSetDrawDone = false;
volatile bool isHiWatermarkActive = false;
volatile bool interruptSet= false;
volatile bool interruptWaiting= false;
volatile bool interruptTokenWaiting = false;
@ -85,7 +86,7 @@ void DoState(PointerWrap &p)
p.Do(bProcessFifoToLoWatermark);
p.Do(bProcessFifoAllDistance);
p.Do(isHiWatermarkActive);
p.Do(isPossibleWaitingSetDrawDone);
p.Do(interruptSet);
p.Do(interruptWaiting);
@ -133,6 +134,7 @@ void Init()
bProcessFifoToLoWatermark = false;
bProcessFifoAllDistance = false;
isPossibleWaitingSetDrawDone = false;
isHiWatermarkActive = false;
et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper);
}
@ -141,7 +143,6 @@ void Read16(u16& _rReturnValue, const u32 _Address)
{
INFO_LOG(COMMANDPROCESSOR, "(r): 0x%08x", _Address);
ProcessFifoEvents();
switch (_Address & 0xFFF)
{
case STATUS_REGISTER:
@ -409,7 +410,6 @@ void Write16(const u16 _Value, const u32 _Address)
if (!IsOnThread())
RunGpu();
ProcessFifoEvents();
}
void Read32(u32& _rReturnValue, const u32 _Address)
@ -425,7 +425,6 @@ void Write32(const u32 _Data, const u32 _Address)
void STACKALIGN GatherPipeBursted()
{
ProcessFifoEvents();
// if we aren't linked, we don't care about gather pipe data
if (!m_CPCtrlReg.GPLinkEnable)
{
@ -487,17 +486,18 @@ void AbortFrame()
void SetOverflowStatusFromGatherPipe()
{
if (!fifo.bFF_HiWatermarkInt) return;
fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark);
isHiWatermarkActive = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt && m_CPCtrlReg.GPReadEnable;
bool interrupt = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt &&
m_CPCtrlReg.GPLinkEnable && m_CPCtrlReg.GPReadEnable;
if (interrupt != interruptSet && interrupt)
CommandProcessor::UpdateInterrupts(true);
if (isHiWatermarkActive)
{
interruptSet = true;
INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
}
}
void SetCpStatus()
@ -505,7 +505,7 @@ void SetCpStatus()
// overflow & underflow check
fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark);
// breakpoint
if (fifo.bFF_BPEnable)
@ -540,13 +540,18 @@ void SetCpStatus()
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
isHiWatermarkActive = ovfInt && m_CPCtrlReg.GPReadEnable;
if (interrupt != interruptSet && !interruptWaiting)
{
u64 userdata = interrupt?1:0;
if (IsOnThread())
{
interruptWaiting = true;
CommandProcessor::UpdateInterruptsFromVideoBackend(userdata);
if(!interrupt || bpInt || undfInt)
{
interruptWaiting = true;
CommandProcessor::UpdateInterruptsFromVideoBackend(userdata);
}
}
else
CommandProcessor::UpdateInterrupts(userdata);
@ -631,8 +636,8 @@ void SetCpControlRegister()
ProcessorInterface::Fifo_CPUEnd = fifo.CPEnd;
}
// If overflown happens process the fifo to LoWatemark
if (bProcessFifoToLoWatermark)
ProcessFifoToLoWatermark();
//if (bProcessFifoToLoWatermark)
// ProcessFifoToLoWatermark();
if(fifo.bFF_GPReadEnable && !m_CPCtrlReg.GPReadEnable)
{

View File

@ -31,6 +31,7 @@ namespace CommandProcessor
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 isHiWatermarkActive;
extern volatile bool interruptSet;
extern volatile bool interruptWaiting;
extern volatile bool interruptTokenWaiting;

View File

@ -250,6 +250,11 @@ bool VideoBackendHardware::Video_IsPossibleWaitingSetDrawDone()
return CommandProcessor::isPossibleWaitingSetDrawDone;
}
bool VideoBackendHardware::Video_IsHiWatermarkActive()
{
return CommandProcessor::isHiWatermarkActive;
}
void VideoBackendHardware::Video_AbortFrame()
{
CommandProcessor::AbortFrame();

View File

@ -180,7 +180,6 @@ void Init()
void Read16(u16& _uReturnValue, const u32 _iAddress)
{
DEBUG_LOG(PIXELENGINE, "(r16) 0x%08x", _iAddress);
CommandProcessor::ProcessFifoEvents();
switch (_iAddress & 0xFFF)
{
// CPU Direct Access EFB Raster State Config
@ -334,7 +333,6 @@ void Write16(const u16 _iValue, const u32 _iAddress)
break;
}
CommandProcessor::ProcessFifoEvents();
}
void Write32(const u32 _iValue, const u32 _iAddress)

View File

@ -215,6 +215,12 @@ bool VideoSoftware::Video_IsPossibleWaitingSetDrawDone(void)
return false;
}
bool VideoSoftware::Video_IsHiWatermarkActive(void)
{
return false;
}
void VideoSoftware::Video_AbortFrame(void)
{
}

View File

@ -36,7 +36,7 @@ class VideoSoftware : public VideoBackend
void Video_SetRendering(bool bEnabled);
void Video_GatherPipeBursted();
bool Video_IsHiWatermarkActive();
bool Video_IsPossibleWaitingSetDrawDone();
void Video_AbortFrame();