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:
parent
a53916ff5d
commit
b0f75f17ae
|
@ -119,6 +119,7 @@ public:
|
||||||
virtual void Video_GatherPipeBursted() = 0;
|
virtual void Video_GatherPipeBursted() = 0;
|
||||||
|
|
||||||
virtual bool Video_IsPossibleWaitingSetDrawDone() = 0;
|
virtual bool Video_IsPossibleWaitingSetDrawDone() = 0;
|
||||||
|
virtual bool Video_IsHiWatermarkActive() = 0;
|
||||||
virtual void Video_AbortFrame() = 0;
|
virtual void Video_AbortFrame() = 0;
|
||||||
|
|
||||||
virtual readFn16 Video_CPRead16() = 0;
|
virtual readFn16 Video_CPRead16() = 0;
|
||||||
|
@ -159,6 +160,7 @@ class VideoBackendHardware : public VideoBackend
|
||||||
void Video_GatherPipeBursted();
|
void Video_GatherPipeBursted();
|
||||||
|
|
||||||
bool Video_IsPossibleWaitingSetDrawDone();
|
bool Video_IsPossibleWaitingSetDrawDone();
|
||||||
|
bool Video_IsHiWatermarkActive();
|
||||||
void Video_AbortFrame();
|
void Video_AbortFrame();
|
||||||
|
|
||||||
readFn16 Video_CPRead16();
|
readFn16 Video_CPRead16();
|
||||||
|
|
|
@ -98,7 +98,8 @@ void STACKALIGN CheckGatherPipe()
|
||||||
memmove(m_gatherPipe, m_gatherPipe + cnt, m_gatherPipeCount);
|
memmove(m_gatherPipe, m_gatherPipe + cnt, m_gatherPipeCount);
|
||||||
|
|
||||||
// Profile where the FIFO writes are occurring.
|
// 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);
|
jit->js.fifoWriteAddresses.insert(PC);
|
||||||
|
|
||||||
|
|
|
@ -580,13 +580,10 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
FixupBranch noExtException = J_CC(CC_Z);
|
FixupBranch noExtException = J_CC(CC_Z);
|
||||||
TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP));
|
TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP));
|
||||||
FixupBranch noCPInt = J_CC(CC_Z);
|
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));
|
MOV(32, M(&PC), Imm32(ops[i].address));
|
||||||
WriteExceptionExit();
|
WriteExceptionExit();
|
||||||
|
|
||||||
SetJumpTarget(clearInt);
|
|
||||||
SetJumpTarget(noCPInt);
|
SetJumpTarget(noCPInt);
|
||||||
SetJumpTarget(noExtException);
|
SetJumpTarget(noExtException);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1929,13 +1929,11 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
|
||||||
FixupBranch noExtException = Jit->J_CC(CC_Z);
|
FixupBranch noExtException = Jit->J_CC(CC_Z);
|
||||||
Jit->TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP));
|
Jit->TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP));
|
||||||
FixupBranch noCPInt = Jit->J_CC(CC_Z);
|
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->MOV(32, M(&PC), Imm32(InstLoc));
|
||||||
Jit->WriteExceptionExit();
|
Jit->WriteExceptionExit();
|
||||||
|
|
||||||
Jit->SetJumpTarget(clearInt);
|
|
||||||
Jit->SetJumpTarget(noCPInt);
|
Jit->SetJumpTarget(noCPInt);
|
||||||
Jit->SetJumpTarget(noExtException);
|
Jit->SetJumpTarget(noExtException);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -56,6 +56,7 @@ static bool bProcessFifoToLoWatermark = false;
|
||||||
static bool bProcessFifoAllDistance = false;
|
static bool bProcessFifoAllDistance = false;
|
||||||
|
|
||||||
volatile bool isPossibleWaitingSetDrawDone = false;
|
volatile bool isPossibleWaitingSetDrawDone = false;
|
||||||
|
volatile bool isHiWatermarkActive = 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;
|
||||||
|
@ -85,7 +86,7 @@ void DoState(PointerWrap &p)
|
||||||
|
|
||||||
p.Do(bProcessFifoToLoWatermark);
|
p.Do(bProcessFifoToLoWatermark);
|
||||||
p.Do(bProcessFifoAllDistance);
|
p.Do(bProcessFifoAllDistance);
|
||||||
|
p.Do(isHiWatermarkActive);
|
||||||
p.Do(isPossibleWaitingSetDrawDone);
|
p.Do(isPossibleWaitingSetDrawDone);
|
||||||
p.Do(interruptSet);
|
p.Do(interruptSet);
|
||||||
p.Do(interruptWaiting);
|
p.Do(interruptWaiting);
|
||||||
|
@ -133,6 +134,7 @@ void Init()
|
||||||
bProcessFifoToLoWatermark = false;
|
bProcessFifoToLoWatermark = false;
|
||||||
bProcessFifoAllDistance = false;
|
bProcessFifoAllDistance = false;
|
||||||
isPossibleWaitingSetDrawDone = false;
|
isPossibleWaitingSetDrawDone = false;
|
||||||
|
isHiWatermarkActive = false;
|
||||||
|
|
||||||
et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper);
|
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);
|
INFO_LOG(COMMANDPROCESSOR, "(r): 0x%08x", _Address);
|
||||||
ProcessFifoEvents();
|
|
||||||
switch (_Address & 0xFFF)
|
switch (_Address & 0xFFF)
|
||||||
{
|
{
|
||||||
case STATUS_REGISTER:
|
case STATUS_REGISTER:
|
||||||
|
@ -409,7 +410,6 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
|
|
||||||
if (!IsOnThread())
|
if (!IsOnThread())
|
||||||
RunGpu();
|
RunGpu();
|
||||||
ProcessFifoEvents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Read32(u32& _rReturnValue, const u32 _Address)
|
void Read32(u32& _rReturnValue, const u32 _Address)
|
||||||
|
@ -425,7 +425,6 @@ void Write32(const u32 _Data, const u32 _Address)
|
||||||
|
|
||||||
void STACKALIGN GatherPipeBursted()
|
void STACKALIGN GatherPipeBursted()
|
||||||
{
|
{
|
||||||
ProcessFifoEvents();
|
|
||||||
// if we aren't linked, we don't care about gather pipe data
|
// if we aren't linked, we don't care about gather pipe data
|
||||||
if (!m_CPCtrlReg.GPLinkEnable)
|
if (!m_CPCtrlReg.GPLinkEnable)
|
||||||
{
|
{
|
||||||
|
@ -487,16 +486,17 @@ void AbortFrame()
|
||||||
|
|
||||||
void SetOverflowStatusFromGatherPipe()
|
void SetOverflowStatusFromGatherPipe()
|
||||||
{
|
{
|
||||||
if (!fifo.bFF_HiWatermarkInt) return;
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
bool interrupt = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt &&
|
if (isHiWatermarkActive)
|
||||||
m_CPCtrlReg.GPLinkEnable && m_CPCtrlReg.GPReadEnable;
|
{
|
||||||
|
interruptSet = true;
|
||||||
if (interrupt != interruptSet && interrupt)
|
INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
|
||||||
CommandProcessor::UpdateInterrupts(true);
|
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,14 +540,19 @@ void SetCpStatus()
|
||||||
|
|
||||||
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
|
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
|
||||||
|
|
||||||
|
isHiWatermarkActive = ovfInt && m_CPCtrlReg.GPReadEnable;
|
||||||
|
|
||||||
if (interrupt != interruptSet && !interruptWaiting)
|
if (interrupt != interruptSet && !interruptWaiting)
|
||||||
{
|
{
|
||||||
u64 userdata = interrupt?1:0;
|
u64 userdata = interrupt?1:0;
|
||||||
if (IsOnThread())
|
if (IsOnThread())
|
||||||
|
{
|
||||||
|
if(!interrupt || bpInt || undfInt)
|
||||||
{
|
{
|
||||||
interruptWaiting = true;
|
interruptWaiting = true;
|
||||||
CommandProcessor::UpdateInterruptsFromVideoBackend(userdata);
|
CommandProcessor::UpdateInterruptsFromVideoBackend(userdata);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
CommandProcessor::UpdateInterrupts(userdata);
|
CommandProcessor::UpdateInterrupts(userdata);
|
||||||
}
|
}
|
||||||
|
@ -631,8 +636,8 @@ void SetCpControlRegister()
|
||||||
ProcessorInterface::Fifo_CPUEnd = fifo.CPEnd;
|
ProcessorInterface::Fifo_CPUEnd = fifo.CPEnd;
|
||||||
}
|
}
|
||||||
// If overflown happens process the fifo to LoWatemark
|
// If overflown happens process the fifo to LoWatemark
|
||||||
if (bProcessFifoToLoWatermark)
|
//if (bProcessFifoToLoWatermark)
|
||||||
ProcessFifoToLoWatermark();
|
// ProcessFifoToLoWatermark();
|
||||||
|
|
||||||
if(fifo.bFF_GPReadEnable && !m_CPCtrlReg.GPReadEnable)
|
if(fifo.bFF_GPReadEnable && !m_CPCtrlReg.GPReadEnable)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 interruptSet;
|
extern volatile bool interruptSet;
|
||||||
extern volatile bool interruptWaiting;
|
extern volatile bool interruptWaiting;
|
||||||
extern volatile bool interruptTokenWaiting;
|
extern volatile bool interruptTokenWaiting;
|
||||||
|
|
|
@ -250,6 +250,11 @@ bool VideoBackendHardware::Video_IsPossibleWaitingSetDrawDone()
|
||||||
return CommandProcessor::isPossibleWaitingSetDrawDone;
|
return CommandProcessor::isPossibleWaitingSetDrawDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VideoBackendHardware::Video_IsHiWatermarkActive()
|
||||||
|
{
|
||||||
|
return CommandProcessor::isHiWatermarkActive;
|
||||||
|
}
|
||||||
|
|
||||||
void VideoBackendHardware::Video_AbortFrame()
|
void VideoBackendHardware::Video_AbortFrame()
|
||||||
{
|
{
|
||||||
CommandProcessor::AbortFrame();
|
CommandProcessor::AbortFrame();
|
||||||
|
|
|
@ -180,7 +180,6 @@ void Init()
|
||||||
void Read16(u16& _uReturnValue, const u32 _iAddress)
|
void Read16(u16& _uReturnValue, const u32 _iAddress)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(PIXELENGINE, "(r16) 0x%08x", _iAddress);
|
DEBUG_LOG(PIXELENGINE, "(r16) 0x%08x", _iAddress);
|
||||||
CommandProcessor::ProcessFifoEvents();
|
|
||||||
switch (_iAddress & 0xFFF)
|
switch (_iAddress & 0xFFF)
|
||||||
{
|
{
|
||||||
// CPU Direct Access EFB Raster State Config
|
// CPU Direct Access EFB Raster State Config
|
||||||
|
@ -334,7 +333,6 @@ void Write16(const u16 _iValue, const u32 _iAddress)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandProcessor::ProcessFifoEvents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write32(const u32 _iValue, const u32 _iAddress)
|
void Write32(const u32 _iValue, const u32 _iAddress)
|
||||||
|
|
|
@ -215,6 +215,12 @@ bool VideoSoftware::Video_IsPossibleWaitingSetDrawDone(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VideoSoftware::Video_IsHiWatermarkActive(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VideoSoftware::Video_AbortFrame(void)
|
void VideoSoftware::Video_AbortFrame(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ class VideoSoftware : public VideoBackend
|
||||||
void Video_SetRendering(bool bEnabled);
|
void Video_SetRendering(bool bEnabled);
|
||||||
|
|
||||||
void Video_GatherPipeBursted();
|
void Video_GatherPipeBursted();
|
||||||
|
bool Video_IsHiWatermarkActive();
|
||||||
bool Video_IsPossibleWaitingSetDrawDone();
|
bool Video_IsPossibleWaitingSetDrawDone();
|
||||||
void Video_AbortFrame();
|
void Video_AbortFrame();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue