PSP GE List Synchronization: Stall, SIGNAL, FINISH, and Ordering
Type: REFERENCE Status: MAINTAINED Scope: Guest GE queue/list state, stall addresses, ListSync versus DrawSync, callbacks, break/continue, and host-renderer boundaries. Last reviewed: 2026-08-11
The PSP Graphics Engine is a producer/consumer system with guest-visible queue state. A host GPU fence is useful implementation machinery, but it is not itself the PSP contract. This reference separates list progress, callback delivery, framebuffer/display visibility, and VBLANK.
API evidence and state vocabulary
The exact maintained PSPSDK pspge.h reference defines sceGeListEnQueue, sceGeListEnQueueHead, sceGeListUpdateStallAddr, sceGeListSync, sceGeDrawSync, callbacks, break/continue, and the public PspGeListState values. The generated header source is the smallest citation for those declarations. The GU layer separately exposes SIGNAL and FINISH callback kinds and sceGuSync modes in group__GU.
CPU producer: write list -> publish visible bytes -> enqueue<br>GE consumer: QUEUED -> RUNNING -> STALL_REACHED -> RUNNING -> DRAWING_DONE / DONE -> CANCEL_DONE or error<br>sync path: ListSync(qid,type) is not DrawSync(type)<br>display path: GE completion -> framebuffer ownership -> VBLANK latch
Keep at least QUEUED, RUNNING, STALLED, COMPLETED, CANCELLED, BROKEN, and ERROR as internal distinctions even if the public enum is smaller. Track queue id, list start, current PC, stall address, callback id/arguments, enqueue order, owner, and command generation. Do not collapse a stalled list into “GPU idle”.
Stall is a live producer/consumer boundary
sceGeListEnQueue accepts a stall pointer, and sceGeListUpdateStallAddr changes it later. That API shape means a list can be partially consumed, wait for more commands, and resume after the CPU publishes additional bytes. A runtime that snapshots a full list at enqueue time loses this behavior. Cache visibility is a separate CPU-to-GE question; see the memory model and the deeper cache page below.
SIGNAL, FINISH, and synchronization are not interchangeable
The GU documentation distinguishes SIGNAL callbacks from FINISH callbacks. A SIGNAL command is an event in a list, not proof that the list is finished. FINISH ordering relative to the final command, callback context, queued lists, and subsequent sceGeListSync/sceGeDrawSync wakeups must be modeled independently. Likewise, sceGeListSync is per-queue and can peek or wait, whereas sceGeDrawSync concerns drawing completion. Neither is a synonym for Vulkan device idle.
Nakagawa’s current software GE path is at src/rt/ge.c; the host bridge and renderer are separate implementation layers. That file-level citation identifies implementation responsibility without claiming external hardware equivalence.
Break, continue, and display timing
The public header also exposes sceGeBreak and sceGeContinue. Treat them as queue state transitions with saved context and wake behavior, not as a host thread pause. Finally, GE logical completion and display/VBLANK latching are different clocks. A completed list can have changed guest framebuffer memory while the panel has not latched it; cross-link to display/VBLANK for that boundary.
Safe experiment design
Use source-owned lists containing one command at a time, positive and negative stall controls, duplicate list pointers, normal versus head enqueue, callback set/unset, and explicit ListSync/DrawSync probes. Record guest-visible scalar results and callback sequence separately from renderer pixels. A software renderer parity result is localization evidence only; it is not a hardware oracle.