ppsspp
ppsspp copied to clipboard
IR Interpreter - collect remaining bugs
As many of you have noticed, the IR interpreter (which is the only practical alternative on modern iOS due to Apple restrictions) is considerably less stable in some games than the JIT or the normal interpreter.
This should be fixable with some work, just need to investigate the issues one by one in detail. Here are the ones I know of:
- ~~Burnout Legends crashes when starting the first race~~
- Metal Gear Solid: Peace Walker (https://github.com/hrydgard/ppsspp/issues/10650)
- God of War - Ghost of Sparta has a crash, might not be unique to IR: #6982 #14958 (might be dupes)
- Dissidia 012 Final Fantasy (https://github.com/hrydgard/ppsspp/issues/13990)
- Frontier Gate Boost (https://github.com/hrydgard/ppsspp/issues/10500)
Please report any others you know of here.
How about Metal Gear Solid: Peace Walker? (#10650)
Regarding Burnout Legends, it only crashed with FastMem enabled.
When FastMem and IgnoreBadMemoryAddress disabled, starting the first race will show something like this for a short time
Followed with a black screen, but background music seems to be playing (with distorted sound), and pressing ESC doesn't have any effect (didn't go to PPSSPP Menu)
With these GPU errors flooding the logs:

This flooding the logs while showing black screen:

PS: if i applied the atrac3 workaround from sum2012 that use SeekToSample, the game didn't go to black screen, but stuck on the incorrectly rendered rotating car scene with FPS slowly dropping down to 0/0 (99~100%) FPS, but background music played properly (no distortion) and pressing ESC worked normally, while the logs still showing the same things with the latest dev build tho.

Dissidia 012 Final Fantasy (https://github.com/hrydgard/ppsspp/issues/13990) Frontier Gate Boost (https://github.com/hrydgard/ppsspp/issues/10500)
Burnout Legend using IR Interpreter can cause hang and worst case is can reboot my phone because of out of memory in ram.

Workaround is disabled JIT Functionality ALU
Burnout Legend using IR Interpreter can cause hang and worst case is can reboot my phone because of out of memory in ram.
Is this memory leaks always happened and can be easily reproduced? It would be nice if you have the savestate right before doing something that could triggers the memory leaks, may be we can catch the leaks when debugging it from Visual Studio.
Workaround is disabled JIT Functionality ALU
Thanks! Yeah, this will prevent the crash when starting a race on Burnout Legends too.
Disabling ALU probably disables a lot of things, and could by proxy affect something else. Sometimes, disabling other things may also help. If there's something other than ALU or LSU that helps, that's more useful information.
It's kinda like if your automobile was having problems getting from point A to point B, and you tried shutting it off and pushing it by hand and foot to the destination. Did it help? Yes, the automobile is now at the destination. Does it tell someone what part of the electrical system is malfunctioning that keeps making it shut off on its own? Not really.
If ALU is the only thing that can help, and disabling everything but ALU doesn't even help, that is more useful.
-[Unknown]
Only by disabling ALU or ALU_IMM can fix Burnout Legends, only one of them need to be disabled
*The screenshot only have ALU & ALU_IMM enabled left, where the game still doesn't work
It pretty much has to be in IRApplyPasses, then, if ALU_IMM alone even fixes it. Most likely either RemoveLoadStoreLeftRight or PropagateConstants (can try commenting them out in the array in IRFrontend.cpp.)
-[Unknown]
Commenting PropagateConstants alone fixes the issue, RemoveLoadStoreLeftRight didn't have any effects.
Okay, commenting these cases inside PropagateConstants function will also fixes the issue.
case IROp::Sub:
case IROp::Slt:
case IROp::SltU:
symmetric = false; // fallthrough
case IROp::Add:
case IROp::And:
case IROp::Or:
case IROp::Xor:
// Regularize, for the add/or check below.
if (symmetric && inst.src2 == inst.dest && inst.src1 != inst.src2) {
std::swap(inst.src1, inst.src2);
}
if (gpr.IsImm(inst.src1) && gpr.IsImm(inst.src2)) {
gpr.SetImm(inst.dest, Evaluate(gpr.GetImm(inst.src1), gpr.GetImm(inst.src2), inst.op));
} else if (inst.op == IROp::And && gpr.IsImm(inst.src1) && gpr.GetImm(inst.src1) == 0) {
gpr.SetImm(inst.dest, 0);
} else if (inst.op == IROp::And && gpr.IsImm(inst.src2) && gpr.GetImm(inst.src2) == 0) {
gpr.SetImm(inst.dest, 0);
} else if (gpr.IsImm(inst.src2)) {
const u32 imm2 = gpr.GetImm(inst.src2);
gpr.MapDirtyIn(inst.dest, inst.src1);
if (imm2 == 0 && (inst.op == IROp::Add || inst.op == IROp::Or)) {
// Add / Or with zero is just a Mov.
if (inst.dest != inst.src1)
out.Write(IROp::Mov, inst.dest, inst.src1);
} else {
out.Write(ArithToArithConst(inst.op), inst.dest, inst.src1, out.AddConstant(imm2));
}
} else if (symmetric && gpr.IsImm(inst.src1)) {
const u32 imm1 = gpr.GetImm(inst.src1);
gpr.MapDirtyIn(inst.dest, inst.src2);
if (imm1 == 0 && (inst.op == IROp::Add || inst.op == IROp::Or)) {
// Add / Or with zero is just a Mov.
if (inst.dest != inst.src2)
out.Write(IROp::Mov, inst.dest, inst.src2);
} else {
out.Write(ArithToArithConst(inst.op), inst.dest, inst.src2, out.AddConstant(imm1));
}
} else {
gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2);
goto doDefault;
}
break;
Edit: Commenting case IROp::Or: alone is sufficient, so this is probably the main culprit.
~~Btw, does Sub affects symmetric too just like Slt/SltU ? not like Add?~~
Edit2: Changing this one line:
if (imm2 == 0 && (inst.op == IROp::Add || inst.op == IROp::Or)) {
into:
if (imm2 == 0 && (inst.op == IROp::Add)) {
will also fixes this
I don't know how to reproduce the flickering issue on Dissidia 012, but i saw missing body parts (on Vaan) during the intro of Quick Battle (1-on-1, Lightning vs Vaan) when using IR interpreter (JIT didn't have this issue)

Edit: Disabling VFPU_VEC fixes the missing body part issue
~~Btw, which file is this VFPU_VEC-related function being located?~~
Edit2: Disabling only IRFrontend::Comp_VecDo3 will also fixes the missing body part issue
Edit3: Commenting these code inside IRFrontend::Comp_VecDo3 will also fixes the issue
case 27: //VFPU3
switch ((op >> 23) & 7) {
case 2: // vmin
case 3: // vmax
allowSIMD = false;
break;
case 6: // vsge
case 7: // vslt
allowSIMD = false;
break;
default:
INVALIDOP;
}
break;
Edit4: Commenting only case 2: // vmin will be sufficient to fix this
Edit5: Changing allowSIMD = false; to true for vmin will also fixes this
Metal Gear Solid Peace Walker can also be fix by disabling jit functionality VFPU_VEC
~~Oh, I see the propagate constants bug. Derp.~~ No wait, might've been too hasty.
-[Unknown]
Would be good to check these scenarios against #15713 when it's built or merged. It could change or fix some of them.
-[Unknown]
Would be good to check these scenarios against #15713 when it's built or merged. It could change or fix some of them.
-[Unknown]
All right, i'll test again later. The flickering issue on Dissidia 012 is kinda odd, because it affects Dynarec(JIT) too when VFPU_VEC/VFPU_XFER being disabled, also flickers on Interpreter.
Btw @Gamemulatorer Could you test the artifacts from my workaround PR on MGS PW (and may be other games too) to see whether it fixes the issue there too? https://github.com/ANR2ME/ppsspp/pull/17 For Android artifact you can find it here https://github.com/ANR2ME/ppsspp/actions/runs/2713797178
Cool! with https://github.com/hrydgard/ppsspp/pull/15713 :
- Burnout Legends no longer crashing.
- Vaan on Dissidia 012 no longer showing missing/invisible body parts, but Cloud on left side still have flickering issue (since it flickers even on Interpreter or when VFPU_VEC/VFPU_XFER being disabled on Dynarec, probably a different issue)
PS: I can't reproduce the issue on MGS:PW even without https://github.com/hrydgard/ppsspp/pull/15713 (ie. v1.12.3-1435) on Windows, may be someone else can test other games mentioned in this issue.
GoW Ghost of Sparta still crashing using IR Interpreter https://github.com/hrydgard/ppsspp/issues/14958#issuecomment-932337843
Metal Gear Solid Peace Walker still have glitch

Burnouts Legends not crashing anymore using IR Interpreter 🎉
Btw @Gamemulatorer Could you test the artifacts from my workaround PR on MGS PW (and may be other games too) to see whether it fixes the issue there too? ANR2ME#17 For Android artifact you can find it here https://github.com/ANR2ME/ppsspp/actions/runs/2713797178
I will test your build later and give feedback 🙂
The issue with Ghost of Sparta might be unrelated to IR, because the game or ppsspp will also crashed on Dynarec(JIT) and Interpreter too when i tested with v1.12.3-1437 on Windows... unless the save state provided there was already corrupted, thus always crashed.
MGS:PW issue also strange, as i can't reproduce it on Windows, but i can reproduce it on Ubuntu (WSL2) and Android.
For the flickering issue on Dissidia 012, i need to remove conditional disable on Comp_VPFX and Comp_VScl like this to fix it:
But Interpreter unaffected by this and will still flickers, also both functions on Dynarec(JIT) will need to be updated too to prevent flickering when VFPU_VEC/VFPU_XFER being dsabled
Doesn't crash on my phone if i disable LSU in jit disable functionality using IR Interpreter. https://github.com/hrydgard/ppsspp/issues/14958#issuecomment-1181360943
Doesn't crash on my phone if i disable LSU in jit disable functionality using IR Interpreter. #14958 (comment)
On Windows, disabling LSU only prevent ppsspp from crashing, but the game still crashed/showing blue/purple screen. ~~But i had "Ignore bad memory access" disabled so i can catch the first crash, may be you have it enabled?~~
There is one time where the game didn't crashed but showing a strange polygon/graphical glitches like in one of your video, but only happened once during my test, most of the time either ppsspp crashed or showing blue/purple screen.
Edit: Yeah, i need to enable "Ignore bad memory access" combined with disabled LSU to prevent the game from crashing. And it could crash too on Dynarec(JIT) instead of specific to IR
Ignore Bad Memory Access is enable only LSU is disabled.
Btw @Gamemulatorer Could you test the artifacts from my workaround PR on MGS PW (and may be other games too) to see whether it fixes the issue there too? ANR2ME#17 For Android artifact you can find it here https://github.com/ANR2ME/ppsspp/actions/runs/2713797178
I will test your build later and give feedback 🙂
@ANR2ME your android build cannot locate my others games especially in internal memory.
With #16396, I think all the known IR issues might be fixed? Although someone posted one on Discord that might be that same bug.
-[Unknown]
Add Crash Of The Titans (Europe) to the list it also crashes in IR INTERPRETER see https://github.com/hrydgard/ppsspp/issues/12510
I'm not sure if it's really an IR issue specifically, given #14964 etc. Any game that requires "fast memory" to be disabled in jit should be expected to not work under IR, but that's not exactly a bug (in IR, it's definitely a bug somewhere else if any game requires fast memory in the first place.) Maybe more of a requested feature. IR doesn't support slow memory - you can't turn off fast memory for it. So it works like the actual PSP does, crashing on bad memory access.
-[Unknown]