PICA command front end¶
The original front end processes a small no-draw configuration command list through the standard GSP queue. It stores raw viewport/scissor register values, applies byte masks and recognizes the finalization emitted by libctru. This is a configuration boundary. It produces no pixels, runs no shader and submits no GX2 draw.
The scene adapter also adapts bounded compiled guest draws through the standard queue. The configuration-only API below remains unchanged; the separate scene/guest adapter handles its explicitly defined shader/target subset.
Wire inspection¶
renderer.pica.decode_commands and runtime/core/ctr_pica.c inspect explicit
little-endian bytes. A record contains its first parameter, header, extra
parameters and padding to an eight-byte boundary. The header contains:
| Bits | Meaning |
|---|---|
| 0–15 | Identifier; this implementation accepts wire IDs 0x000–0x3ff |
| 16–19 | Four byte-enable bits |
| 20–27 | Extra parameter count; one record has 1–256 parameters |
| 28–30 | Unused; unsupported encodings are rejected |
| 31 | Increment register for each parameter, otherwise repeat it |
Inspection supports the wire range without claiming those registers can execute. Padding is skipped and never becomes a write. The inspection API tolerates nonzero padding; the pinned libctru producer writes zero padding. This is not physical hardware evidence. Native/host budgets are at most 4 MiB and 65,536 writes; callers may choose smaller budgets. Range overflow, truncated records, unused header bits and exceeded budgets fail visibly.
Facts were checked against GBATEK's command-list description
and clean libctru commit 9b55eda44cf80b971503991e0c78f9bc8fe50425,
gpu.h, gpu.c and registers.h. Its builder splits API arrays into records of
at most 256 parameters. Its implementation is compiled only into a separate
reference test binary; no emulator or external GPU implementation is embedded
in the native front end.
Supported execution¶
ctr_pica_execute starts with a software snapshot initialized to zero; this does
not model hardware reset values. Its supported ordinary registers are:
| IDs | Raw configuration |
|---|---|
0x41–0x44 |
Viewport width/inverse width/height/inverse height |
0x65–0x67 |
Scissor mode/position/dimensions |
0x68 |
Viewport origin |
The stored words retain byte-mask semantics. Numeric float decoding, clipping
and raster behavior are not implemented. A submitted list must have a length
divisible by sixteen bytes and end with one or two single-parameter, full-mask
FINALIZE (0x10) writes of 0x12345678, matching GPUCMD_Split alignment.
Finalization is handled as a completion marker and never stored as an ordinary
register. Configuration after a marker, missing/invalid markers, streamed marker
parameters and more than two markers fail.
All other registers fail, including with a zero byte mask. Draw triggers, shader/uniform/table uploads, command jumps, caches, textures and render-target state are not treated as generic successful register writes.
The whole list and counters are checked before committing any register change.
Input/state/output/report aliases fail before mutation. The commit pass cannot
change unread input. This avoids a 4 KiB automatic state copy; the current
devkitPPC compiler reports a 176-byte ctr_pica_execute stack frame. That is a
compiler observation, not a measurement of the full Wii U call stack.
Standard guest queue¶
GX command 1 stages the checked guest command-buffer bytes before processing. Its address must be eight-byte aligned; length must be nonzero, a multiple of sixteen and within the bounds above. Unimplemented GSP state flags and nonzero reserved words fail. The cache-request bit uses the existing coherent CPU-backed memory contract; asynchronous GPU coherency remains unfinished.
A successful no-draw list emits one synchronous P3D completion (IRQ 5). The counter of tail-marker writes is separate from that command completion. This does not model physical interrupt timing or assert that hardware emits the same interrupt count. Failure preserves the pending queue entry, subsequent work and PICA register snapshot. Successful earlier queue entries remain committed.
The TXT report records completed lists, writes, markers and the last parser's result/register/offset. Guest-memory failures retain the existing memory-fault report. These observations are distinct from picture/launcher confirmations.
Validation¶
make checkincludes the PICA C suite and integrated GSP rejection/completion tests, normal and with ASan/UBSan. The standalone suite exercises capacity, aliases, counter overflow, the full wire-ID boundary and maximum write budget.tools/validate-pica.py --sanitize --output <new-directory>compares 353 original cases, including real pinned libctru construction, native inspection, the independent Python decoder and checked no-draw state expectations. All 353 vector receipts match an emulated big-endian PowerPC Linux run; this does not establish physical Espresso execution.- The original normal-CRT/libctru GX application sends a builder-produced finalized configuration list and waits for P3D. Its AOT execution exits after 1,489,172 instructions, with zero fallback, 17 GX commands and the expected masked viewport word. Its green/red/green pictures still come from CPU-backed fills/transfers, not PICA draws.
The compiled guest draw adapter executes its separately bounded software subset or the optional guarded GX2 backend, including Texture0 sampling and replace/modulate TEV. General shaders, filtering, combiners, geometry and full renderer compatibility remain unsupported.
Maintained source: docs/pica-commands.md · 3849a94bd97b.
GitHub source and issue links may require repository access.