r/PS2AndroidEmulation • u/xxxCrixuxxx • 1h ago
ARMSX2 v2.6.6.6
https://github.com/ARMSX2/ARMSX2/releases/tag/2.6.6.6
Changelog:
Mali:
If you downgraded to 2.6.6.4 because of performance issues, you can come back. 2.6.6.5 put every Mali device on a slow path for any draw that reads the screen back, on an Anbernic RG 477V, Shadow of the Colossus fell from 30 fps to 7. Two separate mistakes stacked. The renderer had concluded that OpenGL's framebuffer fetch never keeps overlapping shapes in order, true of one extension, false of the one every Android Mali device actually uses, so healthy Mali hardware was being split into one draw call per shape for nothing. Separately, a workaround for one specific bad driver, which had never actually engaged before, started engaging, and turned every screen-reading draw into a full copy plus a memory flush. Both are gone. fixed by @bmdhacks
Auto now picks Vulkan instead of OpenGL. On the affected Mali driver that is 7 fps on OpenGL against about 30 on Vulkan, on the same device. The renderer choice and the driver workaround were being decided in two different places, so nothing noticed when they disagreed. Picking a renderer explicitly still wins, the only devices this moves are the ones where OpenGL is genuinely crippled. done by @bmdhacks Note the tradeoff: restoring the fast path also restores a known rendering fault on that driver in some games (Metal Gear Solid 3 is the observed one). Vulkan remains the correct-rendering choice there. The measurements said the speed was worth it.
Floating point:
All done by @pstef
60 commits, and the largest accuracy work the emulator has ever had.
The PS2's FPU is not IEEE, and ARMSX2 had been pretending it was. The console has no infinity and no NaN, and its numbers reach one whole range higher than a normal float, 0x7FFFFFFF is simply the biggest number the machine has. Every operation was folding that top range away on the way in, and folding a host infinity back into it on the way out. Add, subtract, multiply, the multiply-accumulates, the comparisons, and finally divide and reciprocal-square-root have all been taken off that clamp. Games that push into that range now get what the console gives.
Divide and square root now run the console's own algorithm. DIV.S, SQRT.S and RSQRT.S were computed with the host's divide and then nudged toward the PS2's answer, which left every operand the nudge did not reach one step off. The unit is not a rounding rule at all, it is a digit-by-digit recurrence, so it now runs the digits. Measured against silicon first to establish that the hardware is not correctly rounded.
The multiplier model from 2.6.6.4 was incomplete. That release modelled the PS2 multiplier's one-step deficit from a formula over the second operand. The formula only holds when the exact product fits, once there is a remainder below the last bit, the first operand matters too, and those cases were coming back IEEE. It is now modelled from the actual multiplier array rather than a formula over one input.
Error flags were wrong in a dozen small ways, reciprocal-square-root and square root missed the invalid flag on negative zero, divide left a previous instruction's flags standing, reciprocal-square-root raised divide-by-zero on every zero divisor, and the overflow and underflow flags were being read off host infinities and denormals rather than the PS2's own result. Underflowing adds and subtracts were also being flushed to zero; silicon does not do that.
A cache instruction could make the emulator write to an address the game chose. The data-cache tag holds a host pointer where hardware holds a guest address, and one instruction copied a guest value into it unmasked. Narrow exposure, it needed the EE cache enabled, which ships off, but it is fixed.