Played sessions
Testing is done with Walnut's rating tool (walnut-rate, on the console): how ratings are made and submitted.
Builds:
Walnut 0.1,
cube2-data 1.3-1
The platform builds under it (3)
| Linux kernel | 6.12.111+ps3.747 Walnut's build |
|---|---|
| Mesa | 26.2.4-1+ps3.721 Walnut's build |
| ps3rsx | 0.735+k6.12.111+ps3.747 Walnut's build |
| Date | Launcher | Rules | Play | Ended | Picture | |
|---|---|---|---|---|---|---|
| 2026-10-24 | Cube2:Demo | 1.0 | 3 min | quit | 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.
| Version | Tested | Medal | Rules | Frame rate | Smoothness | Sound | Picture | Stability | Display | Load | Play |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Walnut 0.1 cube2-data 1.3-1 |
2026-10-24 | Scrap · 51 | 1.0 | - | - | 96 | 100 | 90 | - | 100 | 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: BananaBread with cube2-data 1.3's maps. base: the user's recorded demo, copied to ~/.cube2/demo/bench.dmo and played with `mode -1; map bench`.
The recipe's full description
BananaBread (Debian's cube2, so this recipe is still called sauerbraten; our build: textures compressed at upload on Mesa too) with cube2-data 1.3's maps (the BananaBread content). base: the user's recorded demo (assets/sauerbraten-bench.dmo, 2026-10-17: an FFA round on cave with two bots, 93 s of game time, recorded by the local server with `recorddemo 1` and a map reload, saved with getdemo), copied to ~/.cube2/demo/bench.dmo and played with `mode -1; map bench` (demo mode on the local server, as the data's `demo` command does it: the server's setupdemoplayback reads <demodir>/bench.dmo and sends the recorded packets, so the client loads cave from them and runs `mapstart`; at the end, "demo playback finished" and the client runs `demoend`). A CubeScript (-x) counts frames (a sleep re-armed every frame, wall time from getmillis 1): each playback ("loop") prints "ps3bench: loop <k>: <n> frames in <ms> ms: <fps> fps, longest <ms> ms" at its end (fps= and maxms= are loop 1's, the whole first playback). Steady state: the window opens 60 s after the first mapstart (the map loaded) and closes at the playback's end; demoend plays the demo again (a reload, left out of the window: it reopens at the next mapstart) until the window holds ~120 s (114 s: the rest of loop 1 and loop 2), then "ps3bench: steady <n> frames in <ms> ms: <fps> fps, longest <ms> ms" and quit. The script marks the window ("ps3bench: window on/off": WIN_ON_RE, WIN_OFF_RE) so the HUD metrics use the same pieces. The bots in a demo are played back, not simulated: every run is the same. variant spawn: the method before the demo: -l loads map "cave" (its only player start, so every run looks from the same spot) and the player stands still; the script counts frames for 30 s from 10 s after the first frame and prints "ps3bench: <n> frames in <ms> ms: <fps> fps, longest <ms> ms" (fps=, maxms=), then its own steady window, 60 s after the first frame for 120 s (STEADY_RE), and quits. The view is static: one view's rendering once loading is over. The gun, towers and *skin variants use it (the hud gun and the other map only exist there). getfps itself averages only the last 60 frames. Settings go into ~/.cube2/autoexec.cfg (run after config.cfg, so the player's saved fullscreen or vsync can't override them); both files are restored after the run. Our cube2 (ps3.N, gamedb/engines/cube2/technical.md) ships the memory defaults of gamedb/engines/cube2/packages/cube2/patches: CPU skinning (gpuskel 0: GPU skinning indexes a bone array in the vertex shader, which nv30 compiles to if/else trees, 11 fps against 28; no GPU skinning shaders are built then), sky boxes and cube maps from their 256x256 .dds (skydds 1), lightmaps' CPU copies freed after upload (lmfreedata 1), dynamic light and water fade shader variants only as far as maxdynlights, waterrefract and waterfade ask. "base" is that; every variant below changes one thing (or, lean, the bundle that is meant to ship). Memory per run: during.log has MemAvailable and SwapFree every 5 s, bench.txt their lowest.
42 variants of the recipe
base stands for the game | the recipe as it is, without a variant |
|---|---|
gpuskel | GPU skinning on (the old default): shaders for it are built, the hud gun and players use them |
cpuskel | the old default spelled out (base is CPU skinning now) |
pngsky | sky and env map from the PNGs (six 2048x2048, decoded twice at load) instead of the 256x256 .dds |
keeplm | lightmaps' CPU copies kept (24 MB in cave) |
dyn5 | dynamic light shader variants: all five that the stock engine builds (maxdynlights 5 also draws five), or fewer. Lights and muzzle flashes light the world less |
dyn1 | - |
dyn0 | - |
nofade | water: no fade under the surface (no fade variants of every world shader), or no reflection and refraction at all (two extra scene passes when water is in view) |
nowater | - |
sd2 | the world shaders without specular and parallax (shaderdetail 2: no spec map; 1: no parallax either, the menu's "low detail"): fewer texture reads per pixel, fewer variants |
sd1 | - |
nobumpmdl | no normal-mapped or env-mapped models: far fewer model shader programs |
tex1 | textures dropped by a mip level (texreduce 1: a quarter of the memory of the DDS and JPG ones) or capped in size (maxtexsize also caps the sky and the lightmap textures) |
tex2 | - |
maxtex512 | - |
tc512 | compress the uncompressed textures from 512 or 256 pixels up (default 1024): water, models, particles, the HUD. Look for ragged text and HUD edges |
tc256 | - |
snd22 | sound at 22 kHz: the decoded samples are half the size |
lean | the bundle meant to ship if the single steps hold: no water passes, low-detail shaders, models without bump, one dynamic light, compressed 512 textures, 22 kHz sound |
notc | no texture compression at all (as upstream on Mesa): VRAM and load time against base |
spawn | hud gun: -l starts mode 1 (coop edit), where the player spawns with the pistol, and cube2-data 1.3 (the BananaBread content) has no pistol or fist hud gun model (models/hudguns: chaing gl rifle rocket shotg), so nothing is drawn. This switches to the grenade launcher (1 grenade at spawn) 2 s after the first frame, which adds the one skeletal model that CPU or GPU skinning has to move the method before the demo (recipe header) |
gun | - |
gungpu | the same with GPU skinning, to compare against gun |
towers | the biggest map with one player start (66 lights, an 8192 world) |
spuskin | CPU skinning through libspeq (our cube2 0006, ps3-spu's skin.spu), on the hud gun of variant gun (hands 1497 + grenade launcher 1683 vertices with tangent frames: the only skinned model on cave): on the SPEs, with libspeq's vector code on the PPE, or the engine's own loop (as before 0006). SPEQ_DEBUG=1 puts libspeq's counters in the log every 10 s and at exit (batches on the SPEs, mean and max wait, timeouts, errors); gun itself is the default, auto |
ppeskin | - |
offskin | - |
demospu | the same three on the recorded demo (base): the two bots' player models are skinned too, more work than the gun alone (the user, 2026-10-18: the spawn runs showed no demo). With sauerbraten-nonfree-data (the licensed suite) the player models and guns have their real meshes. |
demoppe | - |
demooff | - |
demo | the recorded demo: the same as base (named for the runs made before base became the demo) |
nouni | Fewer GL calls per frame (our cube2 0007-0009, each behind a cvar that is 1 by default; on cave under llvmpipe as GL 2.1 without GL_EXT_gpu_shader4, like the PS3: 1657 GL calls and 199 draws a frame with all off, 1300 and 199 with all on, with the hud gun; the same pixels). Each variant turns one off, to see what it is worth: slot and global shader uniforms sent only when their value changed (gluniformcache) |
notmu | a batch's textures bound together, right before its draw, a glActiveTexture per unit that changes (glbatchtmu) |
nopart | particle vertices uploaded by renderers that have particles only, one glBufferData each (glpartvbo) |
allbatchoff | all of them off: the drawing of ps3.315 and before |
rgbspu | DXT1 of RGB sources (libspeq 2026-10-18, packages/walnut/tools/ps3-spu/doc/dxt-rgb.md): the JPG and other alpha-less textures reach libspeq as 3 bytes a pixel ("speq: s3tc dxt1 ... comps 3" lines), which it used to encode on the PPE (165 ms for a 1024x1024, a hitch mid-game); now the SPEs take them. rgbppe sends them back to the PPE encoder (the old behaviour), rgbspu is the default with the same logging, so the pair differs in the switch alone: stall_cpu_s, load time and the "comps 3 ... spu/ppe" lines. |
rgbppe | - |
oqlag | The water's occlusion query (docs/HOTPATHS.md, target 1): drawreflections waited for this frame's result, the GPU behind (10% of the CPU spun in nv30_query_result). oqlag: our cube2 0010's oqwaterlag 1, this frame's result only if it is in, else last frame's (the first frame water shows again has its last reflection); oqnowait: the stock oqwait 0, every query not in yet counts as visible (the reflection passes then run whenever the result is late). The Mesa side is an ENVS token: NV30_QUERY_WAIT=US sleeps on the fence after US microseconds of spinning (base, pixels the same) |
oqnowait | - |
shortnormals | World normals and tangents as GL_SHORT normalized (our cube2 0011, vanormalshort; docs/MEMORY.md): nv30 can't fetch the stock GL_BYTE ones, so u_vbuf converts them at every world draw and nouveau keeps a malloc copy of every world vertex buffer to read them from. shortnormals uploads them as shorts (the RSX fetches those: no conversion, no copies; cave's world buffers 4.40 -> 5.50 MB of VRAM); off by default (on llvmpipe ~170 pixels a frame differ by 1-2 levels). bytenormals is the stock layout spelled out. With NV30_SYSMEM_STATS=300 (an ENVS token, Mesa 0037) the sysmem_* columns show the copies go |
bytenormals | - |
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. | |||||||||||||||||||||
| BananaBread | the recipe as it is | 39.1 | 25.6 | - | - | - | warm-up + 120 s | 25 | 117 | 0.1 | 103 | 40 | - | - | - | - | - | - | - | - | right, 60-181 underruns a run |
batch ssdroot11 Mesa 0044: NV30_MINMAX_VMX=1 against unset on Sauerbraten base and OpenArena gl2min x3 (SSD root .472 Mesa ps3.545~dev)
2026-10-20 · 2026-10-20-ssdroot11-minmax-vmx
Tested: Whether Mesa 0044 (the AltiVec index scan) helps or hurts games other than SuperTuxKart: BananaBread and OpenArena opengl2, three rounds. Result: Neutral in both (39.37 against 39.64 fps, 61.7 against 62.7), as their draws rarely run the scan. 0044 only pays where those loops run, in SuperTuxKart. What we saw12 runs rotated, none interfered.
| |||||||||||||||||||||
base |
stall recorder at 10 ms | 39.6 | 26.9 | 0 | 36.2 | Kernel ps3.472, Mesa ps3.545~dev | warm-up + 120 s | 23.0 | 117.0 | 0.0 | 78.2 | - | 230.4 | 141 | 78.2 | 0.0 | 0 | 0 | 0 | 0 | |
base |
stall recorder at 10 ms switch minmax_vmx1 |
39.4 | 25.7 | 1 | 36.1 | Kernel ps3.472, Mesa ps3.545~dev | warm-up + 120 s | 26.5 | 117.0 | 0.2 | 139.1 | - | 232.4 | 154 | 139.1 | 0 | 0 | 0 | 0 | 0.1 | |
batch ssdroot7 DUMPON=1 repro of the OpenAL wedge: SuperTuxKart x4 OpenArena x3 ClassiCube x3 Sauerbraten x3 (SSD root .472 Mesa ps3.545~dev)
2026-10-19 · 2026-10-19-ssdroot7-openal-wedge
Tested: How often OpenAL's sound output wedges (stops) in four games, with a full system dump taken the moment it happens, to find the cause. Result: The wedge hit 3 of 4 SuperTuxKart runs, 1 of 3 OpenArena, 1 of 3 ClassiCube and none of 3 BananaBread, as early as 21 s in. The dumps showed the sound card's DMA stopping in the kernel's snd_ps3 driver. Investigation runs: their numbers are not for comparison. What we sawInvestigation runs, not for fps: a dump freezes the game for seconds, and the dump mode itself costs (OpenArena's window was 71 s at 57 fps against 94 s at 62 fps without it). Only the 8 of 13 runs without a dump have numbers, and they are not comparable with other batches.
| |||||||||||||||||||||
base |
stall recorder at 10 ms | 39.4 | 26.3 | 1 | 36.0 | Kernel ps3.472, Mesa ps3.545~dev | warm-up + 120 s | 24.3 | 117.0 | 0.1 | 128.9 | - | 231.6 | 152 | 128.9 | 0 | 0 | 0 | 0 | 0.1 | |
batch ssdroot7 Mesa 0042: NV30_QUERY_KICK=2 and =0 against unset on Sauerbraten base x3 (SSD root .472 Mesa ps3.545~dev)
2026-10-19 · 2026-10-19-ssdroot7-query-kick
Tested: Whether Mesa 0042 (submitting a query's batch when its result is wanted instead of at its end; modes 2 and 0) cuts BananaBread's CPU time, whose water reflection query spent 5.6% there; three rounds. Result: Neutral: 39.8 and 39.6 fps against 39.4 unset, inside a 1 fps spread, and the CPU time unchanged at 231-232 s. Nothing to turn on. What we saw9 runs rotated, 3 per arm, none interfered, webcam picture right in all.
| |||||||||||||||||||||
base |
stall recorder at 10 ms | 39.4 | 26.6 | 1 | 36.2 | Kernel ps3.472, Mesa ps3.545~dev | warm-up + 120 s | 23.3 | 117.0 | 0.2 | 159.5 | - | 231.4 | 141 | 159.5 | 0.0 | 0 | 0 | 0 | 0.1 | |
base |
stall recorder at 10 ms switch query_kick0 |
39.6 | 27.1 | 1 | 36.3 | Kernel ps3.472, Mesa ps3.545~dev | warm-up + 120 s | 24.4 | 117.0 | 0.1 | 130.3 | - | 232.4 | 132 | 130.3 | 0 | 0 | 0 | 0 | 0.1 | |
base |
stall recorder at 10 ms switch query_kick2 |
39.8 | 27.1 | 1 | 36.6 | Kernel ps3.472, Mesa ps3.545~dev | warm-up + 120 s | 26.5 | 117.0 | 0.2 | 136.9 | - | 231.3 | 134 | 136.9 | 0 | 0 | 0 | 0.0 | 0.1 | |
batch ssdroot6 libpng: libpng16 1.6.59 +ps3.560 against Debian's stock on SuperTuxKart lean x3 and Sauerbraten base x3 and OpenArena gl2min x2 (SSD root .472 Mesa ps3.545~dev zlib-ng on both arms)
2026-10-19 · 2026-10-19-ssdroot6-libpng
Tested: Whether our libpng (1.6.59 +ps3.560) cuts load times against Debian's, mainly on SuperTuxKart, whose load profile showed 4 s of PNG decoding; BananaBread and OpenArena as controls, zlib-ng on in both arms. Result: Yes for SuperTuxKart: PNG decoding in the load fell from 4.0 to 1.6 s (-60%, as predicted) and the whole load from 30.3 to 27.6 s (-9%), with gameplay unchanged. Nothing measurable for BananaBread and OpenArena. Our libpng later replaced Debian's on the PS3. What we sawWebcam picture right in all runs.
| |||||||||||||||||||||
base |
stall recorder at 10 ms switch zng |
39.4 | 26.6 | 0 | 36.4 | Kernel ps3.472, Mesa ps3.545~dev | warm-up + 120 s | 25.1 | 117.0 | 0.0 | 86.7 | - | 231.6 | 123 | 86.7 | 0.0 | 0 | 0 | 0 | 0 | |
base |
stall recorder at 10 ms switch zng switch ldstock-png |
39.5 | 27.1 | 0 | 36.6 | Kernel ps3.472, Mesa ps3.545~dev | warm-up + 120 s | 21.8 | 117.0 | 0.0 | 95.3 | - | 231.8 | 113 | 95.3 | 0.0 | 0 | 0 | 0 | 0 | |
batch ssdroot5 load-time libraries: libvorbis +ps3.549 and zlib-ng against stock on SuperTuxKart lean and Sauerbraten base x3, JSIMD=none x2 (SSD root .472 Mesa ps3.544)
2026-10-19 · 2026-10-19-ssdroot5-load-libraries
Tested: Whether our libvorbis (+ps3.549) and zlib-ng shorten load times against Debian's libraries, on SuperTuxKart and BananaBread, three rounds; plus two runs with libjpeg-turbo's AltiVec code turned off to see whether it is in use. Result: Small gains on SuperTuxKart's load: 0.7 s from libvorbis and 0.9 s from zlib-ng. BananaBread's load and all frame rates were unchanged. Both libraries became defaults later (our libvorbis replaces Debian's; zlib-ng is loaded for every game), and the AltiVec test showed libjpeg-turbo's AltiVec path is in use. What we sawLoad-time profiling on, 22 runs.
| |||||||||||||||||||||
base |
stall recorder at 10 ms start-up profile |
39.1 | 25.3 | 2 | 35.2 | Kernel ps3.472, Mesa ps3.544 | warm-up + 120 s | 21.4 | 117.0 | 0.3 | 221.0 | - | 234.0 | 157 | 221.0 | 0.0 | 0 | 0.1 | 0 | 0.2 | |
base |
stall recorder at 10 ms start-up profile switch ldstock-vorbis |
39.4 | 25.9 | 2 | 34.9 | Kernel ps3.472, Mesa ps3.544 | warm-up + 120 s | 22.1 | 117.0 | 0.2 | 146.0 | - | 223.2 | 120 | 146.0 | 0 | 0 | 0 | 0 | 0.1 | |
base |
stall recorder at 10 ms start-up profile switch zng |
39.1 | 25.4 | 0 | 35.4 | Kernel ps3.472, Mesa ps3.544 | warm-up + 120 s | 23.1 | 117.0 | 0.0 | 82.8 | - | 233.7 | 165 | 82.8 | 0.0 | 0 | 0 | 0 | 0 | |
batch ssdroot2 P2: ps3rsx shadow_fast (PS3RSX_SHADOW_FAST=1 against off, STALLS=1)
2026-10-19 · 2026-10-19-ssdroot2-shadow-fast
Tested: A faster path in the ps3rsx kernel driver for copying GPU commands (shadow_fast), switched on and off on ClassiCube, BananaBread and X-Moto. Result: No gain in frame rate, stalls or CPU on any of the three games, so the switch stays off. The code it touches is only 2-6% of the CPU in the first place. What we saw
| |||||||||||||||||||||
base |
stall recorder at 10 ms | 39.2 | 25.6 | 0.5 | 36.1 | - | warm-up + 120 s | 27.5 | 117.0 | 0.1 | 95.6 | - | 233.7 | 160.0 | 95.6 | 0.1 | 0.0 | 0.0 | 0.0 | 0.1 | |
base |
stall recorder at 10 ms switch rsx_shadow_fast1 |
39.7 | 26.1 | 1.0 | 36.3 | - | warm-up + 120 s | 20.8 | 120.3 | 0.1 | 118.3 | - | 229.4 | 115.0 | 118.3 | 0.1 | 0.0 | 0.0 | 0.0 | 0.1 | |
batch ssdroot2 P2: Mesa 0038 NV30_FORCE_DXT=opaque against off (MEM=1 STALLS=1 NV30_FORCE_DXT_STATS=50)
2026-10-19 · 2026-10-19-ssdroot2-force-dxt
Tested: Mesa 0038, a switch that compresses opaque textures to DXT on upload to save VRAM, against off on BananaBread, SuperTuxKart and OpenArena. Result: In BananaBread it cuts peak VRAM from 119.8 MB (the cap) to 73-78 MB with no frame rate change and a slightly softer picture. It compresses nothing in SuperTuxKart and OpenArena, whose textures it skips, so no effect there. What we saw
| |||||||||||||||||||||
base |
stall recorder at 10 ms switch force_dxt_stats50 |
40.0 | 25.9 | 4.0 | 36.5 | - | warm-up + 120 s | 21.4 | 117.0 | 0.5 | 184.5 | - | 218.3 | 65.5 | 184.5 | 0.0 | 0.0 | 0.2 | 0.0 | 0.2 | |
base |
stall recorder at 10 ms switch force_dxtopaque_force_dxt_stats50 |
39.0 | 23.9 | 4.0 | 36.0 | - | warm-up + 120 s | 26.5 | 73.8 | 0.6 | 176.5 | - | 234.1 | 173.0 | 176.5 | 0.1 | 0.0 | 0.1 | 0.0 | 0.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
not comparable gameplay profiles (PERF=1 MEM=1), slower than plain runs. | |||||||||||||||||||||
basenot comparable |
perf recording | 38.3 | 23.5 | 3 | 36.1 | - | warm-up + 120 s | 25.1 | 117.0 | 0.4 | 164.9 | - | 236.0 | 171 | 164.9 | - | - | - | - | - | |
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
not comparable start-up profiles (PERF_LOAD=1 STALLS=1), slower than plain runs. | |||||||||||||||||||||
basenot comparable |
stall recorder at 10 ms start-up profile |
38.8 | 25.2 | 0 | 35.3 | - | warm-up + 120 s | 23.0 | 117.0 | 0.0 | 84.0 | - | 235.5 | 160 | 84.0 | 0 | 0 | 0 | 0 | 0 | |
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
| |||||||||||||||||||||
base |
stall recorder at 10 ms | 39.1 | 25.5 | 1.5 | 36.0 | Kernel ps3.472, Mesa ps3.476, ps3rsx 0.443 | warm-up + 120 s | 24.9 | 117.0 | 0.2 | 123.9 | - | 234.0 | 169.0 | 123.9 | 0.0 | 0.0 | 0.0 | 0.0 | 0.2 | |
batch ssd1: SSD game data and SSD swap spill against the USB disk (Sauerbraten base x3, OpenArena gl2min)
2026-10-18 · 2026-10-18-ssd1
Tested: Whether putting game data, and also the swap overflow, on an SSD instead of the USB disk shortens loads and stalls in BananaBread and OpenArena. Result: Game data alone on the SSD leaves BananaBread unchanged, because its binaries, libraries and shader cache still load from USB. OpenArena loads 28% faster, but with too few runs to be more than indicative. What we saw
| |||||||||||||||||||||
base |
stall recorder at 10 ms | 38.5 | 24.1 | 4 | 32.7 | - | warm-up + 120 s | 19.7 | 117.0 | 1.6 | 459.1 | - | 234.8 | 184 | 459.1 | 0.2 | 0.0 | 0 | 0 | 0.2 | |
base |
stall recorder at 10 ms switch gdssd |
39.3 | 26.4 | 3 | 34.2 | - | warm-up + 120 s | 21.3 | 117.0 | 1.0 | 406.9 | - | 230.5 | 127 | 406.9 | 0.0 | 0.0 | 0 | 0 | 0.1 | |
base |
stall recorder at 10 ms switch gdssd switch swssd |
38.5 | 24.1 | 5 | 33.7 | - | warm-up + 120 s | 21.3 | 117.0 | 1.6 | 454.3 | - | 233.6 | 153 | 454.3 | 0.2 | 0.0 | 0 | 0 | 0.2 | |
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
| |||||||||||||||||||||
base |
stall recorder at 10 ms start-up profile |
37.8 | 23.9 | 5 | 30.6 | - | warm-up + 120 s | 16.9 | 117.0 | 1.5 | 547.3 | - | 238.9 | 202 | 547.3 | 0.3 | 0.1 | 0 | 0.0 | 0.2 | |
base |
stall recorder at 10 ms start-up profile switch sccold |
38.0 | 24.4 | 5 | 31.4 | - | warm-up + 120 s | 16.0 | 117.0 | 1.3 | 460.0 | - | 238.6 | 183 | 460.0 | 0.3 | 0.1 | 0 | 0 | 0.3 | |
base |
stall recorder at 10 ms start-up profile switch scprime |
37.6 | 24.0 | 3 | 30.6 | - | warm-up + 120 s | 21.9 | 117.0 | 1.2 | 525.7 | - | 238.8 | 184 | 525.7 | 0.5 | 0.1 | 0 | 0 | 0.1 | |
base |
stall recorder at 10 ms start-up profile switch scwarm |
38.7 | 24.7 | 5 | 32.5 | - | warm-up + 120 s | 24.2 | 117.0 | 1.5 | 474.2 | - | 236.2 | 183 | 474.2 | 0.1 | 0.0 | 0.1 | 0 | 0.2 | |
base |
stall recorder at 10 ms switch sysmem_stats300 |
38.8 | 25.0 | 4 | 33.0 | - | warm-up + 120 s | 19.1 | 117.0 | 1.2 | 473.4 | - | 234.7 | 167 | 473.4 | 0.1 | 0.0 | 0 | 0 | 0.2 | |
shortnormals |
stall recorder at 10 ms switch sysmem_stats300 |
45.1 | 30.4 | 4.0 | 38.4 | - | warm-up + 120 s | 19.6 | 121.0 | 1.6 | 511.5 | - | 236.4 | 183.0 | 511.5 | 0.3 | 0.0 | 0.0 | 0.0 | 0.2 | |
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
| |||||||||||||||||||||
base |
stall recorder at 10 ms | 38.8 | 24.1 | 4 | 32.4 | - | warm-up + 120 s | 22.0 | 117.0 | 1.4 | 514.0 | - | 235.0 | 159 | 514.0 | 0.1 | 0.0 | 0 | 0 | 0.2 | |
base |
stall recorder at 10 ms switch gpffetch |
38.8 | 25.3 | 2 | 32.8 | - | warm-up + 120 s | 21.6 | 117.0 | 1.0 | 517.6 | - | 235.4 | 185 | 517.6 | 0.2 | 0.0 | 0 | 0 | 0.1 | |
Sauerbraten NV30_QUERY_WAIT=200 repeat (Mesa ps3.416~dev, kick)
2026-10-18 · 2026-10-18-query-wait-repeat
Tested: A repeat of BananaBread with the occlusion query wait capped at 200, to check the 45.6 fps single run of the previous batch. Result: No gain: 23.0 and 33.4 fps against 26.0 and 37.9 without the cap; the earlier result was a lucky single run. The switch stays off. What we saw
| |||||||||||||||||||||
base |
waker kick at 10 ms | 32.0 | 13.9 | 13.0 | 30.9 | Mesa ps3.416~dev | warm-up + 120 s | 19.4 | 119.1 | 2.8 | 456.5 | - | 191.5 | 130.0 | 456.5 | - | - | - | - | - | |
base |
waker kick at 10 ms switch query_wait200 |
28.2 | 10.2 | 12.0 | 30.7 | Mesa ps3.416~dev | warm-up + 120 s | 18.9 | 119.1 | 4.6 | 1777.2 | - | 146.6 | 121.5 | 1777.2 | - | - | - | - | - | |
Mesa ps3.416~dev hot spots (staging pool, query wait), cube2 355 oqlag, xmoto 362 stream, ClassiCube chunks1 (kick)
2026-10-18 · 2026-10-18-mesa-416-hot-spots
Tested: Fixes for driver hot spots in Mesa ps3.416 (a staging buffer pool, a cap on waiting for occlusion queries) and game-side changes: BananaBread's lagged water occlusion queries, X-Moto's streaming draw path and ClassiCube's chunk setting. Result: ClassiCube's chunk setting gains 5% and X-Moto's streaming shortens the worst frame; the staging pool saves 4% CPU at the same frame rate. BananaBread's big jump with the query wait cap was a single run and did not hold up in the repeat. What we saw
| |||||||||||||||||||||
base |
waker kick at 10 ms | 25 | 4.9 | 28 | 30.1 | Mesa ps3.416~dev | warm-up + 120 s | 15.0 | 119.7 | 8.6 | 900.4 | - | 153.3 | 151 | 900.4 | - | - | - | - | - | |
base |
waker kick at 10 ms switch query_wait200 |
45.6 | 16.9 | 18 | 27.7 | Mesa ps3.416~dev | warm-up + 120 s | 18.5 | 119.7 | 5.7 | 998.3 | - | 202.3 | 156 | 998.3 | - | - | - | - | - | |
oqlag |
waker kick at 10 ms | 39.4 | 14.7 | 20 | 35.5 | Mesa ps3.416~dev | warm-up + 120 s | 17.9 | 119.7 | 8.2 | 1531.0 | - | 228.9 | 164 | 1531.0 | - | - | - | - | - | |
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
| |||||||||||||||||||||
base |
waker kick at 10 ms | 39.2 | 26.4 | 6.0 | 30.7 | Mesa ps3.408 | warm-up + 120 s | 23.2 | 117.0 | 2.1 | 690.2 | - | 231.5 | 167.0 | 690.2 | - | - | - | - | - | |
base |
waker kick at 10 ms switch mmmap |
39.9 | 19.8 | 9.0 | 35.1 | Mesa ps3.408 | warm-up + 120 s | 19.9 | 118.3 | 2.1 | 538.1 | - | 193.2 | 133.5 | 538.1 | - | - | - | - | - | |
base |
waker kick at 10 ms switch mtrim |
38.2 | 21.5 | 8.0 | 33.9 | Mesa ps3.408 | warm-up + 120 s | 21.5 | 117.7 | 2.0 | 462.6 | - | 232.1 | 118.5 | 462.6 | - | - | - | - | - | |
ioquake3 ps3.396 (r_keepImages + cl_preloadLate), libspeq 0.394 (RGB DXT on SPEs), Mesa ps3.408 default LUT; recorder + kick
2026-10-18 · 2026-10-18-ioquake3-396
Tested: ioquake3 ps3.396, which keeps loaded images and preloads the late-loading ones so OpenArena stops loading in the middle of the demo; also libspeq 0.394's RGB texture compression on the SPUs, on BananaBread. Result: OpenArena's gameplay stalls go from 9-10 s to none and the steady rate rises from about 65 to 70.6 fps. BananaBread shows no difference because its demo uploads no RGB textures to compress; on its own the SPU compressor is far faster than the PPE. What we saw
| |||||||||||||||||||||
rgbppe |
SPEQ_S3TC_RGB=ppe SPEQ_DEBUG=1 stall recorder at 10 ms waker kick at 10 ms |
39.4 | 25.8 | 3.0 | 33.2 | Mesa ps3.408 | warm-up + 120 s | 23.0 | 117.0 | 1.1 | 478.1 | - | 232.5 | 132.5 | 478.1 | 0.2 | 0.0 | 0.0 | 0.0 | 0.1 | |
rgbspu |
SPEQ_DEBUG=1 stall recorder at 10 ms waker kick at 10 ms |
39.1 | 25.9 | 2.5 | 32.9 | Mesa ps3.408 | warm-up + 120 s | 19.9 | 117.0 | 0.7 | 500.4 | - | 233.2 | 145.0 | 500.4 | 0.1 | 0.1 | 0.0 | 0.0 | 0.2 | |
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
| |||||||||||||||||||||
base |
waker kick at 10 ms | 25.9 | 18.2 | 4.0 | 21.7 | Mesa ps3.407 | warm-up + 120 s | 18.4 | 118.3 | 1.1 | 512.3 | - | 231.6 | 111.5 | 512.3 | - | - | - | - | - | |
base |
waker kick at 10 ms switch translate_lut1 |
39.6 | 26.9 | 4.5 | 33.4 | Mesa ps3.407 | warm-up + 120 s | 19.0 | 117.0 | 1.4 | 507.1 | - | 231.1 | 108.0 | 507.1 | - | - | - | - | - | |
stall recorder (ps3-gpu-tools 0.385), ioquake3 ps3.379 (atlas off), Sauerbraten demo + nonfree data
2026-10-17 · 2026-10-17-stall-recorder
Tested: The first runs with the stall recorder (ps3-gpu-tools 0.385), which logs why each long frame happened, on OpenArena (ioquake3 ps3.379, atlas off) and BananaBread's demo with its full data. Result: The recorder costs 5.6% of a thread. OpenArena's hitches are CPU work on the main thread (texture and skin loads mid-demo), BananaBread's are disk reads from the USB drive. Fewer OpenArena stalls with the recorder on was left unexplained. What we saw
| |||||||||||||||||||||
demooff |
SPEQ_SKIN=off | 25.3 | 17.6 | 4 | 20.6 | - | warm-up + 120 s | 22.0 | 117.0 | - | - | - | 233.7 | 167 | 494.2 | 0.1 | 0.0 | 0 | 0.0 | 0.3 | |
demoppe |
SPEQ_SKIN=ppe SPEQ_DEBUG=1 |
25.5 | 18.3 | 3 | 21.7 | - | warm-up + 120 s | 24.3 | 117.0 | - | - | - | 233.1 | 154 | 511.7 | 0.3 | 0.0 | 0 | 0 | 0.1 | |
demospu |
SPEQ_SKIN=spu SPEQ_DEBUG=1 |
25.8 | 18.8 | 4 | 21.8 | - | warm-up + 120 s | 18.2 | 117.0 | - | - | - | 233.3 | 134 | 469.3 | 0.3 | 0.0 | 0 | 0 | 0.2 | |
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
| |||||||||||||||||||||
offskin |
SPEQ_SKIN=off | 23.0 | 17.4 | 0 | 23.2 | - | warm-up + 120 s | 22.9 | 117.0 | - | - | - | 219.7 | 96 | 75.2 | - | - | - | - | - | |
ppeskin |
SPEQ_SKIN=ppe SPEQ_DEBUG=1 |
28.1 | 20.6 | 0 | 28.0 | - | warm-up + 120 s | 23.3 | 116.4 | - | - | - | 220.4 | 102 | 81.4 | - | - | - | - | - | |
spuskin |
SPEQ_SKIN=spu SPEQ_DEBUG=1 |
23.6 | 12.0 | 21 | 28.4 | - | warm-up + 120 s | 22.1 | 118.8 | - | - | - | 217.9 | 153 | 614.1 | - | - | - | - | - | |
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
| |||||||||||||||||||||
cpuskel |
the recipe as it is | - | - | - | 8 | Mesa ps3.262, ps3rsx 0.249 | whole run | 12.8 | 140.3 | - | - | - | 120.0 | 207 | - | - | - | - | - | - | |
Group 4 smokes (Mesa ps3.246 + ps3rsx 0.249)
2026-10-17 · 2026-10-17-group4-smokes
Tested: First runs of the heavy games with the VRAM swap on: OpenArena's OpenGL 2 renderer with two settings, SuperTuxKart, and BananaBread with GPU and with CPU skinning. Result: The heavy games are memory-bound, with no driver bug in sight: OpenArena's OpenGL 2 renderer made 10.7 to 13.6 fps with single stalls of 28.3 and 36.3 s. SuperTuxKart refused to start on a big-endian machine, and BananaBread's GPU skinning was far slower than CPU skinning. What we saw
| |||||||||||||||||||||
base |
the recipe as it is | - | - | - | 0 | Mesa ps3.246, ps3rsx 0.249 | whole run | 11.3 | 140.8 | - | - | - | 145.0 | 202 | - | - | - | - | - | - | |
cpuskel |
the recipe as it is | - | - | - | 19.6 | Mesa ps3.246, ps3rsx 0.249 | whole run | 9.3 | 134.8 | - | - | - | 113.0 | 171 | - | - | - | - | - | - | |
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
| |||||||||||||||||||||
cpuskel |
the recipe as it is | - | - | - | 28 | Mesa ps3.246, ps3rsx 0.249 | whole run | 9.7 | 140.3 | - | - | - | 116.2 | 176 | - | - | - | - | - | - | |
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
| |||||||||||||||||||||
cpuskel |
the recipe as it is | - | - | - | 15 | Mesa ps3.246, ps3rsx 0.249 | whole run | 10.8 | 125.0 | - | - | - | 95.3 | 246.5 | - | - | - | - | - | - | |