iPhone GPU Performance (A12 XS,
iPhone GPU performance: what costs pixels on Apple GPUs
Section titled “iPhone GPU performance: what costs pixels on Apple GPUs”Context: GitHub #124. One iPhone XS (iPhone11,2, A12) store session on 1.1 (BUILD 338) averaged 46 fps.
Telemetry: samples.gpu_ms ~21.4 ms against a 16.6 ms budget, while tick_ms + render_cpu_ms was
~1.7 ms. The frame is GPU (fill-rate / bandwidth) bound, not CPU or draw-call bound.
Findings (telemetry, 2026-10-24)
Section titled “Findings (telemetry, 2026-10-24)”- No build regression. Apple TV HD (AppleTV11,1, A8, pinned 1080p) GPU time is flat at ~12 ms per frame across builds 303-338 with no evolved weapon. store-335 vs store-338 differ only in scripts/marketing, so their gap is loadout, not code.
- The XS was never comfortably at 60 under load. It was under 60 fps at moderate enemy counts
by build 204 (2026-10-02); the “held 60 on 09-29” note in
docs/reference/fidelity-device-sim.mdwas most likely a light-load run. - Native resolution is the main multiplier. The XS renders world and UI at native 2436x1125
(UIScreen.scale 3, ~2.74 MP) into an RGBA16F target (
viewport/hdr_2d=true), 1.32x the Apple TV’s pixels on a similar-class GPU. A ~720-line cap (~1559x720) is ~41% of the pixels. Implemented as a per-device-class render-scale tunable onfix/124-render-scale(1.1.1). - Event Horizon (evolved Orbit) is the one content-specific cost seen: ATV runs with it climb to 14.9 ms (5-15 min) and 18.4 ms / 48.6 fps (>15 min, 6 sessions, ~24 enemies but ~520 draws). Confounded with run length. Tracked as #152.
- ~5 ms of the XS’s 21.4 ms is not explained by pixel count scaled from the ATV. Unresolved; A/B live
on a TestFlight build with Remote Control armed (skill
bh-console-live-ab). - Telemetry to use:
samples.gpu_ms(populated on iOS/tvOS despite the stale “NULL on Metal” schema comment) plus thelaunchevent’swin_w/h,screen_scale,content_scale. Do not usesim_ms.
How Apple GPUs spend time (tile-based deferred rendering)
Section titled “How Apple GPUs spend time (tile-based deferred rendering)”Apple GPUs render the frame in small tiles held in fast on-chip memory. Work that stays in the tile is cheap; work that moves a whole frame through main memory is expensive. Practical consequences:
- Full-screen copies are the costliest pattern. Each
BackBufferCopy/ screen-reading effect ends the render pass, writes the frame out, and reads it back. Ours: shockwave, gravity lens, screen punch, spacetime warp, warp streaks, screen feedback, the Event Horizon warp. Fewer copies per frame, or smaller copy rects, beats shader micro-optimisation. - Render-target format is bandwidth. RGBA16F (HDR 2D) is twice the bytes of RGBA8 on every load, store and copy.
- Blending and overdraw. Additive halos and soft glows cost per covered pixel per layer, and blending disables hidden-surface removal. Large soft sprites over large areas add up.
- Resolution multiplies all of the above. Hence the render-scale cap as the broadest lever, and
existing reduced-resolution paths (
FxHalfResHostat 0.5,NebulaBgat 0.35). - Measure the right way. Godot’s quick fill-rate test: V-Sync off, compare fps in a large window vs a very small one; a big gain means fill-rate bound.
References
Section titled “References”- Apple, Tailor your apps for Apple GPUs and tile-based deferred rendering
- WWDC20, Optimize Metal Performance for Apple silicon Macs (same GPU architecture)
- Godot docs, GPU optimization: fill rate
- Kodeco, Metal by Tutorials: Best practices
- In-repo:
docs/research/2026-10-11-godot-48-gpu-ab-and-fill-rate.md,docs/research/2026-09-29-general-performance-review.md,docs/architecture/rendering-and-performance.md