jpolo1224 5636c9f3ff Stop paying per-packet and per-argument costs in the FIFO loop
Three changes to the same loop, all measured against 36728 packets and 48737
dispatches per frame in Sonic '06.

GET is published on a bounded lag rather than every packet. It is a release
store into guest DMA memory, and get shares a 64-byte line with put which the
guest PPU writes from another CPU cluster, so each publish was a cross-cluster
coherence miss. The guest reads GET to size its free ring space and is far ahead
of us here, FIFO stalls measuring 0.1 a frame, so lag is invisible to it.
Anything that can idle or block publishes immediately: the put wait in inc_get,
the NOP path, and set_get.

The FIFO accuracy setting is snapshotted once per packet instead of being read
per argument. Reading it goes through a seq_cst atomic load, which on ARM64 is
an ldar the compiler cannot hoist out of the loop.

The again poll is relaxed. That flag is only ever set by this thread, by the
handler invoked immediately before, so sequential consistency buys nothing and
cost another ldar per dispatch.
2026-08-10 00:43:34 -04:00
2026-07-31 18:41:29 +02:00
2026-08-09 23:49:40 -04:00
2026-06-14 16:05:41 +02:00
2024-12-28 19:58:59 +01:00
2020-12-06 15:30:12 +03:00
2020-11-12 23:43:38 +03:00
2026-01-24 09:37:47 +01:00
2024-11-16 15:10:20 +01:00
2014-02-13 11:33:07 +01:00
2025-11-02 14:22:11 +02:00
2026-08-06 09:08:18 -04:00
2026-06-21 16:37:09 +02:00
2016-08-12 14:32:57 +03:00

ARMSX3

Proof of concept Android port of RPCS3.

Uses the latest RPCS3 upstream code (the recent ARM64 improvements included).

Status

From my testing, I only tried Skate 3. It boots, loads and reaches gameplay at roughly 20 to 30 fps on a Snapdragon 8 Gen 2. Rendering, audio, touch controls and physical controllers work. Almost nothing else has been tested. So the main stop gap at the moment is performance/speed.

Differences from upstream RPCS3

Some of the fixes here are not in upstream and affect any ARM64 build, not only Android:

  • Shaders declared runtime sized arrays inside uniform blocks, which requires VK_EXT_shader_uniform_buffer_unsized_array. Adreno does not support that extension, so every game pipeline failed to compile and nothing rendered. Concrete array bounds are emitted when the extension is missing.

  • The ARM64 SPU block verification checksum folded two thirds of every block through an absolute difference. That collides on the near identical job binaries an SPU job manager streams through the same local store address, so a cached block could end up running against another job's code. It sums now.

  • Thread affinity was compiled out on Android, and the core had no ARM big.LITTLE topology, so SPU and RSX threads were never placed on the fast cores.

  • The LLVM JIT target was pinned to cortex-a34, an in order core from 2016. It detects the host now.

Building

Only arm64-v8a is supported. You need the Android SDK with NDK r27 or newer, CMake 3.30 or newer, and a JDK 17. Android Studio ships all of these.

Clone with submodules, then fetch the two third party checkouts that are not submodules:

git clone --recursive https://github.com/ARMSX2/ARMSX3.git
cd ARMSX3
git clone https://github.com/SnowflakePowered/librashader 3rdparty/librashader
git clone https://github.com/bylaws/libadrenotools android/armsx3-ui/app/src/main/cpp/libadrenotools

Build the core. This is the long part and produces an unstripped library of around 1.3 GB:

export ANDROID_HOME=$HOME/Library/Android/sdk
cmake -B build-android -G Ninja \
  -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/<version>/build/cmake/android.toolchain.cmake \
  -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-31 \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build-android --target rpcsx-android -j8

Strip it and put it where the app expects it:

llvm-strip --strip-unneeded build-android/android/libarmsx3-core.so
cp build-android/android/libarmsx3-core.so \
   android/armsx3-ui/app/src/main/jniLibs/arm64-v8a/

Then build the app:

cd android/armsx3-ui
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
./gradlew :app:assembleRelease

The apk lands in app/build/outputs/apk/release/.

Note that the core library has to be rebuilt and copied again whenever anything under rpcs3/ or android/src/ changes. Gradle does not build it for you.

The Discord Social SDK is proprietary and is not redistributed here. Get it from Discord's developer portal and drop it in app/libs/ and app/src/main/cpp/discord_sdk/ if you want that feature. The build skips it otherwise.

Running it needs PS3 firmware, which is not included. License

GPL-2.0-only, the same as RPCS3. See LICENSE. Some files may be licensed differently, check the file headers.

Based on RPCS3, https://github.com/RPCS3/rpcs3

S
Description
No description provided
Readme GPL-2.0
154 MiB
Languages
C++ 77.3%
Kotlin 13.4%
C 7.2%
Self 0.7%
GLSL 0.5%
Other 0.9%