VU: Synchronise VU1, added speedhack for old behaviour

This commit is contained in:
refractionpcsx2 2020-12-12 03:33:24 +00:00
parent 4a90499ec9
commit 7138769182
20 changed files with 127 additions and 53 deletions

View File

@ -76,6 +76,7 @@
-- Speed Hacks (SpeedHackName = <value>)
---------------------------------------------
-- mvuFlagSpeedHack = 1 or 0 // Katamari Damacy have weird speed bug when this speed hack is enabled (and it is by default)
-- InstantVU1SpeedHack = 1 or 0 // Games such as Parappa the Rapper 2 need VU1 to sync, so you can force disable the speedhack here
---------------------------------------------
-- Memory Card Filter Override (MemCardFilter = s)
@ -1391,6 +1392,7 @@ Serial = SCES-50408
Name = PaRappa the Rapper 2
Region = PAL-M5
Compat = 5
InstantVU1SpeedHack = 0 // Fixes noodles.
---------------------------------------------
Serial = SCES-50409
Name = MotoGP 2
@ -3550,6 +3552,7 @@ Region = NTSC-J
Serial = SCPS-15017
Name = PaRappa the Rapper 2
Region = NTSC-J
InstantVU1SpeedHack = 0 // Fixes noodles.
---------------------------------------------
Serial = SCPS-15018
Name = Train Simulator Real, The - Yamanote Sen
@ -4091,6 +4094,7 @@ Region = NTSC-J
Serial = SCPS-19201
Name = PaRappa the Rapper 2 [PlayStation 2 The Best]
Region = NTSC-J
InstantVU1SpeedHack = 0 // Fixes noodles.
---------------------------------------------
Serial = SCPS-19202
Name = Extermination [PlayStation 2 The Best]
@ -4924,6 +4928,7 @@ Serial = SCUS-97167
Name = PaRappa the Rapper 2
Region = NTSC-U
Compat = 5
InstantVU1SpeedHack = 0 // Fixes noodles.
---------------------------------------------
Serial = SCUS-97169
Name = Drakan - The Ancients' Gates [Demo]
@ -5080,6 +5085,7 @@ Region = NTSC-U
Serial = SCUS-97208
Name = Hot Shots Golf 3 & PaRappa the Rapper 2 [Demo]
Region = NTSC-U
InstantVU1SpeedHack = 0 // Fixes noodles on Parappa 2.
---------------------------------------------
Serial = SCUS-97209
Name = Ratchet & Clank [E3 Demo]
@ -6772,6 +6778,7 @@ Region = PAL-M5
Serial = SLED-52488
Name = Suffering, The [Demo]
Region = PAL-E
InstantVU1SpeedHack = 1 // Fixes SPS.
---------------------------------------------
Serial = SLED-52597
Name = Burnout 3 - Takedown [Demo]
@ -7793,6 +7800,7 @@ Serial = SLES-50382
Name = Silent Hill 2
Region = PAL-M6
Compat = 5
InstantVU1SpeedHack = 0 // Fixes hang on FMV's when CDVD timing is accurate.
---------------------------------------------
Serial = SLES-50383
Name = Metal Gear Solid 2 - Sons of Liberty
@ -7961,6 +7969,7 @@ Serial = SLES-50446
Name = Shadow Man - 2econd Coming
Region = PAL-M4
Compat = 4
InstantVU1SpeedHack = 0 // Fixes SPS.
---------------------------------------------
Serial = SLES-50447
Name = All-Star Baseball 2003
@ -8292,6 +8301,7 @@ Region = PAL-M4
Serial = SLES-50608
Name = Shadow Man - 2econd Coming
Region = PAL-G
InstantVU1SpeedHack = 0 // Fixes SPS.
---------------------------------------------
Serial = SLES-50613
Name = Woody Woodpecker
@ -9614,6 +9624,7 @@ Serial = SLES-51144
Name = Shox - Rally Reinvented
Region = PAL-M7
Compat = 5
VU0KickstartHack = 1 // Fixes SPS.
---------------------------------------------
Serial = SLES-51145
Name = Monopoly Party
@ -9642,6 +9653,7 @@ Serial = SLES-51156
Name = Silent Hill 2 - Director's Cut
Region = PAL-M5
Compat = 5
InstantVU1SpeedHack = 0 // Fixes hang on FMV's when CDVD timing is accurate.
---------------------------------------------
Serial = SLES-51157
Name = Silent Scope 3
@ -9863,10 +9875,12 @@ Serial = SLES-51250
Name = Shox - Rally Reinvented
Region = PAL-E
Compat = 5
VU0KickstartHack = 1 // Fixes SPS.
---------------------------------------------
Serial = SLES-51251
Name = Shox - Rally Reinvented
Region = PAL-E
VU0KickstartHack = 1 // Fixes SPS.
---------------------------------------------
Serial = SLES-51252
Name = Lord of the Rings, The - The Two Towers
@ -10797,6 +10811,7 @@ Region = PAL-S
Serial = SLES-51693
Name = Suffering, The
Region = PAL-E-F-G
InstantVU1SpeedHack = 1 // Fixes SPS.
---------------------------------------------
Serial = SLES-51696
Name = Dragon's Lair 3D - Special Edition
@ -11584,6 +11599,7 @@ Serial = SLES-52001
Name = Mission Impossible - Operation Surma
Region = PAL-M5
Compat = 5
VU0KickstartHack = 1 // Fixes crashes and broken graphics.
---------------------------------------------
Serial = SLES-52002
Name = Rogue Ops
@ -12439,6 +12455,7 @@ Serial = SLES-52439
Name = Suffering, The
Region = PAL-E-I-S
Compat = 5
InstantVU1SpeedHack = 1 // Fixes SPS.
---------------------------------------------
Serial = SLES-52440
Name = Harry Potter and the Prisoner of Azkaban
@ -12662,6 +12679,7 @@ Region = PAL-M4 // Nordic.
Serial = SLES-52531
Name = Suffering, The
Region = PAL-G
InstantVU1SpeedHack = 1 // Fixes SPS.
---------------------------------------------
Serial = SLES-52532
Name = Aces of War
@ -15191,16 +15209,19 @@ Region = PAL-G
Serial = SLES-53526
Name = Suffering, The - Ties that Bind
Region = PAL-E-F
InstantVU1SpeedHack = 1 // Fixes SPS.
MemCardFilter = SLES-53526/SLES-53527/SLES-53528/SLES-53626/SLES-51693/SLES-52439/SLES-52531
---------------------------------------------
Serial = SLES-53527
Name = Suffering, The - Ties that Bind
Region = PAL-E-I-S
InstantVU1SpeedHack = 1 // Fixes SPS.
MemCardFilter = SLES-53526/SLES-53527/SLES-53528/SLES-53626/SLES-51693/SLES-52439/SLES-52531
---------------------------------------------
Serial = SLES-53528
Name = Suffering, The - Ties that Bind
Region = PAL-G
InstantVU1SpeedHack = 1 // Fixes SPS.
MemCardFilter = SLES-53526/SLES-53527/SLES-53528/SLES-53626/SLES-51693/SLES-52439/SLES-52531
---------------------------------------------
Serial = SLES-53529
@ -15509,6 +15530,7 @@ Compat = 5
Serial = SLES-53626
Name = Suffering, The - Ties that Bind
Region = PAL-E-G
InstantVU1SpeedHack = 1 // Fixes SPS.
MemCardFilter = SLES-53526/SLES-53527/SLES-53528/SLES-53626/SLES-51693/SLES-52439/SLES-52531
---------------------------------------------
Serial = SLES-53632
@ -21725,6 +21747,7 @@ Region = NTSC-J
Serial = SLPM-61009
Name = Silent Hill 2 (Red Ribbon) [Trial]
Region = NTSC-J
InstantVU1SpeedHack = 0 // Fixes hang on FMV's when CDVD timing is accurate.
---------------------------------------------
Serial = SLPM-61010
Name = Devil May Cry [Trial Version]
@ -21733,6 +21756,7 @@ Region = NTSC-J
Serial = SLPM-61011
Name = Silent Hill 2 (Black Ribbon) [Video Trial]
Region = NTSC-J
InstantVU1SpeedHack = 0 // Fixes hang on FMV's when CDVD timing is accurate.
---------------------------------------------
Serial = SLPM-61051
Name = Dengeki PS2 D61
@ -24098,6 +24122,7 @@ Region = NTSC-J
Serial = SLPM-62737
Name = Rally Shox & Freestyle Motorcross [EA Best Hits]
Region = NTSC-J
VU0KickstartHack = 1 // Fixes SPS.
---------------------------------------------
Serial = SLPM-62739
Name = Suro Genjin
@ -24466,6 +24491,7 @@ Serial = SLPM-65051
Name = Silent Hill 2
Region = NTSC-J
Compat = 5
InstantVU1SpeedHack = 0 // Fixes hang on FMV's when CDVD timing is accurate.
---------------------------------------------
Serial = SLPM-65052
Name = Guitar Freaks 4th Mix & Drummania 3rd Mix
@ -24627,6 +24653,7 @@ Serial = SLPM-65098
Name = Silent Hill 2 - Saigo no Uta
Region = NTSC-J
Compat = 5
InstantVU1SpeedHack = 0 // Fixes hang on FMV's when CDVD timing is accurate.
---------------------------------------------
Serial = SLPM-65100
Name = Onimusha 2
@ -25437,6 +25464,7 @@ Region = NTSC-J
Serial = SLPM-65341
Name = Silent Hill 2 - Saigo No Uta [Konami The Best]
Region = NTSC-J
InstantVU1SpeedHack = 0 // Fixes hang on FMV's when CDVD timing is accurate.
---------------------------------------------
Serial = SLPM-65342
Name = Kyoufu Shinbun (Heisei) Kaiki! Shinrei File
@ -26103,6 +26131,7 @@ Region = NTSC-J
Serial = SLPM-65529
Name = Mission Impossible - Operation Surma
Region = NTSC-J
VU0KickstartHack = 1 // Fixes crashes and broken graphics.
---------------------------------------------
Serial = SLPM-65530
Name = J-League Pro Soccer Club - Tsukuku 2004
@ -26495,6 +26524,7 @@ Region = NTSC-J
Serial = SLPM-65631
Name = Silent Hill 2 [Konami The Best]
Region = NTSC-J
InstantVU1SpeedHack = 0 // Fixes hang on FMV's when CDVD timing is accurate.
---------------------------------------------
Serial = SLPM-65632
Name = Virtua Fighter Cyber Generation - Ambition of the Judgement Six
@ -38218,6 +38248,7 @@ Serial = SLUS-20228
Name = Silent Hill 2
Region = NTSC-U
Compat = 5
InstantVU1SpeedHack = 0 // Fixes hang on FMV's when CDVD timing is accurate.
---------------------------------------------
Serial = SLUS-20229
Name = Jonny Moseley - Mad Trix
@ -39062,6 +39093,7 @@ Serial = SLUS-20400
Name = Mission Impossible - Operation Surma
Region = NTSC-U
Compat = 5
VU0KickstartHack = 1 // Fixes crashes and broken graphics.
---------------------------------------------
Serial = SLUS-20402
Name = Britney's Dance Beat
@ -39111,6 +39143,7 @@ Serial = SLUS-20413
Name = Shadow Man - 2econd Coming
Region = NTSC-U
Compat = 4
InstantVU1SpeedHack = 0 // Fixes SPS.
---------------------------------------------
Serial = SLUS-20414
Name = Legaia 2 - Duel Saga
@ -39690,6 +39723,7 @@ Serial = SLUS-20533
Name = Shox
Region = NTSC-U
Compat = 5
VU0KickstartHack = 1 // Fixes SPS.
---------------------------------------------
Serial = SLUS-20534
Name = Cabela's Big Game Hunter
@ -40177,6 +40211,7 @@ Serial = SLUS-20636
Name = Suffering, The
Region = NTSC-U
Compat = 5
InstantVU1SpeedHack = 1 // Fixes SPS.
---------------------------------------------
Serial = SLUS-20637
Name = Chessmaster (Online)
@ -42886,6 +42921,7 @@ Serial = SLUS-21189
Name = Suffering, The - Ties That Bind
Region = NTSC-U
Compat = 5
InstantVU1SpeedHack = 1 // Fixes SPS.
MemCardFilter = SLUS-21189/SLUS-20636
---------------------------------------------
Serial = SLUS-21190

View File

@ -22,8 +22,8 @@
using namespace R5900;
using namespace R5900::Interpreter;
//#define CP2COND (((VU0.VI[REG_VPU_STAT].US[0] >> 8) & 1))
#define CP2COND (vif1Regs.stat.VEW)
#define CP2COND (((VU0.VI[REG_VPU_STAT].US[0] >> 8) & 1))
//#define CP2COND (vif1Regs.stat.VEW)
//Run the FINISH either side of the VCALL's as we have no control over it past here.
void VCALLMS() {

View File

@ -394,7 +394,8 @@ struct Pcsx2Config
IntcStat :1, // tells Pcsx2 to fast-forward through intc_stat waits.
WaitLoop :1, // enables constant loop detection and fast-forwarding
vuFlagHack :1, // microVU specific flag hack
vuThread :1; // Enable Threaded VU1
vuThread :1, // Enable Threaded VU1
vu1Instant :1; // Enable Instant VU1 (Without MTVU only)
BITFIELD_END
s8 EECycleRate; // EE cycle rate selector (1.0, 1.5, 2.0)
@ -527,6 +528,7 @@ TraceLogFilters& SetTraceConfig();
// ------------ CPU / Recompiler Options ---------------
#define THREAD_VU1 (EmuConfig.Cpu.Recompiler.UseMicroVU1 && EmuConfig.Speedhacks.vuThread)
#define INSTANT_VU1 (EmuConfig.Speedhacks.vu1Instant)
#define CHECK_MICROVU0 (EmuConfig.Cpu.Recompiler.UseMicroVU0)
#define CHECK_MICROVU1 (EmuConfig.Cpu.Recompiler.UseMicroVU1)
#define CHECK_EEREC (EmuConfig.Cpu.Recompiler.EnableEE && GetCpuProviders().IsRecAvailable_EE())

View File

@ -43,6 +43,7 @@ Pcsx2Config::SpeedhackOptions::SpeedhackOptions()
WaitLoop = true;
IntcStat = true;
vuFlagHack = true;
vu1Instant = true;
}
Pcsx2Config::SpeedhackOptions& Pcsx2Config::SpeedhackOptions::DisableAll()
@ -65,6 +66,7 @@ void Pcsx2Config::SpeedhackOptions::LoadSave( IniInterface& ini )
IniBitBool( WaitLoop );
IniBitBool( vuFlagHack );
IniBitBool( vuThread );
IniBitBool( vu1Instant );
}
void Pcsx2Config::ProfilerOptions::LoadSave( IniInterface& ini )

View File

@ -431,7 +431,7 @@ __fi void _cpuEventTest_Shared()
// We're in a EventTest. All dynarec registers are flushed
// so there is no need to freeze registers here.
CpuVU0->ExecuteBlock();
CpuVU1->ExecuteBlock();
// Note: We don't update the VU1 here because it runs it's micro-programs in
// one shot always. That is, when a program is executed the VU1 doesn't even
// bother to return until the program is completely finished.

View File

@ -170,10 +170,8 @@ void CTC2() {
}
break;
case REG_CMSAR1: // REG_CMSAR1
if (!(VU0.VI[REG_VPU_STAT].UL & 0x100) ) {
vu1ExecMicro(cpuRegs.GPR.r[_Rt_].US[0]); // Execute VU1 Micro SubRoutine
vif1VUFinish();
}
vu1Finish(true);
vu1ExecMicro(cpuRegs.GPR.r[_Rt_].US[0]); // Execute VU1 Micro SubRoutine
break;
default:
VU0.VI[_Fs_].UL = cpuRegs.GPR.r[_Rt_].UL[0];

View File

@ -35,15 +35,24 @@ void vu1ResetRegs()
vif1Regs.stat.VEW = false;
}
void vu1Finish() {
void vu1Finish(bool add_cycles) {
if (THREAD_VU1) {
if (VU0.VI[REG_VPU_STAT].UL & 0x100) DevCon.Error("MTVU: VU0.VI[REG_VPU_STAT].UL & 0x100");
return;
}
while (VU0.VI[REG_VPU_STAT].UL & 0x100) {
u32 vu1cycles = VU1.cycle;
if(VU0.VI[REG_VPU_STAT].UL & 0x100) {
VUM_LOG("vu1ExecMicro > Stalling until current microprogram finishes");
CpuVU1->Execute(vu1RunCycles);
}
if (VU0.VI[REG_VPU_STAT].UL & 0x100) {
DevCon.Warning("Force Stopping VU1, ran for too long");
VU0.VI[REG_VPU_STAT].UL &= ~0x100;
}
if (add_cycles)
{
cpuRegs.cycle += VU1.cycle - vu1cycles;
}
}
void __fastcall vu1ExecMicro(u32 addr)
@ -54,7 +63,7 @@ void __fastcall vu1ExecMicro(u32 addr)
return;
}
static int count = 0;
vu1Finish();
vu1Finish(false);
VUM_LOG("vu1ExecMicro %x (count=%d)", addr, count++);
VU1.cycle = cpuRegs.cycle;
@ -64,5 +73,8 @@ void __fastcall vu1ExecMicro(u32 addr)
CpuVU1->SetStartPC(VU1.VI[REG_TPC].UL << 3);
_vuExecMicroDebug(VU1);
CpuVU1->Execute(vu1RunCycles);
if(!INSTANT_VU1)
CpuVU1->ExecuteBlock(1);
else
CpuVU1->Execute(vu1RunCycles);
}

View File

@ -21,7 +21,7 @@
void BaseVUmicroCPU::ExecuteBlock(bool startUp) {
const u32& stat = VU0.VI[REG_VPU_STAT].UL;
const int test = m_Idx ? 0x100 : 1;
const int s = EmuConfig.Gamefixes.VU0KickstartHack ? 16 : 0; // Kick Start Cycles (Jak needs at least 4, DT Racer needs 8192)
const int s = EmuConfig.Gamefixes.VU0KickstartHack ? 16 : 0; // Kick Start Cycles (Jak needs at least 4 due to writing values after they're read
if (!(stat & test)) return;

View File

@ -264,7 +264,7 @@ extern void vu0Finish();
extern void iDumpVU0Registers();
// VU1
extern void vu1Finish();
extern void vu1Finish(bool add_cycles);
extern void vu1ResetRegs();
extern void __fastcall vu1ExecMicro(u32 addr);
extern void vu1Exec(VURegs* VU);

View File

@ -30,6 +30,7 @@ __fi void vif0FLUSH()
vif0.waitforvu = true;
vif0.vifstalled.enabled = VifStallEnable(vif0ch);
vif0.vifstalled.value = VIF_TIMING_BREAK;
vif0Regs.stat.VEW = true;
}
return;
}
@ -158,7 +159,7 @@ __fi void vif0VUFinish()
vif0.waitforvu = false;
ExecuteVU(0);
//Make sure VIF0 isnt already scheduled to spin.
if(!(cpuRegs.interrupt & 0x1) && vif0ch.chcr.STR && !vif0Regs.stat.INT)
if(!(cpuRegs.interrupt & 0x1) && vif0ch.chcr.STR && !vif0Regs.stat.test(VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
vif0Interrupt();
}
//DevCon.Warning("VU0 state cleared");
@ -176,7 +177,7 @@ __fi void vif0Interrupt()
if(vif0.waitforvu)
{
//CPU_INT(DMAC_VIF0, 16);
CPU_INT(VIF_VU0_FINISH, 16);
return;
}

View File

@ -30,6 +30,7 @@ __fi void vif1FLUSH()
vif1.waitforvu = true;
vif1.vifstalled.enabled = VifStallEnable(vif1ch);
vif1.vifstalled.value = VIF_TIMING_BREAK;
vif1Regs.stat.VEW = true;
}
}
@ -236,13 +237,13 @@ __fi void vif1VUFinish()
CPU_INT(VIF_VU1_FINISH, 128);
return;
}
if (VU0.VI[REG_VPU_STAT].UL & 0x100)
{
int _cycles = VU1.cycle;
u32 _cycles = VU1.cycle;
//DevCon.Warning("Finishing VU1");
vu1Finish();
CPU_INT(VIF_VU1_FINISH, (VU1.cycle - _cycles) * BIAS);
vu1Finish(false);
CPU_INT(VIF_VU1_FINISH, VU1.cycle - _cycles);
return;
}
@ -267,7 +268,7 @@ __fi void vif1VUFinish()
vif1.waitforvu = false;
ExecuteVU(1);
//Check if VIF is already scheduled to interrupt, if it's waiting, kick it :P
if((cpuRegs.interrupt & (1<<DMAC_VIF1 | 1 << DMAC_MFIFO_VIF)) == 0 && vif1ch.chcr.STR && !vif1Regs.stat.INT)
if((cpuRegs.interrupt & ((1<<DMAC_VIF1) | (1 << DMAC_MFIFO_VIF))) == 0 && vif1ch.chcr.STR && !vif1Regs.stat.test(VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{
if(dmacRegs.ctrl.MFD == MFD_VIF1)
vifMFIFOInterrupt();
@ -324,6 +325,7 @@ __fi void vif1Interrupt()
{
//DevCon.Warning("Waiting on VU1");
//CPU_INT(DMAC_VIF1, 16);
CPU_INT(VIF_VU1_FINISH, 16);
return;
}
if (!vif1ch.chcr.STR) Console.WriteLn("Vif1 running when CHCR == %x", vif1ch.chcr._u32);

View File

@ -295,7 +295,7 @@ void vifMFIFOInterrupt()
if(vif1.waitforvu)
{
// DevCon.Warning("Waiting on VU1 MFIFO");
//CPU_INT(DMAC_MFIFO_VIF, 16);
CPU_INT(VIF_VU1_FINISH, 16);
return;
}

View File

@ -41,21 +41,16 @@ __ri void vifExecQueue(int idx)
GetVifX.queued_program = false;
int startcycles = 0;
if (!idx) startcycles = VU0.cycle;
else startcycles = VU1.cycle;
if (!idx) vu0ExecMicro(vif0.queued_pc);
else vu1ExecMicro(vif1.queued_pc);
///NOTE: Shadowman 2 has SPS with this, uncommenting the correct code fixes it
if (!idx) { startcycles = ((VU0.cycle-startcycles) + ( vif0ch.qwc - (vif0.vifpacketsize >> 2) )); CPU_INT(VIF_VU0_FINISH, 1/*startcycles * BIAS*/); }
else { startcycles = ((VU1.cycle-startcycles) + ( vif1ch.qwc - (vif1.vifpacketsize >> 2) )); CPU_INT(VIF_VU1_FINISH, 1/*startcycles * BIAS*/); }
//DevCon.Warning("Ran VU%x, VU0 Cycles %x, VU1 Cycles %x, start %x cycle %x", idx, g_vu0Cycles, g_vu1Cycles, startcycles, VU1.cycle);
//GetVifX.vifstalled.enabled = VifStallEnable(vifXch);
//GetVifX.vifstalled.value = VIF_TIMING_BREAK;
// Hack for Wakeboarding Unleashed, game runs a VU program in parallel with a VIF unpack list.
// The start of the VU program clears the VU memory, while VIF populates it from behind, so we need to get the clear out of the way.
/*if (idx && !INSTANT_VU1)
{
VU1.cycle -= 256;
CpuVU1->ExecuteBlock(0);
}*/
}
static __fi void vifFlush(int idx) {
@ -74,8 +69,6 @@ static __fi void vuExecMicro(int idx, u32 addr) {
if(GetVifX.waitforvu)
return;
vifRegs.stat.VEW = true;
if (vifRegs.itops > (idx ? 0x3ffu : 0xffu)) {
Console.WriteLn("VIF%d ITOP overrun! %x", idx, vifRegs.itops);
vifRegs.itops &= (idx ? 0x3ffu : 0xffu);
@ -103,6 +96,9 @@ static __fi void vuExecMicro(int idx, u32 addr) {
GetVifX.queued_program = true;
GetVifX.queued_pc = addr;
GetVifX.unpackcalls = 0;
if (!idx || (!THREAD_VU1 && !INSTANT_VU1))
vifExecQueue(idx);
}
void ExecuteVU(int idx)
@ -271,8 +267,6 @@ static __fi void _vifCode_MPG(int idx, u32 addr, const u32 *data, int size) {
return;
}
// Don't forget the Unsigned designator for these checks
if((addr + size *4) > vuMemSize)
{

View File

@ -1064,6 +1064,7 @@ bool AppConfig::IsOkApplyPreset(int n, bool ignoreMTVU)
EmuOptions.Speedhacks = default_Pcsx2Config.Speedhacks;
EmuOptions.Speedhacks.bitset = 0; //Turn off individual hacks to make it visually clear they're not used.
EmuOptions.Speedhacks.vuThread = original_SpeedHacks.vuThread;
EmuOptions.Speedhacks.vu1Instant= original_SpeedHacks.vu1Instant;
EnableSpeedHacks = true;
// Actual application of current preset over the base settings which all presets use (mostly pcsx2's default values).
@ -1092,12 +1093,14 @@ bool AppConfig::IsOkApplyPreset(int n, bool ignoreMTVU)
EmuOptions.Speedhacks.IntcStat = true;
EmuOptions.Speedhacks.WaitLoop = true;
EmuOptions.Speedhacks.vuFlagHack = true;
EmuOptions.Speedhacks.vu1Instant = true;
// If waterfalling from > Safe, break to avoid MTVU disable.
if (n > 1) break;
[[fallthrough]];
case 0: // Safest
if(n == 0) EmuOptions.Speedhacks.vu1Instant = false;
isMTVUSet ? 0 : (isMTVUSet = true, EmuOptions.Speedhacks.vuThread = false); // Disable MTVU
break;

View File

@ -301,6 +301,14 @@ static int loadGameSettings(Pcsx2Config& dest, const Game_Data& game)
gf++;
}
if (game.keyExists("InstantVU1SpeedHack"))
{
bool vu1InstantHack = game.getInt("InstantVU1SpeedHack") ? 1 : 0;
PatchesCon->WriteLn("(GameDB) Changing Instant VU1 speedhack [mode=%d]", vu1InstantHack);
dest.Speedhacks.vu1Instant = vu1InstantHack;
gf++;
}
for (GamefixId id = GamefixId_FIRST; id < pxEnumEnd; ++id)
{
wxString key(EnumToString(id));

View File

@ -342,6 +342,7 @@ namespace Panels
pxCheckBox* m_check_fastCDVD;
pxCheckBox* m_check_vuFlagHack;
pxCheckBox* m_check_vuThread;
pxCheckBox* m_check_vu1Instant;
public:
virtual ~SpeedHacksPanel() = default;

View File

@ -176,12 +176,18 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent )
m_check_vuThread = new pxCheckBox( vuHacksPanel, _("MTVU (Multi-Threaded microVU1)"),
_("Good Speedup and High Compatibility; may cause hanging... [Recommended if 3+ cores]") );
m_check_vu1Instant = new pxCheckBox(vuHacksPanel, _("Instant VU1 (Without MTVU Only)"),
_("Good Speedup and High Compatibility; may cause some graphical errors"));
m_check_vuFlagHack->SetToolTip( pxEt( L"Updates Status Flags only on blocks which will read them, instead of all the time. This is safe most of the time."
) );
m_check_vuThread->SetToolTip( pxEt( L"Runs VU1 on its own thread (microVU1-only). Generally a speedup on CPUs with 3 or more cores. This is safe for most games, but a few games are incompatible and may hang. In the case of GS limited games, it may be a slowdown (especially on dual core CPUs)."
) );
m_check_vu1Instant->SetToolTip(pxEt(L"Runs VU1 Instantly (When MTVU is disabled). Provides a modest speed improvement. This is safe for most games, but a few games may exhibit graphical errors."
));
// ------------------------------------------------------------------------
// All other hacks Section:
@ -225,6 +231,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent )
*vuHacksPanel += m_check_vuFlagHack | StdExpand();
*vuHacksPanel += m_check_vuThread | StdExpand();
*vuHacksPanel += m_check_vu1Instant | StdExpand();
//*vuHacksPanel += 57; // Aligns left and right boxes in default language and font size
*miscHacksPanel += m_check_intc | StdExpand();
@ -281,6 +288,7 @@ void Panels::SpeedHacksPanel::EnableStuff( AppConfig* configToUse )
m_check_intc->Enable(HacksEnabledAndNoPreset);
m_check_waitloop->Enable(HacksEnabledAndNoPreset);
m_check_fastCDVD->Enable(HacksEnabledAndNoPreset);
m_check_vu1Instant->Enable(hacksEnabled);
// Grayout MTVU on safest preset
m_check_vuThread->Enable(hacksEnabled && (!hasPreset || configToUse->PresetIndex != 0));
@ -315,7 +323,7 @@ void Panels::SpeedHacksPanel::ApplyConfigToGui( AppConfig& configToApply, int fl
m_check_waitloop->SetValue(opts.WaitLoop);
m_check_fastCDVD->SetValue(opts.fastCDVD);
m_check_vuThread->SetValue(opts.vuThread);
m_check_vu1Instant->SetValue(opts.vu1Instant);
// Then, lock(gray out)/unlock the widgets as necessary.
EnableStuff( &configToApply );
@ -339,6 +347,7 @@ void Panels::SpeedHacksPanel::Apply()
opts.IntcStat = m_check_intc->GetValue();
opts.vuFlagHack = m_check_vuFlagHack->GetValue();
opts.vuThread = m_check_vuThread->GetValue();
opts.vu1Instant = m_check_vu1Instant->GetValue();
// If the user has a command line override specified, we need to disable it
// so that their changes take effect

View File

@ -63,11 +63,20 @@ void mVUDTendProgram(mV, microFlagCycles* mFC, int isEbit) {
}
// Save P/Q Regs
if (qInst) { xPSHUF.D(xmmPQ, xmmPQ, 0xe5); }
if (qInst) { xPSHUF.D(xmmPQ, xmmPQ, 0xe1); }
xMOVSS(ptr32[&mVU.regs().VI[REG_Q].UL], xmmPQ);
xPSHUF.D(xmmPQ, xmmPQ, 0xe1);
xMOVSS(ptr32[&mVU.regs().pending_q], xmmPQ);
xPSHUF.D(xmmPQ, xmmPQ, 0xe1);
if (isVU1) {
xPSHUF.D(xmmPQ, xmmPQ, pInst ? 3 : 2);
xPSHUF.D(xmmPQ, xmmPQ, pInst ? 0x1b : 0x4e);
xMOVSS(ptr32[&mVU.regs().VI[REG_P].UL], xmmPQ);
xPSHUF.D(xmmPQ, xmmPQ, pInst ? 0x1b : 0x4e);
xPSHUF.D(xmmPQ, xmmPQ, 0x1b);
xMOVSS(ptr32[&mVU.regs().pending_p], xmmPQ);
xPSHUF.D(xmmPQ, xmmPQ, 0x1b);
}
// Save MAC, Status and CLIP Flag Instances
@ -102,10 +111,9 @@ void mVUDTendProgram(mV, microFlagCycles* mFC, int isEbit) {
xMOVAPS(ptr128[&mVU.regs().micro_statusflags], xmmT1);
}
if (isEbit || isVU1) { // Clear 'is busy' Flags
if (isEbit) { // Clear 'is busy' Flags
if (!mVU.index || !THREAD_VU1) {
xAND(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? ~0x100 : ~0x001)); // VBS0/VBS1 flag
xAND(ptr32[&mVU.getVifRegs().stat], ~VIF1_STAT_VEW); // Clear VU 'is busy' signal for vif
}
}
@ -161,11 +169,11 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit) {
xPSHUF.D(xmmPQ, xmmPQ, 0xe1);
if (isVU1) {
xPSHUF.D(xmmPQ, xmmPQ, pInst ? 0x1b : 0x1e);
xPSHUF.D(xmmPQ, xmmPQ, pInst ? 0x1b : 0x4e);
xMOVSS(ptr32[&mVU.regs().VI[REG_P].UL], xmmPQ);
xPSHUF.D(xmmPQ, xmmPQ, pInst ? 0x1b : 0x4b);
xPSHUF.D(xmmPQ, xmmPQ, pInst ? 0x1b : 0x4e);
xPSHUF.D(xmmPQ, xmmPQ, 0xe1);
xPSHUF.D(xmmPQ, xmmPQ, 0x1b);
xMOVSS(ptr32[&mVU.regs().pending_p], xmmPQ);
xPSHUF.D(xmmPQ, xmmPQ, 0x1b);
}
@ -204,10 +212,9 @@ void mVUendProgram(mV, microFlagCycles* mFC, int isEbit) {
}
if ((isEbit && isEbit != 3) || isVU1) { // Clear 'is busy' Flags
if ((isEbit && isEbit != 3)) { // Clear 'is busy' Flags
if (!mVU.index || !THREAD_VU1) {
xAND(ptr32[&VU0.VI[REG_VPU_STAT].UL], (isVU1 ? ~0x100 : ~0x001)); // VBS0/VBS1 flag
//xAND(ptr32[&mVU.getVifRegs().stat], ~VIF1_STAT_VEW); // Clear VU 'is busy' signal for vif
}
}

View File

@ -491,8 +491,6 @@ void* mVUcompileSingleInstruction(microVU& mVU, u32 startPC, uptr pState, microF
mVUsetFlags(mVU, mFC); // Sets Up Flag instances
mVUoptimizePipeState(mVU); // Optimize the End Pipeline State for nicer Block Linking
mVUdebugPrintBlocks(mVU, false); // Prints Start/End PC of blocks executed, for debugging...
mVUtestCycles(mVU, mFC); // Update VU Cycles and Exit Early if Necessary
// Second Pass
iPC = startPC / 4;

View File

@ -247,8 +247,8 @@ INTERPRETATE_COP2_FUNC(CALLMSR);
void _setupBranchTest(u32*(jmpType)(u32), bool isLikely) {
printCOP2("COP2 Branch");
_eeFlushAllUnused();
xTEST(ptr32[&vif1Regs.stat._u32], 0x4);
//TEST32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, 0x100);
//xTEST(ptr32[&vif1Regs.stat._u32], 0x4);
xTEST(ptr32[&VU0.VI[REG_VPU_STAT].UL], 0x100);
recDoBranchImm(jmpType(0), isLikely);
}
@ -397,12 +397,13 @@ static void recCTC2() {
break;
}
case REG_CMSAR1: // Execute VU1 Micro SubRoutine
xMOV(ecx, 1);
xFastCall((void*)vu1Finish, ecx);
if (_Rt_) {
xMOV(ecx, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
}
else xXOR(ecx, ecx);
xFastCall((void*)vu1ExecMicro, ecx);
xFastCall((void*)vif1VUFinish);
break;
case REG_FBRST:
if (!_Rt_) {