mirror of https://github.com/PCSX2/pcsx2.git
VU: Run sync ahead on small blocks
This commit is contained in:
parent
eabda670ac
commit
6dc5087cbd
|
@ -20,6 +20,19 @@
|
|||
#include "GS.h"
|
||||
#include "Gif_Unit.h"
|
||||
|
||||
__inline u32 CalculateMinRunCycles(u32 cycles, bool requiresAccurateCycles)
|
||||
{
|
||||
// If we're running an interlocked COP2 operation
|
||||
// run for an exact amount of cycles
|
||||
if(requiresAccurateCycles)
|
||||
return cycles;
|
||||
|
||||
// Allow a minimum of 16 cycles to avoid running small blocks
|
||||
// Running a block of like 3 cycles is highly inefficient
|
||||
// so while sync isn't tight, it's okay to run ahead a little bit.
|
||||
return std::max(16U, cycles);
|
||||
}
|
||||
|
||||
// Executes a Block based on EE delta time
|
||||
void BaseVUmicroCPU::ExecuteBlock(bool startUp)
|
||||
{
|
||||
|
@ -57,12 +70,12 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp)
|
|||
if (EmuConfig.Gamefixes.VUKickstartHack)
|
||||
{
|
||||
if (delta > 0) // When kickstarting we just need 1 cycle for run ahead
|
||||
Execute(delta);
|
||||
Execute(CalculateMinRunCycles(delta, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delta >= nextblockcycles && delta > 0) // When running behind, make sure we have enough cycles passed for the block to run
|
||||
Execute(delta);
|
||||
Execute(CalculateMinRunCycles(delta, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +84,7 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp)
|
|||
// EE data to VU0's registers. We want to run VU0 Micro right after this
|
||||
// to ensure that the register is used at the correct time.
|
||||
// This fixes spinning/hanging in some games like Ratchet and Clank's Intro.
|
||||
void BaseVUmicroCPU::ExecuteBlockJIT(BaseVUmicroCPU* cpu)
|
||||
void BaseVUmicroCPU::ExecuteBlockJIT(BaseVUmicroCPU* cpu, bool interlocked)
|
||||
{
|
||||
const u32& stat = VU0.VI[REG_VPU_STAT].UL;
|
||||
const int test = 1;
|
||||
|
@ -83,7 +96,7 @@ void BaseVUmicroCPU::ExecuteBlockJIT(BaseVUmicroCPU* cpu)
|
|||
|
||||
if (delta > 0)
|
||||
{
|
||||
cpu->Execute(delta); // Execute the time since the last call
|
||||
cpu->Execute(CalculateMinRunCycles(delta, interlocked)); // Execute the time since the last call
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ public:
|
|||
// Executes a Block based on EE delta time (see VUmicro.cpp)
|
||||
virtual void ExecuteBlock(bool startUp=0);
|
||||
|
||||
static void __fastcall ExecuteBlockJIT(BaseVUmicroCPU* cpu);
|
||||
static void __fastcall ExecuteBlockJIT(BaseVUmicroCPU* cpu, bool interlocked);
|
||||
|
||||
// VU1 sometimes needs to break execution on XGkick Path1 transfers if
|
||||
// there is another gif path 2/3 transfer already taking place.
|
||||
|
|
|
@ -27,6 +27,7 @@ extern u32 pc; // recompiler pc
|
|||
extern int g_branch; // set for branch
|
||||
extern u32 target; // branch target
|
||||
extern u32 s_nBlockCycles; // cycles of current block recompiling
|
||||
extern bool s_nBlockInterlocked; // Current block has VU0 interlocking
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
|
@ -61,7 +61,7 @@ alignas(16) static u32 hwLUT[_64kb];
|
|||
static __fi u32 HWADDR(u32 mem) { return hwLUT[mem >> 16] + mem; }
|
||||
|
||||
u32 s_nBlockCycles = 0; // cycles of current block recompiling
|
||||
|
||||
bool s_nBlockInterlocked = false; // Block is VU0 interlocked
|
||||
u32 pc; // recompiler pc
|
||||
int g_branch; // set for branch
|
||||
|
||||
|
@ -1927,6 +1927,7 @@ static void __fastcall recRecompile(const u32 startpc)
|
|||
|
||||
// reset recomp state variables
|
||||
s_nBlockCycles = 0;
|
||||
s_nBlockInterlocked = false;
|
||||
pc = startpc;
|
||||
g_cpuHasConstReg = g_cpuFlushedConstReg = 1;
|
||||
pxAssert(g_cpuConstRegs[0].UD[0] == 0);
|
||||
|
|
|
@ -963,7 +963,8 @@ void recLQC2()
|
|||
xForwardJL32 skip;
|
||||
_cop2BackupRegs();
|
||||
xLoadFarAddr(arg1reg, CpuVU0);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg);
|
||||
xMOV(arg2reg, s_nBlockInterlocked);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg, arg2reg);
|
||||
_cop2RestoreRegs();
|
||||
skip.SetTarget();
|
||||
skipvuidle.SetTarget();
|
||||
|
@ -1012,7 +1013,8 @@ void recSQC2()
|
|||
xForwardJL32 skip;
|
||||
_cop2BackupRegs();
|
||||
xLoadFarAddr(arg1reg, CpuVU0);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg);
|
||||
xMOV(arg2reg, s_nBlockInterlocked);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg, arg2reg);
|
||||
_cop2RestoreRegs();
|
||||
skip.SetTarget();
|
||||
skipvuidle.SetTarget();
|
||||
|
|
|
@ -327,6 +327,7 @@ void COP2_Interlock(bool mBitSync)
|
|||
|
||||
if (cpuRegs.code & 1)
|
||||
{
|
||||
s_nBlockInterlocked = true;
|
||||
_freeX86reg(eax);
|
||||
xMOV(eax, ptr32[&cpuRegs.cycle]);
|
||||
xADD(eax, scaleblockcycles_clear());
|
||||
|
@ -342,7 +343,8 @@ void COP2_Interlock(bool mBitSync)
|
|||
xCMP(eax, 0);
|
||||
xForwardJL32 skip;
|
||||
xLoadFarAddr(arg1reg, CpuVU0);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg);
|
||||
xMOV(arg2reg, s_nBlockInterlocked);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg, arg2reg);
|
||||
skip.SetTarget();
|
||||
|
||||
xFastCall((void*)_vu0WaitMicro);
|
||||
|
@ -387,7 +389,8 @@ static void recCFC2()
|
|||
xForwardJL32 skip;
|
||||
_cop2BackupRegs();
|
||||
xLoadFarAddr(arg1reg, CpuVU0);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg);
|
||||
xMOV(arg2reg, s_nBlockInterlocked);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg, arg2reg);
|
||||
_cop2RestoreRegs();
|
||||
skip.SetTarget();
|
||||
skipvuidle.SetTarget();
|
||||
|
@ -449,7 +452,8 @@ static void recCTC2()
|
|||
xForwardJL32 skip;
|
||||
_cop2BackupRegs();
|
||||
xLoadFarAddr(arg1reg, CpuVU0);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg);
|
||||
xMOV(arg2reg, s_nBlockInterlocked);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg, arg2reg);
|
||||
_cop2RestoreRegs();
|
||||
skip.SetTarget();
|
||||
skipvuidle.SetTarget();
|
||||
|
@ -551,7 +555,8 @@ static void recQMFC2()
|
|||
xForwardJL32 skip;
|
||||
_cop2BackupRegs();
|
||||
xLoadFarAddr(arg1reg, CpuVU0);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg);
|
||||
xMOV(arg2reg, s_nBlockInterlocked);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg, arg2reg);
|
||||
_cop2RestoreRegs();
|
||||
skip.SetTarget();
|
||||
skipvuidle.SetTarget();
|
||||
|
@ -591,7 +596,8 @@ static void recQMTC2()
|
|||
xForwardJL32 skip;
|
||||
_cop2BackupRegs();
|
||||
xLoadFarAddr(arg1reg, CpuVU0);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg);
|
||||
xMOV(arg2reg, s_nBlockInterlocked);
|
||||
xFastCall((void*)BaseVUmicroCPU::ExecuteBlockJIT, arg1reg, arg2reg);
|
||||
_cop2RestoreRegs();
|
||||
skip.SetTarget();
|
||||
skipvuidle.SetTarget();
|
||||
|
|
Loading…
Reference in New Issue