3D Geometry Engine

The Geometry Engine on the Nintendo DS is the hardware responsible for taking in 3D Graphics Commands and coverting them to verticies and polygons which can be rendered by the Rendering Engine. It’s jobs include performing various matrix multiplications involving vertex positions, vertex colors, light vectors, etc.

Readable Matricies

The Geometry provides access to the final directional matrix and screen space transformation matrix. (as in, position matricies * projection matrix) Reading these requires the geometry engine to be disabled via bit 27 in the GXSTAT register.

Clip Matrix (0x4000640..=0x400067F, 16 words, R)

Read the 4x4 “Clip matrix” with cells going from row 0 column 0, row by row.

Read Directional Matrix (0x4000680..=0x40006A3, 9 words, R)

Read the “top left” 3x3 segment of the directional matrix with cells going from row 0 column 0, row by row.

3D Command FIFO

The Geometry engine is heavily based upon a Command FIFO and PIPE used to transfer vertex lists, bind textures, set viewport, modify matricies, etc. The FIFO can be directly accessed by writing command numbers and parameters to memory location 0x4000400 or indirectly by writing parameters to the corresponding “Command Ports” at various memory locations from0x4000440..=0x40005FF.

Using the FIFO indirectly

The simpler and more user friendly method of interacting with the FIFO is via the “Command Ports”, where parameters are written to the corresponding memory address for a given command. The command + parameter combo is automatically sent down the FIFO to the 3D hardware once every parameter has been sent. For commands that don’t have any parameters one may simply write any value to the port.

Using the FIFO directly

When using the FIFO directly, commands are sent by first writing a “Command word” containing up to 4 packed command indicies. Followed by writing the parameters for each command in order. If the last command does not have a parameter, 0 must be written as a dummy parameter in order for the hardware to accept a new “command word”. When trying to specify invalid command indicies they will be treated the same as command index 0. (no command, no parameters) This way of using the fifo is better suited to transferring large chunks of commands, such as via DMA.

“Command word” definition

Bit(s)Description
0-7Command Index 0
8-15Command Index 1
16-23Command Index 2
24-31Command Index 3

Notes:

When packing multiple commands you may not leave zeroed indicies (indicating no command) in between non-zeroed indicies. Meaning that when sending one command the top 24 bits must be zero, when sending 2 commands the top 16 bits must be zero, and when sending 3 commands the top 8 bits must be zero.

Command Summary

Command IndexPort addressSummary
0x100x0400_0440Select Matrix Mode/Matrix Stack
0x110x0400_0444Push matrix onto stack
0x120x0400_0448Pull matrix from stack
0x130x0400_044CStore matrix on stack
0x140x0400_0450Restore matrix from stack
0x150x0400_0454Set current matrix to I (Unit/Identity matrix)
0x160x0400_0458Load 4x4 values into current matrix.
0x170x0400_045CLoad 4x3 values into current matrix.
0x180x0400_0460Multiply current matrix by 4x4 Matrix
0x190x0400_0464Multiply current matrix by 4x3 Matrix
0x1A0x0400_0468Multiply current matrix by 3x3 Matrix
0x1B0x0400_046CScale current matrix by vector
0x1C0x0400_0470Translate current matrix by vector
0x200x0400_0480Set Vertex Color
0x210x0400_0484Set Vertex Normal
0x220x0400_0488Set Vertex Texture Coordinates
0x230x0400_048CSet Vertex Position (16-bit)
0x240x0400_0490Set Vertex Position (10-bit)
0x250x0400_0494Set Vertex XY position
0x260x0400_0498Set Vertex XZ position
0x270x0400_049CSet Vertex YZ position
0x280x0400_04A0Set Vertex position relative to the last
0x290x0400_04A4Set Vertex Attributes
0x2A0x0400_04A8Set Texture Parameters
0x2B0x0400_04ACSet Texture Palette
0x300x0400_04C0Set Diffused/Ambient Color
0x310x0400_04C4Set Specular/Emissive Color
0x320x0400_04C8Set Light Direction
0x330x0400_04CCSet Light Color
0x340x0400_04D0Set Shininess table
0x400x0400_0500Start vertex list
0x410x0400_0504End vertex list
0x500x0400_0540Swap Buffers between geometry and rendering engine
0x600x0400_0580Set 3D Viewport
0x700x0400_05C0Test view volume against cuboid
0x710x0400_05C4Test Position Vector
0x720x0400_05C8Test Direction Vector