GP0 Drawing Commands: Difference between revisions
| Revision as of 02:32, 23 October 2026 RemmyLee (CLAUDE.md, CONTEXT.md: the gate skips doc-slop's length and lede rules) | Revision as of 02:43, 23 October 2026 RemmyLee (GPU at register depth: GP0, GP1, GPUSTAT, VRAM, rendering, T-cache, video timing) | ||
| Line 1: | Line 1: | ||
| + | --- | ||
| + | title: GP0 Drawing Commands | ||
| + | type: register | ||
| + | summary: Polygon, line and rectangle commands that the CPU writes to the GP0 port. | ||
| + | category: Hardware | ||
| + | category: GPU | ||
| + | --- | ||
| + | |||
| + | ## Summary | ||
| + | |||
| + | GP0 is the command port of the [GPU](/hardware/gpu/) at 0x1F801810. The CPU writes each drawing command and its parameters to GP0 as a series of 32-bit words. It may write the words directly or send them by DMA. The GPU first inspects the top 3 bits of the first word, and these bits select one of eight command groups. Drawing commands are groups 1 to 3, and the table below shows where the other groups are described.[^spx-io][^spx-sum] | ||
| + | |||
| + | Table: GP0 command groups | ||
| + | |||
| + | | Bits 29 to 31 | Group | Page | | ||
| + | | --- | --- | --- | | ||
| + | | 0 | Misc commands | [GP0 transfer and other commands](/hardware/gpu/gp0-transfer/) | | ||
| + | | 1 | Polygon primitive | This page | | ||
| + | | 2 | Line primitive | This page | | ||
| + | | 3 | Rectangle primitive | This page | | ||
| + | | 4 | VRAM-to-VRAM blit | [GP0 transfer and other commands](/hardware/gpu/gp0-transfer/) | | ||
| + | | 5 | CPU-to-VRAM blit | [GP0 transfer and other commands](/hardware/gpu/gp0-transfer/) | | ||
| + | | 6 | VRAM-to-CPU blit | [GP0 transfer and other commands](/hardware/gpu/gp0-transfer/) | | ||
| + | | 7 | Environment commands | [GP0 environment commands](/hardware/gpu/gp0-environment/) | | ||
| + | |||
| + | Execution of a command starts when all of its parameters have been received. However, a polygon command starts as soon as its first 3 vertices have arrived, and a line command after its first 2.[^spx-sum] In libgpu a command and its parameters form a primitive (or packet), which is a data structure in main memory. The libgpu structures correspond closely to the primitives recognized by the GPU hardware, so the fields below map directly onto members such as r0, x0 and tpage.[^lo84][^lo89] | ||
| + | |||
| + | ## Polygon Commands | ||
| + | |||
| + | A polygon command draws a triangle or a quadrilateral with flat or Gouraud shading and with or without a texture. The first word of the command holds the following fields:[^spx-poly] | ||
| + | |||
| + | Table: Polygon command word | ||
| + | |||
| + | | Bits | Name | Content | | ||
| + | | --- | --- | --- | | ||
| + | | 0 to 7 | R0 | Red of the polygon color, or of vertex 0 with Gouraud shading | | ||
| + | | 8 to 15 | G0 | Green of the polygon color, or of vertex 0 with Gouraud shading | | ||
| + | | 16 to 23 | B0 | Blue of the polygon color, or of vertex 0 with Gouraud shading | | ||
| + | | 24 | TGE | Texture color mode (0 = shaded or modulated, 1 = raw texture) | | ||
| + | | 25 | ABE | Semi-transparency (0 = off, 1 = on) | | ||
| + | | 26 | TME | Texture mapping (0 = off, 1 = on) | | ||
| + | | 27 | VTX | Vertex count (0 = triangle, 1 = quadrilateral) | | ||
| + | | 28 | IIP | Shading (0 = flat, 1 = Gouraud) | | ||
| + | | 29 to 31 | CODE | Command group, always 1 | | ||
| + | |||
| + | When TGE is 1 the texture is drawn as stored and the color is ignored. With ABE set on a textured polygon, semi-transparency applies only to texels whose bit 15 is set; the other texels are drawn opaque.[^spx-poly] | ||
| + | |||
| + | ### Vertex Words | ||
| + | |||
| + | Each vertex sends up to 3 words in this order:[^spx-poly] | ||
| + | |||
| + | Table: Polygon vertex words | ||
| + | |||
| + | | Word | Format | Present | | ||
| + | | --- | --- | --- | | ||
| + | | Color | 00BBGGRR | Gouraud shading only, from the second vertex on | | ||
| + | | Vertex | YYYYXXXX | Always | | ||
| + | | Texture coordinate | ClutVVUU or PageVVUU | Textured polygons only | | ||
| + | |||
| + | The texture coordinate words also carry the texture settings. The upper 16 bits of the word for vertex 0 hold the CLUT ID, and those of vertex 1 hold the texture page ID; in the remaining texture coordinate words these bits should be 0. The GPU processes every combination of the command bits, including ones that make no sense. Gouraud shading with a raw texture, for example, still requires a color word for every vertex, although the colors have no effect.[^spx-poly] | ||
| + | |||
| + | ### Polygon Command Codes | ||
| + | |||
| + | The command bits give the following codes. The libgpu primitive column names the libgpu structure that draws the same shape.[^lo89] | ||
| + | |||
| + | Table: Polygon command codes | ||
| + | |||
| + | | Code | Shape | Shading | Texture | Words | libgpu primitive | | ||
| + | | --- | --- | --- | --- | --- | --- | | ||
| + | | 20h | Triangle | Flat | None | 4 | POLY_F3 | | ||
| + | | 24h | Triangle | Flat | Modulated | 7 | POLY_FT3 | | ||
| + | | 25h | Triangle | Flat | Raw | 7 | POLY_FT3 | | ||
| + | | 28h | Quadrilateral | Flat | None | 5 | POLY_F4 | | ||
| + | | 2Ch | Quadrilateral | Flat | Modulated | 9 | POLY_FT4 | | ||
| + | | 2Dh | Quadrilateral | Flat | Raw | 9 | POLY_FT4 | | ||
| + | | 30h | Triangle | Gouraud | None | 6 | POLY_G3 | | ||
| + | | 34h | Triangle | Gouraud | Modulated | 9 | POLY_GT3 | | ||
| + | | 38h | Quadrilateral | Gouraud | None | 8 | POLY_G4 | | ||
| + | | 3Ch | Quadrilateral | Gouraud | Modulated | 12 | POLY_GT4 | | ||
| + | |||
| + | Adding 2 to a code sets ABE and therefore makes the polygon semi-transparent. The word counts follow from the vertex words above: a Gouraud-shaded textured quadrilateral, for example, needs 4 x 3 = 12 words.[^spx-poly] | ||
| + | |||
| + | ### Example | ||
| + | |||
| + | A flat triangle takes a command word followed by one word for each vertex. The coordinates in these words are hexadecimal values:[^spx-poly] | ||
| + | |||
| + | Table: Flat triangle example | ||
| + | |||
| + | | Word | Value | | ||
| + | | --- | --- | | ||
| + | | Command and color | 200000FFh | | ||
| + | | Vertex 0 | 00100020h | | ||
| + | | Vertex 1 | 00300040h | | ||
| + | | Vertex 2 | 00500060h | | ||
| + | |||
| + | ### Polygon Notes | ||
| + | |||
| + | A polygon is drawn up to its lower-right coordinates, but the lower-right edge itself is excluded (see Drawing Rules below). The GPU draws a quadrilateral as two triangles, the first from vertices 1, 2 and 3 and the second from vertices 2, 3 and 4. Because colors are interpolated within each triangle, this split affects the shading of a Gouraud-shaded quadrilateral.[^spx-poly] | ||
| + | |||
| + | The order of the vertices within a triangle does not matter to the GPU. Consequently, a front and back check based on clockwise or counter-clockwise order must be performed on the GTE side. Dithering applies to a polygon only when it uses Gouraud shading or modulation.[^spx-poly] | ||
| + | |||
| + | ## Line Commands | ||
| + | |||
| + | A line command draws a single line or a series of lines joined end to end (a polyline). The first word of the command holds the following fields:[^spx-line] | ||
| + | |||
| + | Table: Line command word | ||
| + | |||
| + | | Bits | Name | Content | | ||
| + | | --- | --- | --- | | ||
| + | | 0 to 7 | R0 | Red of the line color, or of vertex 0 with Gouraud shading | | ||
| + | | 8 to 15 | G0 | Green of the line color, or of vertex 0 with Gouraud shading | | ||
| + | | 16 to 23 | B0 | Blue of the line color, or of vertex 0 with Gouraud shading | | ||
| + | | 24 | | Unused | | ||
| + | | 25 | ABE | Semi-transparency (0 = off, 1 = on) | | ||
| + | | 26 | | Unused | | ||
| + | | 27 | PLL | Vertex count (0 = single line, 1 = polyline) | | ||
| + | | 28 | IIP | Shading (0 = flat, 1 = Gouraud) | | ||
| + | | 29 to 31 | CODE | Command group, always 2 | | ||
| + | |||
| + | Each vertex then sends a vertex word, preceded by a color word from the second vertex on when Gouraud shading is used. The command codes are as follows:[^spx-line] | ||
| + | |||
| + | Table: Line command codes | ||
| + | |||
| + | | Code | Type | Shading | libgpu primitive | | ||
| + | | --- | --- | --- | --- | | ||
| + | | 40h | Single line | Flat | LINE_F2 | | ||
| + | | 48h | Polyline | Flat | | | ||
| + | | 50h | Single line | Gouraud | LINE_G2 | | ||
| + | | 58h | Polyline | Gouraud | | | ||
| + | |||
| + | Adding 2 to a code sets ABE.[^spx-line] Libgpu also provides LINE_F3, LINE_G3, LINE_F4 and LINE_G4, which draw 2 and 3 lines joined end to end.[^lo810] | ||
| + | |||
| + | ### Polyline Terminator | ||
| + | |||
| + | A polyline must be sent at least 2 vertices, and its vertex list has no count. Instead, a word for which (word AND F000F000h) = 50005000h ends the list. The terminator takes the place of the first word of a vertex, which is the color word when Gouraud shading is used.[^spx-line] | ||
| + | |||
| + | ### Line Notes | ||
| + | |||
| + | Unlike a polygon, a line is drawn up to and including its lower-right coordinates. When the 2 vertices of a line are equal, the GPU draws a 1 x 1 rectangle in the color of the first vertex. With dithering enabled every line is dithered, flat or Gouraud-shaded, which differs from flat polygons and rectangles. A polyline whose last vertex equals its first vertex draws a wire-frame polygon.[^spx-line] | ||
| + | |||
| + | ## Rectangle Commands | ||
| + | |||
| + | A rectangle command draws a rectangle with horizontal and vertical edges. Libgpu calls a texture-mapped rectangle a sprite (SPRT) and a solid one a tile (TILE).[^lo810] The first word of the command holds the following fields:[^spx-rect] | ||
| + | |||
| + | Table: Rectangle command word | ||
| + | |||
| + | | Bits | Name | Content | | ||
| + | | --- | --- | --- | | ||
| + | | 0 to 7 | R0 | Red of the rectangle color, ignored when TGE is 1 | | ||
| + | | 8 to 15 | G0 | Green of the rectangle color, ignored when TGE is 1 | | ||
| + | | 16 to 23 | B0 | Blue of the rectangle color, ignored when TGE is 1 | | ||
| + | | 24 | TGE | Texture color mode (0 = modulated, 1 = raw texture) | | ||
| + | | 25 | ABE | Semi-transparency (0 = off, 1 = on) | | ||
| + | | 26 | TME | Texture mapping (0 = off, 1 = on) | | ||
| + | | 27 to 28 | SIZ | Size (0 = variable, 1 = 1 x 1, 2 = 8 x 8, 3 = 16 x 16) | | ||
| + | | 29 to 31 | CODE | Command group, always 3 | | ||
| + | |||
| + | The command is followed by these words:[^spx-rect] | ||
| + | |||
| + | Table: Rectangle words | ||
| + | |||
| + | | Word | Format | Present | | ||
| + | | --- | --- | --- | | ||
| + | | Command and color | ccBBGGRR | Always | | ||
| + | | Vertex | YYYYXXXX | Always, the upper-left corner | | ||
| + | | Texture coordinate | ClutVVUU | Textured rectangles only | | ||
| + | | Width and height | YsizXsiz | Variable size only, up to 1023 x 511 | | ||
| + | |||
| + | Table: Rectangle command codes | ||
| + | |||
| + | | Code | Size | Texture | libgpu primitive | | ||
| + | | --- | --- | --- | --- | | ||
| + | | 60h | Variable | None | TILE | | ||
| + | | 64h | Variable | Modulated | SPRT | | ||
| + | | 65h | Variable | Raw | SPRT | | ||
| + | | 68h | 1 x 1 | None | TILE_1 | | ||
| + | | 70h | 8 x 8 | None | TILE_8 | | ||
| + | | 74h | 8 x 8 | Modulated | SPRT_8 | | ||
| + | | 78h | 16 x 16 | None | TILE_16 | | ||
| + | | 7Ch | 16 x 16 | Modulated | SPRT_16 | | ||
| + | |||
| + | Adding 2 to a code sets ABE.[^spx-rect] The libgpu names are those of the sprite primitive table.[^lo810] | ||
| + | |||
| + | ### Rectangle Notes | ||
| + | |||
| + | Unlike a polygon, a rectangle has no texture page field. Therefore the current texture page must be set before a sprite is drawn, either in the drawing environment or with a DR_MODE primitive, which sends GP0(E1h).[^spx-rect][^lo823] A rectangle is drawn much faster than a polygon because the GPU draws it as a single shape without splitting it into triangles. However, a rectangle cannot use Gouraud shading, it is not dithered, and its texture cannot be rotated or scaled.[^spx-rect] | ||
| + | |||
| + | The size of a variable rectangle can reach 1023 x 511, while the texture window is at most 256 x 256; a larger rectangle therefore repeats its texture. The U coordinate and the width of a textured rectangle must be even, because an odd value causes a one-pixel sampling error every 16 pixels.[^spx-rect] | ||
| + | |||
| + | Bits 12 and 13 of GP0(E1h) flip the texture of a rectangle in X and Y on the v2 GPU, and they affect rectangles only. psx-spx reports that older consoles may lack the flip bits and names the PU-7 board as a possible case.[^spx-rect] Sony does not document the flip bits. Its developer FAQ instead flips a sprite by drawing a POLY_FT4 with the (u, v) values swapped. A POLY_FT4 is drawn at about half the speed of a sprite.[^faq14] | ||
| + | |||
| + | ## Attributes | ||
| + | |||
| + | ### Vertex | ||
| + | |||
| + | Table: Vertex word | ||
| + | |||
| + | | Bits | Content | | ||
| + | | --- | --- | | ||
| + | | 0 to 10 | X coordinate, signed, -1024 to +1023 | | ||
| + | | 11 to 15 | Not used, ignored by the GPU | | ||
| + | | 16 to 26 | Y coordinate, signed, -1024 to +1023 | | ||
| + | | 27 to 31 | Not used, ignored by the GPU | | ||
| + | |||
| + | The drawing offset set by GP0(E5h) is added to each vertex before drawing. Two vertices may be at most 1023 apart horizontally and 511 apart vertically, and a polygon or line that exceeds these limits is not drawn at all. For example, a line from Y = -300 to Y = +300 spans 600 lines and is not drawn, while a line from Y = -100 to Y = +400 spans 500 lines and is drawn. When part of a shape lies outside the drawing area, the GPU draws only the part inside it.[^spx-attr] | ||
| + | |||
| + | ### Color | ||
| + | |||
| + | Table: Color word | ||
| + | |||
| + | | Bits | Content | | ||
| + | | --- | --- | | ||
| + | | 0 to 7 | Red, 0 to FFh | | ||
| + | | 8 to 15 | Green, 0 to FFh | | ||
| + | | 16 to 23 | Blue, 0 to FFh | | ||
| + | | 24 to 31 | Command in the first word, ignored in later words | | ||
| + | |||
| + | For an untextured shape FFh is the brightest value. For a modulated texture, however, 80h leaves the texel unchanged, and values from 81h to FFh make it up to about twice as bright; the result saturates at 1Fh in each 5-bit channel.[^spx-attr] Sony states the same rule: if the r, g and b members of a primitive are all 128, the pixels drawn have the brightness of the source texture, and a result above 255 is clipped to 255.[^lo825] | ||
| + | |||
| + | ### Texture Page Attribute | ||
| + | |||
| + | The upper half of the texture coordinate word of vertex 1 is the texture page attribute. Its fields are those of GP0(E1h) except for the bits marked unused:[^spx-poly] | ||
| + | |||
| + | Table: Texture page attribute | ||
| + | |||
| + | | Bits | Content | | ||
| + | | --- | --- | | ||
| + | | 0 to 8 | Same as GP0(E1h) bits 0 to 8 | | ||
| + | | 9 to 10 | Unused, GP0(E1h) bits 9 to 10 stay unchanged | | ||
| + | | 11 | Same as GP0(E1h) bit 11 | | ||
| + | | 12 to 13 | Unused, GP0(E1h) bits 12 to 13 stay unchanged | | ||
| + | | 14 to 15 | Unused, should be 0 | | ||
| + | |||
| + | A textured polygon command therefore also changes the current texture page, except for the dither and draw-to-display bits, which only GP0(E1h) can change.[^spx-attr][^spx-env] | ||
| + | |||
| + | ### CLUT Attribute | ||
| + | |||
| + | The upper half of the texture coordinate word of vertex 0 gives the position of the CLUT in VRAM, which Sony calls the CBA parameter of the drawing command. It is used only by 4-bit and 8-bit textures.[^spx-attr][^hw36] | ||
| + | |||
| + | Table: CLUT attribute | ||
| + | |||
| + | | Bits | Name | Content | | ||
| + | | --- | --- | --- | | ||
| + | | 0 to 5 | CLX | X coordinate divided by 16 | | ||
| + | | 6 to 14 | CLY | Y coordinate, 0 to 511 | | ||
| + | | 15 | | Unused, should be 0 | | ||
| + | |||
| + | On a v2 GPU with 2 MB VRAM, CLY occupies bits 6 to 15 and ranges from 0 to 1023. A CLUT therefore starts at an X coordinate that is a multiple of 16.[^spx-attr] | ||
| + | |||
| + | ## Drawing Rules | ||
| + | |||
| + | The GPU draws the pixels whose centers lie within the boundary of the polygon vertices. When the center of a pixel lies outside this area, the following rules decide whether it is drawn:[^lo813] | ||
| + | |||
| + | Table: Boundary pixel rules | ||
| + | |||
| + | | Pixel inside the drawing area | Boundary pixel | | ||
| + | | --- | --- | | ||
| + | | To the right | Drawn | | ||
| + | | To the left | Not drawn | | ||
| + | | Above | Not drawn | | ||
| + | | Below | Drawn | | ||
| + | |||
| + | As a result, the rightmost and lowest points of a POLY_* primitive are not drawn. This ensures that pixels on a shared boundary are not drawn twice when polygons are placed next to each other, which matters in semi-transparent mode.[^lo813] | ||
| + | |||
| + | The rule also applies to texture coordinates. A 16 x 16 texture on a 16 x 16 polygon therefore needs (u, v) from (0, 0) to (16, 16); with (0, 0) to (15, 15) the bottom and right lines of the texture are not displayed.[^lo834] Because u and v are 8-bit values, 256 cannot be specified, and the lines u = 255 and v = 255 at the right and bottom of a texture page cannot be displayed by a polygon enlarged two times or more.[^lo839] | ||
| + | |||
| + | ## References | ||
| + | |||
| + | [^spx-io]: psx-spx. Graphics Processing Unit (GPU), GPU I/O Ports, DMA Channels, Commands, VRAM. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-io-ports-dma-channels-commands-vram | ||
| + | [^spx-sum]: psx-spx. Graphics Processing Unit (GPU), GPU Command Summary. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-io-ports-dma-channels-commands-vram | ||
| + | [^spx-poly]: psx-spx. Graphics Processing Unit (GPU), GPU Render Polygon Commands. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-render-polygon-commands | ||
| + | [^spx-line]: psx-spx. Graphics Processing Unit (GPU), GPU Render Line Commands. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-render-line-commands | ||
| + | [^spx-rect]: psx-spx. Graphics Processing Unit (GPU), GPU Render Rectangle Commands. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-render-rectangle-commands | ||
| + | [^spx-attr]: psx-spx. Graphics Processing Unit (GPU), GPU Rendering Attributes. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-rendering-attributes | ||
| + | [^spx-env]: psx-spx. Graphics Processing Unit (GPU), GP0(E1h) - Draw Mode setting. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-rendering-attributes | ||
| + | [^hw36]: Sony Computer Entertainment Inc. PlayStation Hardware. August 1998. Page 3-6. | ||
| + | [^lo84]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-4. | ||
| + | [^lo89]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-9, Table 8-3. | ||
| + | [^lo810]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-10, Table 8-4, Table 8-5. | ||
| + | [^lo813]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-13, Figure 8-5. | ||
| + | [^lo823]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-23. | ||
| + | [^lo825]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-25. | ||
| + | [^lo834]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Pages 8-34 to 8-35. | ||
| + | [^lo839]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-39. | ||
| + | [^faq14]: Sony Computer Entertainment. The Un-official PlayStation Development FAQ, LIBGPU Conference. Release v1.1. August 31, 1995. Item 1.4.1. | ||