Table of Contents
PICA200
The PICA200 was a semi-programmable, fixed-function GPU developed by DMP
Summarizing, the unit found in the 3DS has 2 display controllers, 2 memory fill units, a transfer engine, and a 3D engine.
We’ll focus on the 3D engine
3D engine
General Information

Low Level Information
The 3D engine has the expected functionality which a usual GPU exposes, commands can be issued from MMIO registers or from a parallel
command buffer interface (exposed through those)
Command buffers
Commands are simply deferred writes to MMIO registers that are done by the GPU directly. Allows the CPU to do work in parallel and be interrupted
later by the GPU; this interface can only write to 3D engine registers.
It uses fixed-point and custom IEEE-formatted floating point values, we’ll name them for brevity:
- fX.Y - An IEEE-formatted floating point value with X exponent bits and Y stored mantissa bits
- uqX.Y - An unsigned fixed-point value with X integer bits and Y fractional bits
- qX.Y - A signed fixed-point value with X integer bits and Y fractional bits
GSP
In Horizon, userland applications don’t use the MMIO registers as the GPU is driven by the GSP sysmodule (gsp::GPU). Nonetheless, GSP doesn’t implement any kind
of Graphics API; only exposes a way to submit GPU requests to each GPU unit.
Quirks and undocumented behavior
Even though the GPU has been reverse engineered, there’s still lots of things that are unknown and are being discovered to this day. For example, no one
has rendered gaseous objects with the primitives the PICA200 provides.
The pipeline starts when a drawcall is issued. There are two ways to do this, through Immediate Vertices or Vertex Fetching
Immediate Vertices
These are issued through register writes. The GPU waits for 4 packed f7.16 values in little endian and reverse order; i.e 3 separate words sent like this WWWZ - ZZYY - YXXX.
Those values fill inputs in the vertex shader. When all inputs all filled and enough vertices have been issued to emit a primitive, the primitive is drawn.
This shouldn’t be used in applications. However, this may be useful for debugging when developing drivers.
Vertex Fetching
Vertex fetching happens when either a draw or indexed draw is issued.
Multiple registers drive the behavior, including the configuration of index and vertex buffers which must be set up. Here’s the relevant register group as we won’t explain them now.
While vertices are fetched, they are handed to the Vertex Shader
Vertex Shader Units
