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

WIP

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

WIP

Annex