All games

Luanti

Rust · 60 0.2 h played, 0 crashes

A voxel sandbox engine for building and exploring, with Minetest Game and thousands of mods.

Genre
sandbox adventure
Players
single player online multiplayer
Input
made for keyboard and mouse
View
3D first-person
Content
mods
Keywords
voxel building

Played sessions

Testing is done with Walnut's rating tool (walnut-rate, on the console): how ratings are made and submitted.

Same in every session: Walnut 0.1

DateLauncherGame buildPlatform builds that differRulesPlayEndedPicture
2026-10-29 Luanti luanti 5.15.2+dfsg-2+ps3.1124~dev20261029153146 Linux kernel 6.12.111+ps3.874
Mesa 26.2.4-1+ps3.924
ps3rsx 0.924+k6.12.111+ps3.874
2.311 minquit ok Details
2026-10-24 Luanti luanti 5.15.2+dfsg-2+ps3.786 Linux kernel 6.12.111+ps3.747
Mesa 26.2.4-1+ps3.721
ps3rsx 0.735+k6.12.111+ps3.747
1.08 minquit ok Details

Download all sessions as CSV (one row per session, the aspects as columns)

Rating history

The rating on each version it was tested on, newest first: each row is rated from that version's sessions alone, under the newest rules those sessions have the data for.

VersionTestedMedalRules Frame rateSmoothnessSoundPictureStabilityControlsDisplayFeaturesLoad Play
Walnut 0.1
luanti 5.15.2+dfsg-2+ps3.1124~dev20261029153146
2026-10-29 Rust · 60 2.3 10-99100911008510092 0.2 h
1 test
Walnut 0.1
luanti 5.15.2+dfsg-2
2026-10-24 Scrap · 56 1.0 22-9610090---98 0.1 h
1 test

Scripted benchmarks

Not rated: tests of driver and game changes. A script plays the same scene on the PS3 again and again (the desktop stopped, vsync off) to compare two builds of the game or of the graphics driver. The numbers say which build is faster; they never feed the medal.

How the script plays it: Luanti 5.15.2 with Minetest Game: a fixed flight over terrain generated from a fixed seed.

The recipe's full description

Luanti 5.15.2 (our build, LuaJIT, ppc64) with Minetest Game (luanti-game-minetest): a fixed flight over terrain generated from a fixed seed. A server-side mod can't count frames, so the world mod ps3bench (assets/luanti-ps3bench) only makes every run the same: it holds the player at the start for 15 s while the first blocks are generated and meshed, logs "ps3bench: path start", flies 45 s (240 nodes north looking down, then a full turn), logs "ps3bench: path end" and shuts the game down. fps from the Gallium HUD from the "path start" line (the load time includes the 15 s hold; parse prints joined=, Luanti's own stamps from its first log line to the join). Steady state: the path is flown 4 times (ps3bench_loops; the mod logs "path loop K"), 180 s after the hold. WARMUP=45 from "path start": the hold and the first loop (60 s after joining, the fresh world's first terrain generated) don't count; the HUD window is loops 2-4 (MEASURE=135), the same terrain flown again (generated by then; blocks the server or client unloaded come back). World and config live in /var/tmp/ps3-bench/luanti (the player's ~/.minetest worlds and minetest.conf are untouched). The world is made new for every run, so each run generates the same terrain (mapgen CPU time counts, as for a player exploring); variant saved keeps the last map. The mod also logs the process's memory every 5 s; parse() turns it into mem_* keys (KiB). The other variants (below) change one memory or load-stall lever each; the game's technical.md has the reasoning, the sizes assumed for each, and the measurements.

57 variants of the recipe
base stands for the gamethe recipe as it is, without a variant
savedthe map from the previous run: loaded from disk instead of generated
nopppost-processing off (on by default: the scene goes through an FBO)
mipmipmapping on (off by default): Mesa generates the levels on the GPU
chunk3Mapgen. The built-in server generates a whole chunk at a time (chunksize 5 = 80^3 nodes) inside a voxel manipulator that is one block larger on every side (7^3 blocks: 5.6 MB of nodes, 1.4 MB of flags, 343 MapBlocks of 16 KB created in the map), with v7's two 3D noises kept for good (2 x 4.2 MB) and the cave noises made and freed per chunk (2 x 4.2 MB): ~30 MB at the peak, all touched for every chunk. chunksize 3 (48^3) is ~8 MB. A world-creation setting (a new world here): the terrain's shape is the same, trees and ores near chunk borders differ; the border is a bigger share of each chunk (5^3 blocks processed per 3^3 instead of 7^3 per 5^3), so generation costs more CPU per node.
srvunloadThe server keeps a block 29 s after the last time it was wanted (generated chunks include blocks nobody is sent: out of view, air, underground) and saves it on unloading. 8 s keeps what the flight is still using (the active and send ranges refresh the timer).
active2Blocks within active_block_range (default 4: 9^3 = 729 blocks) are loaded from the database and kept alive for ABMs and mobs; 2 is 5^3 = 125 (Luanti's own Android default).
gen3Generate no further than 3 blocks (48 nodes) from the player; blocks beyond that are sent only when they already exist (chunks generated whole still reach ~4 blocks further). Far terrain appears later or only as the player comes closer: watch for gaps at the edge of the view.
ioSave less often and without a full fsync per commit (sqlite_synchronous 1 = NORMAL, Android's value, instead of FULL; map_save_interval 15 s instead of 5.3). The PS3's disk takes one command at a time, so a world save can hold up page faults.
cliunloadClient map. The client keeps every block it was sent that is within the view range of the camera (all around, not only the frustum) and the others for client_unload_unused_data_timeout (600 s) up to client_mapblock_limit (7500 blocks, "about 120 MB" says the source) or the number of blocks in a view-range sphere, whichever is larger (3600 at the default range 190, 268 at 60): a 45 s flight cannot show this, a 10 minute session can. 15 s makes the flight drop what it left behind (about 60 nodes behind after ~9 s) and so shows the saving; blocks seen again are re-sent.
leavesEvery block's mesh is kept twice: S3DVertex (36 B, 4 per quad) and u16 indices in Irrlicht's CPU buffer, and the VBO. Fancy leaves draw every face between leaf nodes; simple draws only the outer ones (Android's default). Changes the look of trees.
tradeoffsmooth_lighting asks for 26 neighbours to be re-meshed whenever a block arrives, 6 without it (performance_tradeoffs keeps the lighting and re-meshes 6; edges may be wrong for a moment).
flatlight-
nominimapThe minimap thread, its per-block copy (2 KB a block) and the mesh thread's scan for it.
view40Fewer blocks everywhere (about the square of the range): 40 and 90 around the 60 of the base.
view90-
view120-
view190-
nomergeStalls while blocks arrive. renderMap merges every mesh buffer of under 300 vertices of the visible blocks into new buffers (copy, new VBO with EHM_STREAM), cached by the exact set of buffers: while blocks arrive or the camera turns the set changes and the merge is redone, with VBOs of up to 65535 vertices (2.3 MB) created and destroyed, in a driver and memory where both are expensive. 0 turns it off (more draw calls); 100 merges only the smallest.
merge100-
meshdelayThe mesh thread sleeps this many ms after each mesh ("reduces jitter on slower clients"): leaves the two hardware threads to the renderer and the server while blocks arrive.
meshchunk2One mesh and one buffer set per 2^3 blocks: an eighth of the VBOs and draw calls, but a block arriving re-meshes eight.
noraycullOcclusion culling by raycasts in the render thread, every time the draw list is rebuilt.
profLuanti's own profiler (the F6 numbers: updateDrawList, renderMap's collecting and drawing, merged buffers and their cache hit rate, blocks drawn, mesh queue) printed every 5 s into a log file at info level on the disk ($LU_DIR, not the run directory in RAM), gzipped into the run directory as luanti-debug.txt.gz after the run. For a diagnosis, not for fps: info level logs more.
v120prof-
v120nice-
v120srv10the server dropping blocks it has not used for 10 s instead of 29 (4128 server blocks in memory at 120, about half the heap): less to swap, more blocks loaded again from the world database. luanti 0011 (ps3.1125 on) makes 10 the default: v120srv29 is its off-switch, v120old both 0010's and 0011's (the game as ps3.1123 ran it), v120srv5 a shorter timeout still
v120srv29-
v120srv5-
v120old-
v120noniceluanti 0010 (ps3.1124 on) sets nice 10 inside the engine (LU_NICE, default 10): v120nonice is the game as before it, the off-switch for the same-boot A/B
v120mesh2two mesh threads instead of one (Luanti's automatic count is a quarter of the CPUs, at least 1)
mallocglibc's malloc. Threads have their own arenas, and a freed block inside one stays resident: dirty garbage the kernel swaps out. The mapgen's 2-8 MB arrays, the voxel manipulator and the mesh vectors are above the 128 KB mmap threshold only until the first big free raises it (up to 32 MB); with the threshold fixed they are mmapped and returned when freed. Luanti's own malloc_trim() (porting.cpp) waits until 256 MB were freed in all. Environment only, no rebuild.
trim16Luanti's own malloc_trim() threshold (our luanti 0007, LU_TRIM_MB; 256 MB freed by default): the MEM=1 profile of 2026-10-18 had 23-28 MB free inside the arenas (18-22 MB in one thread arena), resident or swapped out (docs/MEMORY.md). Trims run in the emerge and mesh threads, not the renderer. The generic alternative for every game is run.sh MALLOC=trim (ps3-malloctrim.so).
trim64-
leanCombinations. lean: no change a player would notice (the view range and mapgen shape stay); leaner: also simple leaves, no minimap, no buffer merging, a mesh delay.
leaner-
allbatchoffOur luanti build's GL submission switches (gamedb/games/luanti/packages/luanti/patches 0004-0006, irr/include/LuGlOpt.h): all on in the base run, LU_GL=0 is the game as upstream draws it. On the host (llvmpipe, GL 2.1, the same flight) they take the GL calls from ~1180 to ~835 a frame and the buffer bytes uploaded from ~32 KB to ~16 KB a frame; each variant turns one off (or all, allbatchoff).
nodupup-
nobind-
noxform-
noptr-
nofog-
noskin-
nosky-
nomatreuse-
allog-
b16-
f44-
b16f44-
p1024-
alnull-
f32-
lin-
nosound-
menu-
freshmenuthe main menu on an empty configuration: the package's own defaults (0008 fullscreen, 0009 viewing range 60)

One table, a header row per batch (what it tested and what came out). Conditions: what a variant adds to the recipe (its environment switches) and what ran alongside (the stall recorder, a profiler); a column appears only when this game has a value in it. Rows marked invalid or not comparable say why.

What the run length means

"warm-up + 120 s" is a steady-state run, which leaves out a 60 s warm-up and measures 120 s or more; "whole run" counted everything from the start, the way runs before 2026-10-17 did.

Variant Conditions Steady fps
in the window
1% low
fps
Stalls
frames over 100 ms
fps
whole run
Build Run length ram free
MiB
vram
MiB
stall play s
seconds
longest play ms
ms
sound faults per min
faults a minute
cpu
seconds
underruns
underruns
longest ms
ms
stall disk s
seconds
stall swap s
seconds
stall reclaim s
seconds
stall gpu s
seconds
stall cpu s
seconds
Note
Suite summary 2026-10-20 · suite-summary-2026-10
Tested: Not a test run: the suite's 13 benchmarked games (15 rows, with OpenArena's two renderers and OpenTTD's two blitters) gathered with their known numbers as of October 2026, each value naming the batch or document it came from.
Result: It is the calibration of the rating formula (rules 1): the scale was tried on these numbers before any game was rated, and the GameDB calibration table is generated from it. Benchmarks never give a medal; medals come from played sessions only.
Luanti the recipe as it is 46.0 19.1 - - - warm-up + 120 s 19 63 3.5 724 0 - - - - - - - - right, no underruns
Mesa ps3.924 + kernel .874, luajit ps3.931~dev (0002), luanti ps3.1124~dev (0010, 0011 at 5 s) 2026-10-29 · 2026-10-29-luanti-shipped
Tested: The final Luanti build (0010, and 0011 at 5 s) against both patches off at viewing range 120, three rounds, plus one round with screenshots inside the measured window to check the picture.
Result: Shipped: 38 against 21 fps, 1.8 against 30.9 s of stalls per 135 s, 1% low 16.7 against 4.3. The black and grey screenshots come from the flight path passing through a mountain, the same in both builds.
What we saw

3 rounds alternating, same boot, stall recorder on, every run fullscreen 1920x1080, no interference.

  • Shipped build: 38 fps steady (38-39), 1% low 16.7, 1.8 s of stalls in 135 s (1.3-2.4), longest frame 210 ms, swap stalls 0.1 s, the game's swap at the end 49-53 MB.
  • Both off: 21 fps (19-21), 1% low 4.3, 30.9 s of stalls (30.8-35.1), longest 1409 ms, swap stalls 8.2 s, 97-105 MB of swap.
  • Pictures: the shipped build's 100 s shot shows the world (the mountain ahead, sea, sky). The 60 and 150 s shots of both builds and the old build's 100 s shot are black, and the 20 s warm-up shots grey with a black hand.
  • The flight path runs through a mountain: the camera is in rock (black) or in blocks not generated yet (grey), the same for both builds.
v120old LU_NICE=0
stall recorder at 10 ms
21 4.3 185 24 - warm-up + 120 s 11.8 83.7 30.9 1409.0 - 314.3 0 1409.0 0.9 8.2 0.5 0 21.6
v120old LU_NICE=0
stall recorder at 10 ms
screenshots in the window
20 4.0 201 23 - warm-up + 120 s 13.2 78.6 37.1 1453.0 - 311.9 0 1453.0 1.1 9.9 1.1 0 23.2
view120 stall recorder at 10 ms 38 16.7 14 41 - warm-up + 120 s 12.3 70.0 1.8 209.8 - 326.2 0 209.8 0.1 0.1 0.0 0.0 1.5
view120 stall recorder at 10 ms
screenshots in the window
34 13.1 24 38 - warm-up + 120 s 16.4 69.3 5.0 819.7 - 318.5 0 819.7 0.1 0.6 0.2 0.0 2.4
Mesa ps3.924 + kernel .874, luajit ps3.931~dev (0002), luanti ps3.1124~dev (0010, 0011 at 10 s) 2026-10-29 · 2026-10-29-luanti-srvunload
Tested: luanti 0010 with 0011 (the built-in server unloads map blocks unused for 10 s instead of 29) against the game as it was, against 0011 off, and against a 5 s timeout; three rounds at viewing range 120.
Result: Both patches together took the game from 21 to 34 fps and its stalls from 31.6 to 3.8 s per 135 s. A 5 s timeout was better still (38 fps, 1.2 s of stalls), so 0011's default became 5 s.
What we saw

3 rounds alternating, same boot, stall recorder on. The screenshot was moved into the warm-up at 30 s, because a capture costs 1-3 s of stalls at this load.

  • Both on (10 s): 34 fps steady, 1% low 13.2, 3.8 s of stalls in 135 s (3.3-4.4), longest frame 230-800 ms.
  • Both off (the game as ps3.1123 ran it): 21 fps, 1% low 4.7, 31.6 s of stalls (26.7-35.0), longest up to 2.8 s.
  • 0011 off (29 s): 31 fps, 1% low 9.0, 9.1-9.6 s of stalls. One run left out: a system service ran during it.
  • 5 s timeout: 38 fps, 1% low 16.9, 1.2 s of stalls (1.1-2.2), swap stalls 0.1 s.
  • The game's swap at the end: 50-56 MB at 5 and 10 s against 80-101 MB at 29 s.
  • Every run fullscreen 1920x1080, the world drawn in every screenshot, no input or SSH interference.
v120old LU_NICE=0
stall recorder at 10 ms
21 4.7 175 25 - warm-up + 120 s 10.6 80.8 31.6 1426.0 - 310.4 0 1426.0 0.6 7.5 0.4 0.0 21.7
v120srv29 stall recorder at 10 ms 31.0 8.9 56.0 35.5 - warm-up + 120 s 11.3 81.9 9.3 784.1 - 312.9 0.0 784.1 0.4 2.4 0.3 0.1 6.0
v120srv5 stall recorder at 10 ms 38 16.9 8 40 - warm-up + 120 s 14.2 70.4 1.2 345.2 - 327.7 0 345.2 0.1 0.1 0.0 0.0 1.0
view120 stall recorder at 10 ms 34 13.2 25 37 - warm-up + 120 s 12.4 74.2 3.8 236.2 - 322.6 0 236.2 0.0 0.5 0.1 0 2.6
Mesa ps3.924 + kernel .874, luajit ps3.931~dev (0002), luanti ps3.1124~dev (0010: background threads at nice 10) 2026-10-29 · 2026-10-29-luanti-nice
Tested: luanti 0010 (the engine itself puts its background threads at nice 10) against the switch off, plus two variants: two mesh threads, and the built-in server unloading map blocks after 10 s instead of 29; three rounds at viewing range 120.
Result: 0010 matches the outside renice: 30 against 20 fps and 10.7 against 30.1 s of stalls. Two mesh threads are worse. Unloading blocks after 10 s was the best (35 fps, 5.3 s of stalls, less swap) and became patch 0011.
What we saw

3 rounds alternating, same boot, stall recorder on, every run fullscreen 1920x1080, no interference, the world drawn in every 100 s screenshot.

  • With 0010: 30 fps steady (27-31), 1% low 8.5, 10.7 s of stalls in 135 s, longest frame 516 ms. The threads showed nice 10.
  • Without it: 20 fps, 1% low 4.2, 30.1 s of stalls, longest 1218 ms.
  • Two mesh threads: worse, 28 fps and 12.8 s of stalls.
  • Server unloading after 10 s: the best. 35 fps (34-35), 1% low 11.1, 5.3 s of stalls (3.5-6.2), swap stalls 0.7 against 2.1 s, lowest free memory 14.6 against 11.0 MB, the game's swap at the end 57-65 MB against 77-105.
v120mesh2 stall recorder at 10 ms
screenshots in the window
28 7.1 78 31 - warm-up + 120 s 12.0 80.8 12.8 795.9 - 309.6 0 795.9 0.2 2.8 0.0 0.0 9.4
v120nonice LU_NICE=0
stall recorder at 10 ms
screenshots in the window
20 4.2 177 23 - warm-up + 120 s 11.6 83.8 30.1 1218.0 - 312.8 0 1218.0 0.4 5.8 0.5 0.0 22.3
v120srv10 stall recorder at 10 ms
screenshots in the window
35 11.1 33 38 - warm-up + 120 s 14.3 71.6 5.3 546.4 - 320.9 0 546.4 0.1 0.7 0.3 0.0 3.4
view120 stall recorder at 10 ms
screenshots in the window
30 8.5 65 34 - warm-up + 120 s 10.7 80.4 10.7 516.4 - 306.3 0 516.4 0.2 2.1 0.9 0.0 7.3
Mesa ps3.924 + kernel .874, luajit ps3.931~dev (0002), luanti ps3.1123, background threads reniced 2026-10-29 · 2026-10-29-luanti-renice
Tested: Why Luanti stalls at viewing range 120: two profiled runs to see which threads hold the CPU in the stall frames, then the background threads lowered to nice 10 from outside against the plain game, three runs each.
Result: The main thread was starved: it ran only 22% of its stall frames while the mesh, map generation and server threads and the kernel's swapper held the two PPE threads. Lowering those threads' priority took the game from 20 to 30 fps and its stalls from 35.1 to 10.2 s per 135 s; this went into the engine next as luanti 0010.
What we saw
  • Two profiled runs first (their fps don't count). In the 55.9 s of stall frames the main thread was on the CPU only 22% of the time (46% in the other frames). MeshUpdate (28%), the kernel's swapper kswapd0 (27%), Emerge-0 (25%) and Server (14%) held the two PPE threads.
  • The server held 4128 map blocks; malloc had 152-177 MB in use.
  • Plain against background threads at nice 10, 3 runs each, alternating: 20 against 30 fps steady, 1% low 4.1 against 8.4, 35.1 against 10.2 s of stalls in 135 s, longest frame 1937 against 811 ms, swap stalls 9.3 against 2.1 s.
  • Every run fullscreen 1920x1080, no interference, only system services running beforehand.
  • The world was drawn in every screenshot. The one black frame (seen in the previous batch too) is most likely the camera inside the mountain the flight path crosses: Luanti blacks out the screen when the camera is inside a solid block.
v120nice stall recorder at 10 ms
screenshots in the window
30 8.4 66 34 - warm-up + 120 s 10.8 79.3 10.2 811.3 - 313.4 0 811.3 0.2 2.1 0.0 0 8.1
v120prof stall recorder at 10 ms
perf recording
screenshots in the window
14 2.1 242 19 - warm-up + 120 s 18.9 79.0 58.7 2669.0 - 299.9 0 2669.0 1.4 17.3 11.1 0 25.5
view120 stall recorder at 10 ms
perf recording
screenshots in the window
14 3.2 307 17 - warm-up + 120 s 15.2 80.5 55.9 2017.0 - 298.8 0 2017.0 0.7 16.8 0.2 0 36.7
view120 stall recorder at 10 ms
screenshots in the window
20 4.1 183 23 - warm-up + 120 s 11.0 83.6 35.1 1937.0 - 309.2 0 1937.0 0.7 9.3 0.2 0 23.3
Mesa ps3.924 + kernel .874, luajit ps3.931~dev (0002), luanti ps3.1025 2026-10-29 · 2026-10-29-luanti-view120
Tested: Luanti at viewing range 120, the lowest the user accepts, against 60: three runs at 120 and one at 60, as the starting point for the smoothness work.
Result: 120 gives 20 fps with 36 s of long frames in 135 s, against 46 fps and 4.5 s at 60. The package's default became 120 (patch 0009), and the stall work started from these numbers.
What we saw

Same boot, stall recorder on, every run fullscreen 1920x1080, no interference, only system services running beforehand.

  • Viewing range 120: 20 fps steady (19-20), 1% low 4.0 (3.9-4.3), 36 s of frames over 100 ms in the 135 s window (35.7-41.0), longest frame 1.0-3.8 s.
  • Viewing range 60: 46 fps, 1% low 16.8, 4.5 s of stalls, longest frame 500 ms.
  • One 120 run showed a black world with only the HUD at its 100 s screenshot, read then as meshes not caught up. The next batch traced such frames to the camera passing through a mountain.
base stall recorder at 10 ms
screenshots in the window
46 16.8 30 47 - warm-up + 120 s 11.7 61.1 4.5 500.5 - 254.8 0 500.5 0.2 0.1 1.0 0 2.9
view120 stall recorder at 10 ms
screenshots in the window
20 4.0 203 24 - warm-up + 120 s 12.3 81.4 36.2 1602.0 - 309.0 0 1602.0 0.5 9.4 0.4 0.0 25.4
Mesa ps3.924 + kernel .874, luajit ps3.931~dev (0002) 2026-10-28 · 2026-10-28-luanti-view190
Tested: How Luanti runs at its own default viewing range of 190 against the benchmark's 60, one run each; the played session of 2026-10-24 had used 190.
Result: Far worse at 190: 15 fps with 56 s of long frames in 135 s, against 46 fps and 2.3 s at 60. The package's default became 60 on these numbers (later raised to 120, the user's floor).
What we saw

One run each, same boot, stall recorder on.

  • Viewing range 190: 15 fps steady, 1% low 3.0, 56 s of frames over 100 ms in the 135 s window (318 stalls, the main thread on the CPU, swapping through the VRAM), 129 MB resident, 93 MB VRAM.
  • Viewing range 60: 46 fps, 1% low 18, 2.3 s of stalls, 118 MB resident, 62 MB VRAM.
base stall recorder at 10 ms 46 18.0 14 46 - warm-up + 120 s 21.2 61.0 2.3 272.8 - 249.4 0 272.8 0.1 0.1 0.0 0 2.0
view190 stall recorder at 10 ms 15 3.0 318 18 - warm-up + 120 s 10.6 90.5 55.8 641.8 - 311.9 0 641.8 0.5 13.2 0.2 0 41.0
RT mixer: RTPRIO=10 against RTPRIO=0 (OpenAL's mixer on SCHED_RR) on OpenArena, Yamagi Quake II and Luanti base x3 (kernel .874) 2026-10-28 · 2026-10-28-rtprio-openal
Tested: Whether letting OpenAL's mixer thread run at real-time priority (SCHED_RR, allowed by a priority limit of 10) prevents sound dropouts in OpenArena, Yamagi Quake II and Luanti, three rounds.
Result: No gain: there were no audible dropouts with or without it, and it cost a little frame rate. Not shipped.
What we saw

18 runs, rounds alternating the order, none interfered. Every run fullscreen at 1920x1080, with a screenshot 40 s after the load.

  • No audible dropout in either arm. Inaudible gaps: 4 without the limit (Luanti 3, up to 102 ms; Yamagi 1, 67 ms), 1 with it (Yamagi, 7 ms).
  • OpenArena, without against with: 68.55 against 68.3 fps steady, 1% low 37.5 against 36.6.
  • Yamagi Quake II: 86.8 against 86.3 fps (the ranges don't overlap).
  • Luanti: 46 against 45 fps (HUD), 1% low 19.8 against 20.9, stall time 4.1 against 2.6 s.
  • 20 live runs outside the harness (OpenArena and Quake III with bots) agree: no gain, a small fps cost.
  • Extreme Tux Racer and Armagetron were left out: their recipes need a virtual input device that was not installed (the runs sat in menus), and neither plays through OpenAL.
base real-time priority 0 46 19.8 10 47 - warm-up + 120 s - - 4.1 1764.0 - 254.9 0 1764.0 - - - - -
base real-time priority 10 45 20.9 8 46 - warm-up + 120 s - - 2.6 1022.0 - 252.1 0 1022.0 - - - - -
batch ssdroot8 Mesa 0038 force-DXT on the rest of the suite: Luanti and ClassiCube off/opaque/opaque+NEAREST, OpenArena gl2min and gl2min_tc0 off/opaque, SuperTuxKart lean opaque/all (SSD root .472 Mesa ps3.545~dev) 2026-10-20 · 2026-10-20-ssdroot8-force-dxt
Tested: Whether Mesa 0038's forced texture compression (opaque textures to DXT1, or every texture with 'all') saves VRAM in the rest of the suite: Luanti, ClassiCube, OpenArena and SuperTuxKart.
Result: Only SuperTuxKart with 'all' changed anything: 182 textures went to DXT5 and peak VRAM fell from 95.5 to 58.1 MiB (-39%) at the same frame rate, with no difference visible on the webcam. The other games compressed nothing, because their uploads are empty textures filled later, small, or in formats the switch skips. No decision recorded; the user has the last word on the picture.
What we saw

24 runs, compression statistics on in every arm, none interfered, webcam picture right in all.

  • Luanti: nothing compressed (every upload is an empty texture filled later). Peak VRAM 62.4 MiB off, 60.9 opaque, 61.9 opaque with nearest filtering; 46.5, 46.0 and 46.0 fps; stalls 3.3, 3.3 and 3.9 s; load about 25 s. Equal within the noise.
  • ClassiCube: nothing compressed (textures under 64 px, or kept for nearest filtering or alpha). VRAM 60.1 MiB in every arm, 47.2-47.3 fps, no stalls.
  • OpenArena opengl2: nothing compressed (formats the switch doesn't take). 61.8 fps off against 62.1 opaque, VRAM 114-117 MiB in both. With the game's own compression off, still nothing: 58.6 against 58.9 fps at 145-149 MiB.
  • SuperTuxKart: opaque compresses nothing again (the game already compresses its opaque textures). 'all' takes 182 textures to DXT5 (52-53 MB sent as 13 MB).
  • SuperTuxKart, opaque against all: peak VRAM 95.5 against 58.1 MiB (-37 MiB, -39%), 20 against 20.5 fps, 1% low 11.3 against 11.4, stalls 1.8 against 1.4 s, load 28.1 against 28.4 s. Free RAM 26-32 MiB in both: the saving is VRAM, not RAM.
  • Picture: SuperTuxKart's photos with 'all' show the same track and kart, with no blockiness at the webcam's resolution. DXT5's loss on fine detail can't be judged by a webcam.
  • OpenAL wedged in 9 of the 24 runs, in off arms too, without changing their fps.
base stall recorder at 10 ms
switch force_dxt_stats50
46.5 17.4 17.5 46.5 Kernel ps3.472, Mesa ps3.545~dev warm-up + 120 s 23.2 62.4 3.2 370.9 - 245.7 0.0 370.9 0.1 0.2 1.4 0.0 1.5
base stall recorder at 10 ms
switch force_dxtopaque_force_dxt_nearest1_force_dxt_stats50
46.0 16.4 20.5 46.5 Kernel ps3.472, Mesa ps3.545~dev warm-up + 120 s 23.0 62.0 3.9 486.9 - 241.9 0.0 486.9 0.2 0.5 1.3 0.0 1.8
base stall recorder at 10 ms
switch force_dxtopaque_force_dxt_stats50
46.0 17.1 17.5 46.5 Kernel ps3.472, Mesa ps3.545~dev warm-up + 120 s 21.1 60.9 3.3 459.3 - 243.0 0.0 459.3 0.1 0.2 1.5 0.0 1.4
batch ssdroot2 P1b: gameplay profiles on the SSD root (PERF=1 MEM=1 x1) 2026-10-19 · 2026-10-19-ssdroot2-gameplay-profiles
Tested: Where the CPU goes during play in seven games on the SSD root, profiled with perf over the measured window.
Result: Mesa is the biggest share in BananaBread (62.8%) and ClassiCube, the game itself in SuperTuxKart, OpenArena and Luanti, and OpenTTD spends half its time in the kernel. Profiled runs, not for frame rates; OpenTTD was profiled at its title screen, not in play.
What we saw
  • Same boot, one run per game, perf at 499 Hz over the window. Profiled runs are for profiles, not fps (OpenArena 56 against 60 unprofiled).
  • Share of the game process's samples:
  • BananaBread: Mesa 62.8%, the GPU kernel driver 4.8, the game 10.5.
  • ClassiCube: Mesa 41.2, kernel 20.1, the GPU kernel driver 7.1.
  • SuperTuxKart: the game 36.5, Mesa 35.5, libc 15.1.
  • OpenArena: the game 27.6, Mesa 23.1, other 20.4 (OpenAL 12.4, libdeflate 3.9).
  • Luanti: the game 47.2 (its mesh-update thread 20.7% of all samples), Mesa 14.6, libc 13.7.
  • dsda-doom: Mesa 22.3, the game 20.5, audio 30 (FluidSynth 15, libspeq 12).
  • OpenTTD: kernel 49.5 (36.7 replaying deferred interrupts, 8.3 page table invalidation, 5.1 clearing GPU memory mappings when buffers are created), audio 17. It ran at its title screen (a menu, not gameplay: 18 fps, 4172 underruns).
  • Mesa has no symbols in these profiles (to be resolved on the PC later). SuperTuxKart's fps is the HUD's.

not comparable gameplay profiles (PERF=1 MEM=1), slower than plain runs.
base
not comparable
perf recording 46 15.7 24 46 - warm-up + 120 s 18.2 61.1 5.2 491.3 - 253.3 0 491.3 - - - - -
batch ssdroot2 P1a: start-up profiles on the SSD root (PERF_LOAD=1 STALLS=1 x1) 2026-10-19 · 2026-10-19-ssdroot2-startup-profiles
Tested: Where the start-up time goes now that the system runs from the SSD: one profiled start of each of five games, from a cold cache.
Result: Loads are 39-61% shorter than on USB and are now mostly CPU work on the main thread (47-77%), with the disk only 13-26%. The biggest remaining costs are named per game (map inflate, PNG and zlib decoding, Luanti's map generation). Profiled runs, not for frame rates.
What we saw
  • Same boot as the SSD baseline, cold page cache, one run per game.
  • Time to the end of the loading screens, against the USB profiles of batch 17: BananaBread 7.7 s (19.8), OpenArena 14.2 (28.1), Luanti 26.1 (43.1), SuperTuxKart 31.5 (54.3), ClassiCube 7.5 (13.9). That is -39 to -61%.
  • The main thread's disk wait in the load fell from 4.8-18.6 s to 1.0-3.2 s (BananaBread 1.9, OpenArena 2.1, Luanti 3.0, SuperTuxKart 3.2, ClassiCube 1.0).
  • The main thread's CPU stayed about the same (BananaBread 3.9 s against 4.1, OpenArena 8.7 against 9.0, SuperTuxKart 23.8 against 22.5, ClassiCube 3.2 against 2.9).
  • So loads are now 47-77% CPU on the main thread, not fully CPU-bound: disk 13-26%, the rest GPU, memory reclaim, waiting to run and sleeps.
  • Biggest costs now: BananaBread zlib 1.6 s (inflating the map); OpenArena the game's own load path 3.9 s (shader scripts, mipmaps); Luanti map generation 8.6 s plus a 15 s hold; SuperTuxKart PNG 4.2, zlib 3.9, audio 2.2 and JPEG 2.1 s; ClassiCube the game 1.5 s and the dynamic linker 0.6 s.
  • Profiled runs are for profiles, not fps.

not comparable start-up profiles (PERF_LOAD=1 STALLS=1), slower than plain runs.
base
not comparable
stall recorder at 10 ms
start-up profile
46 20.5 9 46 - warm-up + 120 s 18.4 63.4 2.3 541.2 - 253.3 0 541.2 0.2 0.4 1.1 0 0.7
batch ssdroot1+2 A: baseline on the SSD root (kernel .472 Mesa .476 ps3rsx 0.443 ps3-gpu-tools 0.477~dev) 2026-10-19 · 2026-10-19-ssdroot1-baseline
Tested: A new baseline with the whole system running from the internal SSD instead of a USB disk, on five games, to see what it does to loads, stalls and frame rates. This console has an upgraded SSD; a stock PS3 has a hard disk.
Result: Loads are 35-58% shorter (BananaBread 16.9 to 7.1 s, SuperTuxKart 53.6 to 31.1 s) and BananaBread's gameplay stalls almost vanish, while frame rates stay about the same apart from OpenArena (55.9 to 60.4). It also showed SuperTuxKart's own "Average FPS" is its physics tick rate, so its fps is taken from the HUD from here on.
What we saw
  • Same boot, kernel 6.12.111+ps3.472, root on the internal SSD (an upgraded SSD; a stock PS3 has a hard disk).
  • 5 of 17 runs left out as interfered (SSH logins, a key press, a polling loop at the batch switch).
  • Load against the USB root (other boots, older Mesa for some games): BananaBread 7.1 s against 16.9, OpenArena 6.9 against 10.7, Luanti 25.0 against 40.8, SuperTuxKart 31.1 against 53.6, ClassiCube 7.6 against 14.2.
  • The load's disk wait: 1.3-3.4 s against 5.5-10.9 s.
  • Gameplay stalls: BananaBread 0.05 s against 1.6, OpenArena 0.2 against 0.3, Luanti 3.5 against 2.5 (memory reclaim 1.6 s against 0.4), SuperTuxKart 0.2 s (one run).
  • Steady fps about the same: BananaBread 39.1 against 38.5, Luanti 46 against 46, SuperTuxKart 22 (HUD) against 20, ClassiCube 48.1 against 45.9 (falling to 46.1 later in the session with nothing changed). OpenArena gained: 60.4 against 55.9.
  • SuperTuxKart's own 'Average FPS' (105-111) is its physics tick rate (120 Hz for 180 s, 21602 ticks in every run), not rendered frames. Its fps cells are the HUD median from now on.
  • Photos show the right scenes. Luanti's photos at 60 and 150 s fall on the flight path's turn over the sea (cyan, no terrain), because the load is shorter than on USB: not a missing world.
  • Microphone: OpenArena audible; the other games mostly at the room-hum level.
base stall recorder at 10 ms 46 19.1 11 46 Kernel ps3.472, Mesa ps3.476, ps3rsx 0.443 warm-up + 120 s 19.0 61.5 3.5 724.1 - 247.2 0 724.1 0.3 0.2 1.6 0 0.9
batch 17: ETR uncapped, start-up profiles x5, shader cache cold/warm, OpenArena gl2 memory variants, Mesa sysmem switches, Sauerbraten shortnormals 2026-10-18 · 2026-10-18-batch17
Tested: A mixed batch: ioquake3 462's new colour path and memory variants for OpenArena's OpenGL 2 renderer, Mesa's system-memory copy switches, BananaBread's short normals, a warm shader cache, Extreme Tux Racer without a frame cap, and start-up profiles.
Result: ioquake3 462 cuts OpenArena's stalls from 9-11 s to 0.7-2.6 s at 57-60 fps, Mesa's system-memory switches fix the old colour path's stalls, and BananaBread's short normals give +17%. The shader cache gives no faster loads and Extreme Tux Racer's 59 fps is not a vsync cap.
What we saw
  • Same boot as batch 16 (kernel .433), ioquake3 462, Mesa 442~dev, cube2 442~dev. One BananaBread run with a key press left out.
  • OpenArena OpenGL 2 on ioquake3 462 (compact colours by default): steady 57-60 fps, stalls 0.7-2.6 s. On the 396 build in batch 16: 51-53 fps and 9-11 s.
  • The old 16-bit colour path: 52-53 fps, 12.9 s of stalls, 20 s of swap stalls.
  • Packed animated model frames: 20 MB less VRAM, same stalls. Gamma-correct mipmaps computed per channel: the lowest stalls (0.7-0.9 s).
  • Mesa's system-memory copy plus buffer invalidation on the old colour path: stalls 9.9 and 12.3 s to 1.5 and 1.4 s, swap stalls 20-26 s to 0.6-1.1 s, steady 53-54 to 59 fps.
  • BananaBread with short normals: 38.7 to 45.4 fps (+17%), stalls equal, VRAM +4 MB.
  • Shader cache cold against warm: no load gain (OpenArena 10.3 s cold, 10.6 s warm; BananaBread 17.4 against 18.4 s).
  • Extreme Tux Racer without a frame cap: still 59 fps, so not a vsync cap.
base stall recorder at 10 ms
start-up profile
47 17.8 16 46 - warm-up + 120 s 16.9 61.3 2.9 445.3 - 245.9 0 445.3 0.6 0.1 0.3 0.0 1.5
batch 16: game prefetch A/B, idle fix on/off (433), ClassiCube chunks1, X-Moto stream, Luanti lean parts 2026-10-18 · 2026-10-18-batch16
Tested: Several checks on kernel .433: a game-data prefetch, the idle-CPU fix on and off, ClassiCube's chunk setting, X-Moto's streaming draw path, and the parts of Luanti's lean settings one at a time.
Result: The prefetch gives no gain and makes Luanti worse, so it was turned off by default. The idle fix is confirmed clean (gameplay stalls 0.4 s against 8-9 s); ClassiCube's chunk setting gains 4.7% and X-Moto's streaming 1%. Luanti's chunk size 3 is what empties the world in lean.
What we saw
  • Same boot, kernel .433 with the idle fix and no kicker, interference detector on (3 runs disturbed by SSH logins left out).
  • Prefetch against none, three runs each: no gain. BananaBread load 18.1-18.6 s against 15.2-18.8; OpenArena OpenGL 2 about 0.5 s faster; Luanti worse (load +1-4 s, two runs with 3 s hitches). Default turned off.
  • Idle fix on and off, two runs each: gameplay stall time 0.4 and 0.4 s against 9.0 and 7.9 s, longest frame 0.22-0.38 s against 2.2-2.8 s. Clean.
  • ClassiCube's alternative chunk drawing: 48.1 fps against 46.0 (+4.7%).
  • X-Moto with its streaming draw path: 162.1 against 160.6 (+1%).
  • Luanti with chunk size 3 renders a black void at 150 s: it is the part of lean that empties the world. Server unloading and active block range 2 render, but stall more (6.3 and 6.7 s against about 2.5).
base stall recorder at 10 ms 46 17.5 16 47 - warm-up + 120 s 16.8 62.6 2.5 357.7 - 247.0 0 357.7 0.5 0.2 0.4 0.0 1.1
base stall recorder at 10 ms
switch gpffetch
46 20.0 13 47 - warm-up + 120 s 17.3 61.9 5.5 3089.0 - 247.3 0 3089.0 2.6 0.4 0.6 0.0 0.6
active2 the recipe as it is 46 18.1 14 46 - warm-up + 120 s 17.8 59.7 6.7 2142.0 - 241.6 0 2142.0 - - - - -
chunk3 the recipe as it is 45 21.9 7 44 - warm-up + 120 s 18.1 65.7 1.2 225.6 - 266.2 0 225.6 - - - - -
srvunload the recipe as it is 45 17.6 25 45 - warm-up + 120 s 12.6 59.9 6.3 1025.0 - 279.6 0 1025.0 - - - - -
Luanti ps3.405 clean re-runs (interference detector, kernel 433, kick) 2026-10-18 · 2026-10-18-luanti-clean-reruns
Tested: Clean re-runs of Luanti's base, client-unloading and lean variants, with the new interference detector, after the earlier runs were found disturbed by someone playing.
Result: Base stays the default. Client-side unloading is worse (worst frames over 2 s) and lean only looks faster because it draws a black void instead of the world.
What we saw
  • Two runs each, kernel .433, no interference in any run.
  • As built: stalls 1.5 and 2.1 s, longest frame 167 and 203 ms, 45-46 fps.
  • Client-side unloading: worse. Stalls 3.8 and 5.2 s, longest 2.05 and 2.08 s (unload, then reload hitches).
  • Lean: 56-57 fps, stalls 0.4 and 0.9 s, but the webcam shows a black void at 150 s in both runs (no sky, no terrain). It renders nothing, so it is not a win.
  • Base stays the default. Next: find which part of lean (server unloading, active block range 2 or chunk size 3) empties the world.
base stall recorder at 10 ms
waker kick at 10 ms
45.5 18.4 12.5 46.0 Kernel ps3.433 warm-up + 120 s 16.9 62.0 1.8 185.2 - 241.8 0.0 185.2 0.3 0.1 0.0 0.0 1.0
cliunload stall recorder at 10 ms
waker kick at 10 ms
46.0 20.1 9.5 46.5 Kernel ps3.433 warm-up + 120 s 21.0 58.5 4.5 2065.5 - 265.6 0.0 2065.5 2.4 0.1 0.3 0.0 0.6
lean stall recorder at 10 ms
waker kick at 10 ms
56.5 22.2 4.0 57.0 Kernel ps3.433 warm-up + 120 s 22.1 45.4 0.7 238.2 - 304.0 0.0 238.2 0.1 0.0 0.3 0.0 0.1
Luanti ps3.405 memory variants + ClassiCube PERF (kick, STALLS) 2026-10-18 · 2026-10-18-luanti-memory
Tested: Luanti memory variants (lean settings, a closer view range, client-side unloading and others) for fewer stalls, and ClassiCube's batching profiled.
Result: Invalid for the Luanti decisions that mattered: someone was playing during the base, lean and tradeoff runs, so those cells are void and the runs were repeated clean in a later batch. ClassiCube's batching profile shows Mesa's share falling from 57.7% to 42.8%.
What we saw
  • Same boot, one run each. Luanti gameplay stall time, longest frame and lowest free memory:
  • As built: 6.5 s, 1.9 s, 13.6 MB.
  • Lean: 0.2 s, 0.17 s, 31.5 MB, but the webcam showed missing nearby terrain at 150 s.
  • View range 40: 0.9 s, 0.36 s, 19.1 MB, 59 fps, closer fog.
  • Client-side unloading: 0.8 s, 0.26 s, 21.5 MB, same picture (looked like a default candidate).
  • Tradeoff: 6.7 s, 3.0 s. No mesh merging: 2.5 s, 0.36 s.
  • ClassiCube profiled, batching against old drawing: steady 48.4 against 50.3 fps. The game's share of samples 15.6% against 9.5%, Mesa's 42.8% against 57.7%.
  • Interference (found by the later scan): somebody played Luanti during the base run (2 digs and 4 clicks, a 1943 ms frame right after), the lean run (41 digs, 31 clicks: the 'missing terrain' was the digging and looking at the sky) and the tradeoff run (3 clicks). Those cells are invalid. View 40, client unloading, no merging and ClassiCube are clean as far as the files show.
base stall recorder at 10 ms
waker kick at 10 ms
45 16.2 24 46 - warm-up + 120 s 13.3 61.6 6.5 1943.0 - 254.0 0 1943.0 1.8 1.2 0.0 0.0 1.8
cliunload stall recorder at 10 ms
waker kick at 10 ms
48 21.6 5 48 - warm-up + 120 s 21.0 57.9 0.8 258.9 - 272.0 0 258.9 0.2 0 0.3 0.0 0.2
lean stall recorder at 10 ms
waker kick at 10 ms
54 19.9 1 54 - warm-up + 120 s 30.8 44.0 0.2 164.8 - 316.6 0 164.8 0.1 0.0 0 0 0.0
nomerge stall recorder at 10 ms
waker kick at 10 ms
46 17.1 14 47 - warm-up + 120 s 14.4 64.6 2.5 360.7 - 259.3 0 360.7 0.3 0.1 0.7 0.0 0.9
tradeoff stall recorder at 10 ms
waker kick at 10 ms
46 18.4 21 47 - warm-up + 120 s 12.6 63.5 6.7 2983.0 - 230.3 0 2983.0 2.8 0.6 1.1 0.0 1.0
view40 stall recorder at 10 ms
waker kick at 10 ms
59 29.2 5 58 - warm-up + 120 s 18.7 54.5 0.9 362.4 - 241.0 0 362.4 0.4 0.0 0.1 0.0 0.1
smoke re-runs (teeworlds ps3.422) + vm.watermark_boost_factor A/B on Luanti (kick) 2026-10-18 · 2026-10-18-smoke-reruns-watermark
Tested: Re-runs of three smoke tests (Teeworlds with a big-endian fix, Red Eclipse, SuperTux) and an A/B of a kernel memory setting (watermark boost) on Luanti's stalls.
Result: Teeworlds now runs and Red Eclipse no longer runs out of memory; SuperTux never left its title card. The kernel setting gave no clear gain and was not shipped.
What we saw
  • Same boot.
  • Teeworlds (ps3.422): in game, warm-up on the dm1 map, 183 fps. The big-endian socket fix works.
  • Red Eclipse: no out-of-memory with lean sound and textures. It stops at the first-start profile menu.
  • SuperTux: still on the title card (the virtual key press didn't arrive).
  • Luanti, watermark boost on, off, on, off: gameplay stall time 12.5, 0.8, 2.0, 2.1 s. The first run is an outlier. No clear gain, not shipped.
  • The webcam view moved (PC monitor left, PS3 right).
base waker kick at 10 ms 47.0 21.6 12.0 47.0 - warm-up + 120 s 14.2 62.3 2.0 321.5 - 247.0 0.0 321.5 - - - - -
batch 8: STK lean, OpenTTD gl, ClassiCube/dsda batching, malloc presets, profiles (Mesa ps3.408, kick) 2026-10-18 · 2026-10-18-batch8
Tested: A mixed batch: SuperTuxKart's lean settings, OpenTTD's OpenGL driver, draw batching in ClassiCube and dsda-doom, memory allocator presets, and profiles of OpenArena and Luanti.
Result: SuperTuxKart lean runs 21.4 fps against 13 with far fewer stalls, OpenTTD's GL driver doubles its frame rate, dsda-doom's batching gains 3% while ClassiCube's loses 4%, and the allocator presets were noise. One Luanti profiling run was disturbed by a mouse click.
What we saw
  • Same boot.
  • SuperTuxKart: the track draws (webcam). Lean settings 21.4 fps smooth against 13 as built, stalls 2.4 against 13.5 s.
  • OpenTTD with the GL driver: right picture, 21 fps (8-12 with software drawing).
  • ClassiCube with batching 47.3 fps against 49.4 with the old drawing (-4%), but 1% low 31 against 27.6.
  • dsda-doom GL renderer with batching 55.9 against 54.2 (+3%), 1% low 40.8 against 36.5.
  • Memory allocator presets: inconsistent between rounds (noise).
  • OpenArena OpenGL 2 renderer: 55 s of stalls, longest 16 s, 66 MB swapped out. Luanti: 10 s of stalls, 51 MB swapped out.
  • Interference (found by the later scan): the profiled Luanti run had a right click in its measured window, so distrust that cell.
base waker kick at 10 ms
perf recording
46 15.4 31 47 Mesa ps3.408 warm-up + 120 s 20.6 61.6 10.4 2763.0 - 246.5 0 2763.0 - - - - -
Mesa ps3.407 NV30_TRANSLATE_LUT, yquake2 ps3.408 kiss4k, luanti ps3.405 trim16 (all with WAKER kick) 2026-10-18 · 2026-10-18-mesa-407-lut
Tested: Three changes: Mesa ps3.407's lookup table for 8-bit vertex attributes on BananaBread, Yamagi Quake II's memory cut (kiss4k) and Luanti's trim16 setting.
Result: The lookup table speeds BananaBread up by 53%, and Yamagi's memory cut ends its stalls (22.6 s to 0.05 s). Luanti's trim16 gave no gain and more stalls, so it was rejected.
What we saw
  • Same boot, two runs each, all with the 10 ms waker kick.
  • BananaBread demo with the lookup table for 8-bit vertex attributes: steady 25.9 to 39.6 fps (+53%), 1% low 18.3 to 26.9.
  • Yamagi Quake II with kiss4k: memory in use 125 to 56 MB, swap used 80 to 9 MB, gameplay stall time 22.6 to 0.05 s, longest frame 4.5 s to 91 ms, steady 65.7 to 68.7 fps.
  • Luanti trim16: no gain and more stalls (3.35 to 8.6 s). Rejected.
  • Pictures right on the webcam.
base waker kick at 10 ms 47.0 20.3 15.5 47.5 Mesa ps3.407 warm-up + 120 s 15.8 62.9 3.4 425.4 - 250.7 0.0 425.4 - - - - -
trim16 LU_TRIM_MB=16
waker kick at 10 ms
47.5 20.6 11.0 48.0 Mesa ps3.407 warm-up + 120 s 15.9 61.0 8.6 3648.0 - 246.1 0.0 3648.0 - - - - -
Luanti ps3.364 batching, Neverball ps3.370 batching, Sauerbraten libspeq 0.381 skinning (spawn) 2026-10-17 · 2026-10-17-luanti-neverball-batching
Tested: Draw batching in our Luanti (ps3.364) and Neverball (ps3.370) packages against the old drawing, and BananaBread's model skinning on the SPUs, on the PPE through libspeq, or off (libspeq 0.381).
Result: Batching gives Luanti fewer stalls and shorter worst frames, and cuts Neverball's CPU from 80 to 65 s at the same frame rate. For BananaBread libspeq's PPE skinning is best; the SPU path adds hitches. One Luanti batching-off run was later found disturbed by input.
What we saw
  • Same boot.
  • Luanti, batching on against off, two runs each: steady 45.0 against 46.0 fps, stall time 6.25 against 9.1 s, longest frame 1.7 against 3.4 s, no underruns, picture right.
  • Neverball, batching on against old drawing: smooth 78.7 against 79.1 fps, CPU 65 against 80 s, stalls similar. One batched run ended before the measured window (12 demo loops were too few; now 20).
  • BananaBread (spawn point with the gun), one run each: skinning on the SPUs 23.6 fps steady with 21 stalls (4.3 s); on the PPE 28.1 fps with no stalls; off 23.0 with no stalls. libspeq's PPE path is the best; the SPU path adds hitches.
  • Interference (found by the later scan): one Luanti batching-off run had three digs (a mouse button in the game) in its warm-up. The measured window had no logged action, but the batching-off cell includes that run.
base the recipe as it is 45.0 18.9 20.0 45.5 - warm-up + 120 s 15.1 62.5 - - - 246.1 0.0 1685.1 - - - - -
allbatchoff LU_GL=0 46.0 17.5 26.5 46.0 - warm-up + 120 s 16.8 61.5 - - - 241.6 0.0 3415.0 - - - - -
Mesa ps3.262 OpenAL log variants (allog; perf recording) 2026-10-17 · 2026-10-17-mesa-262-allog
Tested: How much of the CPU OpenAL's sound mixing takes in four games, profiled with perf, to see whether moving the mixer to the SPUs would pay off.
Result: OpenAL itself is 3.7-4.7% of the game's CPU samples, under the 6% bar set for an SPU mixer. The frame rates are slowed by the profiler and are not for comparison.
What we saw
  • OpenArena, Yamagi Quake II, Luanti and ClassiCube with stock OpenAL settings and OpenAL's log on, perf recording for 20 s from the sound start. One run each.
  • The profiler slows the games: OpenArena 46.2 fps, Yamagi 32.1 (63.9 unprofiled), ClassiCube 45.6, Luanti 58 (HUD). Not for comparison.
  • OpenAL itself is 4.7% of OpenArena's process samples and 3.7% of ClassiCube's: under the 6% bar for an SPU mixer.
  • The sound device was stereo float32 at 48000 Hz (OpenAL's ALSA path).
  • No underruns except in Yamagi (14).

not comparable OpenAL logging runs with perf recording, slower than plain runs.
allog
not comparable
the recipe as it is - - - 58 Mesa ps3.262 whole run 21.0 53.0 - - - 115.7 0 - - - - - -
Mesa ps3.262 + ps3rsx 0.249 2026-10-17 · 2026-10-17-mesa-262
Tested: Mesa ps3.262 (patches 0019 to 0025: fewer words sent to the GPU per draw) across the suite, against ps3.246.
Result: Big gains in several games: OpenArena +23%, Yamagi +24%, X-Moto +21%, Extreme Tux Racer and dsda-doom +15%. Armagetron fell from 60 to 51 fps, which the next batches traced. Single runs; BananaBread's drop is a memory stall, not a driver number.
What we saw
  • The patches: no relocations, the texture cache invalidated only after texture changes, no duplicate vertex-format writes, batched vertex program constants. One run per game.
  • Against ps3.246: OpenArena with compressed textures 44.2 to 54.4 fps (+23%), Yamagi 51.4 to 63.9 (+24%), X-Moto 39 to 47 (+21%), Extreme Tux Racer 46 to 53 (+15%), dsda-doom software 33 to 38 with the demo now finishing (+15%), ClassiCube 47.6 to 50.1 (+5%).
  • Neverball 78.2 to 71.5 (noise), QuakeSpasm 70.5 to 66.3 (repeated in the next batch), Luanti 53 to 53.
  • Armagetron dropped from 60 to 51 (driver frame counter).
  • BananaBread reads 28 to 8 on the counter, but it was memory-stalled (13 MB free, killed at the cap): not a driver number, and the cause is uncertain.
  • The kernel's command validator rejected nothing.
  • Single runs.
base the recipe as it is - - - 53 Mesa ps3.262, ps3rsx 0.249 whole run 16.7 52.4 - - - 117.2 0 - - - - - -
Mesa ps3.246 + ps3rsx 0.249 2026-10-17 · 2026-10-17-mesa-246-ps3rsx-249
Tested: The first full suite round after the reboot into ps3rsx 0.249, one run per game, as a baseline.
Result: Every game ran with the right picture. The sound was right except in dsda-doom (MIDI music), BananaBread and OpenTTD. Single runs, so differences of a few fps are noise.
What we saw
  • One run per game. Frame rates by the game's own counter, or the driver's frame counter where marked:
  • Armagetron 60 (counter), ClassiCube 47.6, dsda-doom software 33 (counter, demo unfinished), Extreme Tux Racer 46 (counter), Luanti 53 (counter), Neverball 78.2.
  • OpenArena with compressed textures 44.2 (longest frame 2.1 s), QuakeSpasm 70.5, BananaBread with CPU skinning 28 (counter), X-Moto 39 (counter), Yamagi Quake II 51.4.
  • Pictures right. Sound right except dsda-doom (1161 underruns, MIDI music), BananaBread (176) and OpenTTD (1429, choppy).
  • OpenTTD used 55.5 s of CPU and has no frame rate (plain X11 path).
  • Single runs: differences of a few fps are within the run-to-run spread.
base the recipe as it is - - - 53 Mesa ps3.246, ps3rsx 0.249 whole run 27.1 53.6 - - - 105.3 0 - - - - - -
ps3rsx 0.249 first boot (Mesa ps3.246; SDL3 ps3.254) 2026-10-17 · 2026-10-17-ps3rsx-249-first-boot
Tested: The first boot with ps3rsx 0.249 and libsdl3 ps3.254: Neverball without the wedge, OpenTTD's native upload, and the first runs of Luanti and BananaBread (the Cube 2 engine).
Result: Neverball runs without wedging (76.4 and 70.2 fps), and OpenTTD rose from about 2 to 8 fps (12 with the 8-bit blitter). Luanti and BananaBread run but are memory-bound; BananaBread's first run was killed for lack of memory.
What we saw
  • The GL tests pass and switching virtual terminals works with a GL program running (those runs aren't in the records).
  • Neverball (our +ps3.257 with its own benchmark, about 23 s) runs without the wedge: 76.4 and 70.2 fps by its own count, longest frames 320 and 378 ms, 15 and 36 underruns.
  • OpenTTD with libsdl3 ps3.254 (native BGRA upload): from about 2 to 8 fps on the driver's frame counter (9.5 across the two runs), 12 fps with the 8-bit blitter. The game's own software drawing is the limit.
  • Luanti, first run: load 37 s, 67 fps on the counter (10th percentile 23, dropping to 0 while map chunks load), free memory down to 31 MB.
  • BananaBread (CPU skinning), first runs: the first was killed by the out-of-memory killer (free memory down to 10 MB); the second reached 15 fps on the counter, 236 underruns.
  • Smoke runs, single or paired.
base the recipe as it is - - - 67 Mesa ps3.246, ps3rsx 0.249 whole run 31.4 48.9 - - - 92.3 0 - - - - - -