-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Document Important 3D Hardware Functions (#28)
This PR tries to partially solve issue #6 by documenting the overall usage of the 3D hardware. Giving brief explanations of the Geometry and Rendering Engine, as well as defining each available graphics function and it's parameter types/formats. This PR does not document certain intricacies of non-standard behaviour, and may or may not need gramatical refinements and touches in the future. It also does not provide details on the specs of the 3D hardware, or how graphics commands result in the final Vertex/Polygons RAM buffers.
1 parent
a12f0e4
commit 0f156ee
Showing
10 changed files
with
693 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# 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 from``0x4000440..=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-7 | Command Index 0 | ||
| 8-15 | Command Index 1 | ||
| 16-23 | Command Index 2 | ||
| 24-31 | Command 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 Index | Port address | Summary | | ||
|---------------|--------------|--------------------------------------| | ||
| 0x10 | 0x0400_0440 | <a href=3d_matrix_commands.html#3D_CMD_10>Select Matrix Mode/Matrix Stack</a> | ||
| 0x11 | 0x0400_0444 | <a href=3d_matrix_commands.html#3D_CMD_11>Push matrix onto stack</a> | ||
| 0x12 | 0x0400_0448 | <a href=3d_matrix_commands.html#3D_CMD_12>Pull matrix from stack</a> | ||
| 0x13 | 0x0400_044C | <a href=3d_matrix_commands.html#3D_CMD_13>Store matrix on stack</a> | ||
| 0x14 | 0x0400_0450 | <a href=3d_matrix_commands.html#3D_CMD_14>Restore matrix from stack</a> | ||
| 0x15 | 0x0400_0454 | <a href=3d_matrix_commands.html#3D_CMD_15>Set current matrix to ``I`` (Unit/Identity matrix)</a> | ||
| 0x16 | 0x0400_0458 | <a href=3d_matrix_commands.html#3D_CMD_16>Load 4x4 values into current matrix.</a> | ||
| 0x17 | 0x0400_045C | <a href=3d_matrix_commands.html#3D_CMD_17>Load 4x3 values into current matrix.</a> | ||
| 0x18 | 0x0400_0460 | <a href=3d_matrix_commands.html#3D_CMD_18>Multiply current matrix by 4x4 Matrix</a> | ||
| 0x19 | 0x0400_0464 | <a href=3d_matrix_commands.html#3D_CMD_19>Multiply current matrix by 4x3 Matrix</a> | ||
| 0x1A | 0x0400_0468 | <a href=3d_matrix_commands.html#3D_CMD_1A>Multiply current matrix by 3x3 Matrix</a> | ||
| 0x1B | 0x0400_046C | <a href=3d_matrix_commands.html#3D_CMD_1B>Scale current matrix by vector</a> | ||
| 0x1C | 0x0400_0470 | <a href=3d_matrix_commands.html#3D_CMD_1C>Translate current matrix by vector</a> | ||
| 0x20 | 0x0400_0480 | <a href=3d_vertex_polygon_commands.html#3D_CMD_20>Set Vertex Color</a> | ||
| 0x21 | 0x0400_0484 | <a href=3d_vertex_polygon_commands.html#3D_CMD_21>Set Vertex Normal</a> | ||
| 0x22 | 0x0400_0488 | <a href=3d_vertex_polygon_commands.html#3D_CMD_22>Set Vertex Texture Coordinates</a> | ||
| 0x23 | 0x0400_048C | <a href=3d_vertex_polygon_commands.html#3D_CMD_23>Set Vertex Position (16-bit)</a> | ||
| 0x24 | 0x0400_0490 | <a href=3d_vertex_polygon_commands.html#3D_CMD_24>Set Vertex Position (10-bit)</a> | ||
| 0x25 | 0x0400_0494 | <a href=3d_vertex_polygon_commands.html#3D_CMD_25>Set Vertex XY position</a> | ||
| 0x26 | 0x0400_0498 | <a href=3d_vertex_polygon_commands.html#3D_CMD_26>Set Vertex XZ position</a> | ||
| 0x27 | 0x0400_049C | <a href=3d_vertex_polygon_commands.html#3D_CMD_27>Set Vertex YZ position</a> | ||
| 0x28 | 0x0400_04A0 | <a href=3d_vertex_polygon_commands.html#3D_CMD_28>Set Vertex position relative to the last</a> | ||
| 0x29 | 0x0400_04A4 | <a href=3d_vertex_polygon_commands.html#3D_CMD_29>Set Vertex Attributes</a> | ||
| 0x2A | 0x0400_04A8 | <a href=3d_vertex_polygon_commands.html#3D_CMD_2A>Set Texture Parameters</a> | ||
| 0x2B | 0x0400_04AC | <a href=3d_vertex_polygon_commands.html#3D_CMD_2B>Set Texture Palette</a> | ||
| 0x30 | 0x0400_04C0 | <a href=3d_vertex_polygon_commands.html#3D_CMD_30>Set Diffused/Ambient Color</a> | ||
| 0x31 | 0x0400_04C4 | <a href=3d_vertex_polygon_commands.html#3D_CMD_31>Set Specular/Emissive Color</a> | ||
| 0x32 | 0x0400_04C8 | <a href=3d_test_commands.html#3D_CMD_32>Set Light Direction</a> | ||
| 0x33 | 0x0400_04CC | <a href=3d_test_commands.html#3D_CMD_33>Set Light Color</a> | ||
| 0x34 | 0x0400_04D0 | <a href=3d_test_commands.html#3D_CMD_34>Set Shininess table</a> | ||
| 0x40 | 0x0400_0500 | <a href=3d_vertex_polygon_commands.html#3D_CMD_40>Start vertex list</a> | ||
| 0x41 | 0x0400_0504 | <a href=3d_vertex_polygon_commands.html#3D_CMD_41>End vertex list</a> | ||
| 0x50 | 0x0400_0540 | <a href=3d_vital_commands.html#3D_CMD_50>Swap Buffers between geometry and rendering engine</a> | ||
| 0x60 | 0x0400_0580 | <a href=3d_vital_commands.html#3D_CMD_60>Set 3D Viewport</a> | ||
| 0x70 | 0x0400_05C0 | <a href=3d_test_commands.html#3D_CMD_70>Test view volume against cuboid</a> | ||
| 0x71 | 0x0400_05C4 | <a href=3d_test_commands.html#3D_CMD_71>Test Position Vector</a> | ||
| 0x72 | 0x0400_05C8 | <a href=3d_test_commands.html#3D_CMD_72>Test Direction Vector</a> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# 3D Light Commands | ||
|
||
These are the commands which specifies the lighting conditions for any upcoming polygons and verticies. | ||
|
||
<a id="3D_CMD_32"></a> | ||
## Set Lights Directional Vector: Port 0x040004C8, Index 0x32, 1 Parameter | ||
|
||
Sets the direction a given light points in. | ||
|
||
Parameter Definition: | ||
|
||
| Bit(s) | Description | | ||
|--------|-------------| | ||
| 0-9 | X coordinate | ||
| 10-19 | Y coordinate | ||
| 20-29 | Z coordinate | ||
| 30-31 | Light Index (0..=3) | ||
|
||
all coordinate parameters are in the same format, as in: 1bit sign + 9 bit fraction. | ||
|
||
<a id="3D_CMD_33"></a> | ||
## Set Lights Color: Port 0x040004CC, Index 0x33, 1 Parameter | ||
|
||
Sets the color of a given light. | ||
|
||
Parameter Definition: | ||
|
||
| Bit(s) | Description | | ||
|--------|-------------| | ||
| 0-4 | Red | ||
| 5-9 | Green | ||
| 10-14 | Blue | ||
| 15-29 | Unused | ||
| 30-31 | Light Index (0..=3) | ||
|
||
<a id="3D_CMD_34"></a> | ||
## Set Shininess table: Port 0x040004D0, Index 0x34, 32 Parameters | ||
|
||
Sets the contents of a 128-byte shininess table used for specular reflections. transferred 4 entries (bytes) at a time. 0 = least shiny, 255 = most shiny. | ||
|
||
Notes: When the shininess table is disabled, the Rendering Engine will act as if the table is filled with linearly increasing entries from the minimum to the maximum. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# 3D Matrix Commands | ||
On the DS there are multiple matrix operations as well as matrix stacks responsible for calculating the resulting light, normal, and position vectors related to any given vertex. These matrix stacks are: | ||
|
||
* Projection stack (Size: 1, Mode: 0) | ||
* Coordinate stack (Size: 32, Mode: 1,2) | ||
* Directional stack (Size: 32, Mode: 1,2) | ||
* Texture stack: (Size: 1, Mode: 3) | ||
|
||
Mode in this case reffers to what index needs to be sent to CMD 0x10 in order to "select" the given stack. Notice how the coordinate and directional stack share modes 1 and 2. Which indicates how both are changed when in those modes (and also internally share the same stack pointer). The two modes however change both stacks in different ways depending on the commands used. | ||
|
||
When working with the matrix commands, you may often stumble upon the term "Current matrix", which reffers to the matrix at the top of the selected matrix stack(s). | ||
|
||
# Matrix Stack Commands | ||
|
||
Here are the commands which depends on the matrix stack(s): | ||
|
||
<a id="3D_CMD_10"></a> | ||
## Set Matrix Mode: Port 0x04000440, Index 0x10, 1 Parameter | ||
Selects the matrix stack which is to be modified | ||
|
||
Parameter Definition: | ||
|
||
| Bit(s) | Description | | ||
|--------|---------------------------------------------------------| | ||
| 0-1 | Mode Index | ||
| 2-31 | Unused | ||
|
||
Possible Mode Indicies: | ||
|
||
| Mode Index | Selected Stack and purpose | | ||
|------------|----------------------------| | ||
| 0 | Selects Projection Matrix, in a traditional MVP matrix this would be the P part. | ||
| 1 | Position and Direction Matrix stack. In a traditional MVP matrix this would be the MV parts. | ||
| 2 | Position and Direction Matrix stack. Primarily used in lighting and test related context. | ||
| 3 | Selects Texture Coordinate Matrix stack. Modifies how texture coordinates are transformed. | ||
|
||
|
||
<a id="3D_CMD_11"></a> | ||
## Push Matrix stack: Port 0x04000444, Index 0x11, No Parameter | ||
Pushes the "Current matrix" onto the stack | ||
|
||
<a id="3D_CMD_12"></a> | ||
## Pull Matrix stack: Port 0x04000448, Index 0x12, 1 Parameter | ||
Pops N matricies off the current matrix stack | ||
|
||
Parameter Definition: | ||
|
||
| Bit(s) | Description | | ||
|--------|---------------------------------------------------------| | ||
| 0-5 | Ammount of matricies to pop in range -30..=31 (N) | ||
| 6-31 | Unused | ||
|
||
Notes: | ||
|
||
On matrix stacks with a size of 1, the parameter is ignored and 1 is always used. | ||
|
||
<a id="3D_CMD_13"></a> | ||
## Store Current Matrix on Stack: Port 0x0400044C, Index 0x13, 1 Parameter | ||
Stores the current matrix on another part of the stack. Leaves the stack pointer unchanged. | ||
|
||
Parameter Definition: | ||
|
||
| Bit(s) | Description | | ||
|--------|---------------------------------------------------------| | ||
| 0-4 | Stack Offset | ||
| 5-31 | Unused | ||
|
||
Note: | ||
|
||
A Stack Offset of 31 causes the stack error flag in the ``GXSTAT`` register to be set. | ||
|
||
On stacks where the size is 1, the parameter is ignored and 0 is always used. | ||
|
||
<a id="3D_CMD_14"></a> | ||
## Restore Current Matrix from Stack: Port 0x04000450, Index 0x14, 1 Parameter | ||
Sets the current matrix to the values of another matrix on the stack. Leaves the stack pointer unchanged. | ||
|
||
Parameter Definition: | ||
|
||
| Bit(s) | Description | | ||
|--------|---------------------------------------------------------| | ||
| 0-4 | Stack Offset | ||
| 5-31 | Unused | ||
|
||
Note: | ||
|
||
A Stack Offset of 31 causes the stack error flag in the ``GXSTAT`` register to be set. | ||
|
||
On stacks where the size is 1, the parameter is ignored and 0 is always used. | ||
|
||
# General Matrix Commands | ||
|
||
These are the commands which modify the current matrix: | ||
|
||
<a id="3D_CMD_15"></a> | ||
## Load Identity Matrix: Port 0x04000454, Index 0x15, No Parameter | ||
Sets the current matrix to a Unit/Identity matrix. Sometimes denoted as ``I`` or ``1``. | ||
|
||
<a id="3D_CMD_16"></a> | ||
## Load 4x4 Matrix: Port 0x04000458, Index 0x16, 16 Parameters | ||
Sets the current matrix to a 4x4 matrix, where each parameter corresponds to a cell in the matrix. Values are loaded row by row. starting at row 0 column 0. | ||
|
||
<a id="3D_CMD_17"></a> | ||
## Load 4x3 Matrix: Port 0x0400045C, Index 0x17, 12 Parameters | ||
Sets the current matrix to a 4x3 matrix (padded to a 4x4 matrix which doesn't scale W), where each parameter corresponds to a cell in the matrix. Values are loaded row by row. starting at row 0 column 0. | ||
|
||
<a id="3D_CMD_18"></a> | ||
## Multiply 4x4 Matrix: Port 0x04000460, Index 0x18, 16 Parameters | ||
Multiply the current matrix by a 4x4 matrix, where each parameter corresponds to a cell in the matrix. Values are loaded row by row. starting at row 0 column 0. | ||
|
||
<a id="3D_CMD_19"></a> | ||
## Multiply 4x3 Matrix: Port 0x04000464, Index 0x19, 12 Parameters | ||
Multiply the current matrix by a 4x3 matrix (padded to a 4x4 matrix which doesn't scale W), where each parameter corresponds to a cell in the matrix. Values are loaded row by row. starting at row 0 column 0. | ||
|
||
<a id="3D_CMD_1A"></a> | ||
## Multiply 3x3 Matrix: Port 0x04000468, Index 0x1A, 9 Parameters | ||
Multiply the current matrix by a 3x3 matrix (padded to a 4x4 matrix which makes W unnaffected), where each parameter corresponds to a cell in the matrix. Values are loaded row by row. starting at row 0 column 0. | ||
|
||
<a id="3D_CMD_1B"></a> | ||
## Scale Current Matrix by vector: Port 0x0400046C, Index 0x1B, 3 Parameters | ||
Multiply the current matrix by a scale matrix where each scalar value corresponds to the coordinates in a vector. (W coordinate is always 1) | ||
|
||
<a id="3D_CMD_1C"></a> | ||
## Translate Current Matrix by vector: Port 0x04000470, Index 0x1C, 3 Parameters | ||
Multiply the current matrix by a translation matrix containing the supplied vector coordinates. | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# 3D Rendering Engine | ||
|
||
The Rendering Engine on the Nintendo DS is responsible for taking in the Vertex And Polygon buffers from the Geometry Engine and constructing frames of video. This can either be displayed as background 0 on the main 2D PPU or captured by the capture unit to be used as a bitmap image. | ||
|
||
The Rendering Engine uses a 48-line "Scanline Cache" as opposed to a full framebuffer containing the entire output of a frame when rendering. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# 3D Display Control | ||
|
||
This chapter talks about the status registers of the 3D hardware. | ||
|
||
<a id="GXSTAT"></a> | ||
## GXSTAT: Geometry Engine Status Register (0x04000600, mixed R/W) | ||
|
||
| Bit(s) | Description | | ||
|--------|--------------------| | ||
| 0 | Test functions Busy | ||
| 1 | Box Test Result | ||
| 2-7 | unused | ||
| 8-12 | Position & Directional Matrix Stack Pointer | ||
| 13 | Projection Matrix Stack Pointer | ||
| 14 | Matrix Stack Busy | ||
| 15 | Matrix Stack Overflow/Undeflow | ||
| 16-24 | Number of 40-bit entries in Command FIFO | ||
| 25 | FIFO is less than half full | ||
| 26 | FIFO is empty | ||
| 27 | General Busy Flag | ||
| 28-29 | unused | ||
| 30-31 | Command FIFO IRQ (0 = Never, 1 = Less than half full, 2 = Empty, 3 = Reserved) | ||
|
||
|
||
## RAM statistics: Polygon List & Vertex RAM Count (0x04000604, R) | ||
|
||
| Bit(s) | Description | | ||
|--------|--------------------| | ||
| 0-11 | Number of Polygons currently in Polygon List RAM | ||
| 12-15 | unused | ||
| 16-28 | Number of Verticies currently in Vertex RAM | ||
| 29-31 | unused | ||
|
||
Note: Once a buffer swap has been sent, the counters are reset 10 cycles after V-Blank. | ||
|
||
## Performance Statistics (0x04000320, R) | ||
|
||
| Bit(s) | Description | | ||
|--------|--------------------| | ||
| 0-5 | Minimum number of buffered lines during last frame - 2 | ||
| 6-31 | unused | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# 3D Test Commands | ||
|
||
These Commands test various parameters against desired results by the user. Each command requires that the "test busy" bit of the ``GXSTAT`` register is cleared before reading the result. | ||
|
||
<a id="3D_CMD_70"></a> | ||
## Test if Cuboid Intersects View Volume: Port 0x040005C0, Index 0x70, 3 Parameters | ||
|
||
The result of this command can be read from bit 1 of the ``GXSTAT`` register and indicates if any part of the specified cuboid intesects the view volume. A value of 1 indicates that the cuboid would have been visible if drawn. | ||
|
||
Parameter definition: | ||
|
||
| Parameter | Bit(s) | Description | | ||
|-----------|--------|-------------| | ||
| 1 | 0-15 | Origin X coordinate | ||
| 1 | 16-31 | Origin Y coordinate | ||
| 2 | 0-15 | Origin Z coordinate | ||
| 2 | 16-31 | Width (X-Offset) | ||
| 3 | 0-15 | Height (Y-Offset) | ||
| 3 | 16-31 | Depth (Z-Offset) | ||
|
||
all parameters are in the same format as 16 bit vertex coordinates. As in, 1bit sign + 3 bit integer + 12 bit fraction. | ||
|
||
<a id="3D_CMD_71"></a> | ||
## Set Coordinates for Position Test: Port 0x040005C4, Index 0x71, 2 Parameters | ||
|
||
Takes the vector ``(x,y,z,1)`` and multiplies by the positional and projection matrix stacks. Result can be read from the memory region at ``0x04000620..=0x0400062F`` where each word corresponds to a coordinate of the resulting vector. In format 1bit sign + 19 bit integer + 12 bit fraction. | ||
|
||
Parameter Definition: | ||
|
||
| Parameter | Bit(s) | Description | | ||
|-----------|--------|-------------| | ||
| 1 | 0-15 | X coordinate | ||
| 1 | 16-31 | Y coordinate | ||
| 2 | 0-15 | Z coordinate | ||
| 2 | 16-31 | Unused | ||
|
||
all parameters are in the same format as 16 bit vertex coordinates. As in, 1bit sign + 3 bit integer + 12 bit fraction. | ||
|
||
Notes: This command should not be issued while a vertex list is being constructed. As any vertex position commands that inherit the coordinates of the previous vertex will instead inherit the coordinates set by this command. | ||
|
||
<a id="3D_CMD_72"></a> | ||
## Set Directional vector for Direction Test: Port 0x040005C8, Index 0x72, 1 Parameter | ||
|
||
Takes the vector ``(x,y,z,0)`` and multiplies by the directional matrix stack. (according to no$ also requires matrix mode 2?) Result can be read from the memory region at ``0x04000630..=0x04000635`` where each 2byte half word corresponds to a coordinate of the resulting vector. In format 4bit sign + 12 bit fraction. (sign is either ``0b0000`` or ``0b1111``) | ||
|
||
Parameter Definition: | ||
|
||
| Bit(s) | Description | | ||
|--------|-------------| | ||
| 0-9 | X coordinate | ||
| 10-19 | Y coordinate | ||
| 20-29 | Z coordinate | ||
| 30-31 | Unused | ||
|
||
all parameters are in the same format as those for other light direction commands, as in: 1bit sign + 9 bit fraction. |
Oops, something went wrong.