Basic Graphics Library (libgpu)
Provides functions for drawing primitives such as sprites, polygons and lines.
| Library | libgpu.lib |
|---|---|
| Header File | libgpu.h |
| SDK | Psy-Q |
Overview
The Basic Graphics Library (libgpu) is a low-level function library for drawing primitives such as triangles, rectangles and sprites with the GPU. It provides system functions that control the whole graphics system, frame buffer access functions that read and write the frame buffer directly, and primitive functions that initialize primitive structures and set the texture page. It also provides ordering table functions, which register primitives in an ordering table and draw them, and synchronization functions, which wait for the vertical blank period and for the end of drawing.12
A program that uses libgpu links with libgpu.lib and includes libgpu.h.3
This library is part of the run-time library that Sony distributed with the Psy-Q development tools.4
Graphics System
The graphics system consists of the GPU and a 1 MB frame buffer together with the GTE. The frame buffer holds the current display, a drawing area, textures and color tables, and the GPU can use the results of GTE calculations in its commands.1
The GPU draws into the drawing area of the frame buffer by executing instruction strings (primitives) stored in main memory, and the data structures of libgpu correspond to the primitives of the GPU hardware. The video signal is made continuously from the frame buffer, so rewriting the frame buffer up to 60 times per second produces moving images. The graphics system has no separate background plane.5
Frame Buffer Addressing
The frame buffer is a bitmap 1024 pixels wide and 512 pixels tall with 16 bits per pixel. Its total size is therefore one megabyte (1024 x 512 pixels x 2 bytes per pixel). It stores texture patterns and color lookup tables (CLUTs) as well as the drawing and display areas.5
A pixel is addressed by X from 0 to 1023 and Y from 0 to 511. Each pixel has 5 bits for blue, 5 bits for green and 5 bits for red, and the high-order bit is the semi-transparent flag (STP):56
| Bit | 15 | 14 to 10 | 9 to 5 | 4 to 0 |
|---|---|---|---|---|
| Contents | STP | Blue | Green | Red |
Display Area and Drawing Area
The display area is the rectangle of the frame buffer that is shown on the screen. Its size depends on the display mode, from 256 x 240 to 640 x 480 (709 x 488 with overscan), and the following values can be combined:6
| Item | Values |
|---|---|
| Width | 256, 320, 360, 512, 640 |
| Height | 240 (interlace off), 480 (interlace on) |
| Pixel mode | 24-bit, 16-bit |
| Interlace | On, off (must be off in 480-line mode) |
The heights assume NTSC. PAL is described under PAL Format below.6
The drawing area is the rectangle of the frame buffer into which primitives are drawn, and it may be any size that fits in the frame buffer. When the drawing area overlaps the display area, the drawing shows on the screen. A program therefore prepares two areas of the same size, draws into one while the other is displayed, and switches them in the vertical blank period to avoid flashing and tearing.6
Drawing Environment
A DRAWENV structure holds the drawing environment, which is the set of settings for two-dimensional drawing such as the position of the drawing area and the drawing offset. SetDefDrawEnv() sets the members of a DRAWENV, PutDrawEnv() makes it the current drawing environment and GetDrawEnv() returns the current one. DRAWENV has the following members:67
| Member | Contents |
|---|---|
| clip | Drawing (clipping) area (clip.x, clip.y) to (clip.x + clip.w, clip.y + clip.h) |
| ofs[0], ofs[1] | Offsets added to the X and Y of all primitives before drawing |
| tw | Texture window inside the texture page |
| tpage | Default texture page. One texture page is 256 x 256 pixels. |
| dtd | Dithering when 1 |
| dfe | Drawing in the display area is permitted when 1. By default it is blocked. |
| isbg | The clipping area is cleared to r0, g0, b0 when the environment is set |
| r0, g0, b0 | Background color for the clear |
A new drawing environment set with PutDrawEnv() during drawing does not affect the primitive being executed or the rest of the current list. It takes effect with the next drawing operation. A program can also change all or part of the drawing environment in the middle of drawing by registering a special primitive in the ordering table.8
Display Environment
A DISPENV structure holds the display environment, which is the set of display settings such as the position of the display area. SetDefDispEnv() sets its members, PutDispEnv() makes it current and GetDispEnv() returns the current one. DISPENV has the following members:7
| Member | Contents |
|---|---|
| disp | Display area in the frame buffer. The width is 256, 320, 360, 512 or 640 and the height 240 or 480. |
| screen | Position of the display area on the monitor screen. The standard is (0, 0) to (256, 240). |
| isinter | Interlace mode when 1. A height of 480 is always interlaced. |
| isrgb24 | 24-bit pixel format when 1 |
A smaller screen area gives an underscan and a larger one an overscan, but the size of each pixel does not change. Settings in the display environment take effect at once. Consequently, the display position and area can change while drawing goes on in the background.78
Double Buffer
A double buffer uses two areas of the frame buffer that change places between the display environment and the drawing environment. For example, with buffer 0 at (0, 0) to (320, 240) and buffer 1 at (0, 240) to (320, 480), the environments are set as follows:8
| Setting | Buffer 0 | Buffer 1 | Notes |
|---|---|---|---|
| Drawing environment (clip.x, clip.y) | (0, 0) | (0, 240) | Clip start point |
| Drawing environment (ofs[0], ofs[1]) | (0, 0) | (0, 240) | Drawing offset |
| Display environment (disp.x, disp.y) | (0, 240) | (0, 0) | Display area origin |
In 640 x 480 interlace mode the frame buffer has no room for two buffers, so a single buffer is used for both drawing and display. In each 1/60 second field the display shows either the odd or the even lines. With dfe set to 0 the GPU then draws only on the lines that are not being displayed, which is equivalent to double buffer switching, provided that drawing completes within 1/60 second.9
Blocking and Non-Blocking Functions
A blocking function completes its processing before it returns. Several drawing functions take a long time, and these are processed in the background and return without waiting for completion. They are called non-blocking functions:9
| Function | Contents |
|---|---|
| LoadImage() | Transfer from main memory to frame buffer |
| StoreImage() | Transfer from frame buffer to main memory |
| MoveImage() | Transfer from frame buffer to frame buffer |
| DrawPrim() | Draw a primitive |
| DrawOTag() | Execute a list of GPU primitives |
All other functions are blocking functions, and DrawSync() detects or waits for the end of the non-blocking ones. Up to 64 non-blocking requests may wait in the queue. When DrawOTag(ot1) is called before DrawOTag(ot0) has finished, the request is registered in the queue and the function returns at once, and a 65th request blocks until the queue has room.910
Primitives
A primitive (or packet) is the smallest command the graphics system handles. Primitives are data structures created in main memory, and the CPU and the GPU may refer to them at the same time. Drawing primitives draw pixels in the frame buffer. Special primitives change parameters of the GPU, such as the clipping area and the texture page, during drawing, and do not change the frame buffer themselves.10
There are four types of drawing primitive: polygon, line, sprite and tile. A polygon has 3 or 4 sides, flat or Gouraud shading and texture mapping on or off, which gives eight polygon primitives. Tiles are drawn in a solid color, while sprites are texture-mapped.1011
| Primitive name | Contents |
|---|---|
| POLY_F3, POLY_F4 | Triangle, quadrilateral, flat shaded |
| POLY_FT3, POLY_FT4 | Triangle, quadrilateral, flat shaded, textured |
| POLY_G3, POLY_G4 | Triangle, quadrilateral, Gouraud shaded |
| POLY_GT3, POLY_GT4 | Triangle, quadrilateral, Gouraud shaded, textured |
| LINE_F2 | A straight line between two points |
| LINE_F3, LINE_F4 | Two or three connected lines |
| LINE_G2, LINE_G3, LINE_G4 | The same as LINE_F2 to LINE_F4, with color gradation |
| SPRT | Texture-mapped sprite of free size |
| SPRT_8, SPRT_16 | Texture-mapped sprite of 8 x 8 or 16 x 16 pixels |
| TILE | Solid color tile of free size |
| TILE_1, TILE_8, TILE_16 | Solid color tile of 1 x 1, 8 x 8 or 16 x 16 pixels |
Special primitives change all or part of the drawing environment during drawing:11
| Primitive name | Parameter changed | DRAWENV members |
|---|---|---|
| DR_ENV | Drawing environment | All members |
| DR_MODE | Drawing and texture mode | tpage, dtd, dfe, tw |
| DR_TWIN | Texture window | tw |
| DR_AREA | Drawing area | clip |
| DR_OFFSET | Drawing offset | ofs |
Primitive Format
Primitives are C structures, and the first two words of every drawing primitive are the same. The tag word links primitives into a list so that several primitives execute together. Its top 8 bits hold the number of GPU words in the packet and its bottom 24 bits point to the next primitive. The code member holds the primitive identifier, which is a value reserved for the library.1112
The members of POLY_FT4 show the general form:12
| Member | Contents |
|---|---|
| tag | Number of GPU words and pointer to the next primitive |
| code | Primitive identifier |
| r0, g0, b0 | Display color, 0 to 255 |
| tpage | Texture page ID |
| clut | CLUT ID |
| x0, y0 to x3, y3 | Screen coordinates of the vertices |
| u0, v0 to u3, v3 | Texture page coordinates of the texture |
A primitive must be initialized before it is executed. The initializing function of each primitive type, such as SetPolyFT4(), sets the tag, code and pad members, and the other members may then be written freely. libgpu.h defines macros for setting the members.12
Between initialization and execution, SetSemiTrans() sets the semi-transparent attribute and SetShadeTex() inhibits shading of a texture. MargePrim() joins two primitives into a single new primitive of at most 16 long words. AddPrim() and DrawPrim() handle the result like any other primitive.13
DrawPrim() executes one primitive. Because a primitive is drawn on top of the primitives executed before it, the order of execution sets the display priority. Many primitives are therefore usually registered in an ordering table and executed together with DrawOTag().13
Primitive Drawing Rules
The GPU draws the pixels whose centers lie inside the boundary of the primitive. For a pixel center on the boundary, the pixel is drawn when the inside lies to its right or below it, and not drawn when the inside lies to its left or above it. Consequently, POLY primitives do not draw their extreme right and lowest points, and pixels along the edge shared by adjacent polygons are not drawn twice.14
Ordering Tables
The ordering table (OT) controls the order of execution of many primitives. It is an array of pointers to primitives in main memory and is a form of list designed for inserting the primitives of a three-dimensional scene. Its size is the number of priority levels needed. An OT of 256 entries gives 256 levels of priority.14
ClearOTag() initializes the array so that each entry points to the next and the last entry holds a terminator. AddPrim() or AddPrims() registers primitives in the entries, and DrawOTag() executes them. Because DrawOTag() is a non-blocking function, the CPU continues its work while the GPU draws.14
The primitives at the start of the OT are executed first and therefore appear furthest back. Several primitives may share one entry, and in that case the primitive registered last in the entry executes first. Special primitives registered in the OT affect the primitives that follow them.15
A program may also chain primitives to each other without an OT and execute the list with DrawOTag(). Such a list loses the flexibility of the OT.1516
Z Sorting
An OT implements Z sorting, which removes hidden surfaces by ordering the primitives by depth. The position of a primitive in the OT is computed from its Z value. Many libgte functions such as RotTransPers() return this index (otz) together with the coordinate transformation. The otz value is the Z coordinate divided by 4, so an OT of 1/4 the dynamic range of Z is sufficient.16
Because otz is large for distant objects, it would have to be inverted before use as an index. ClearOTagR() avoids this by initializing the OT in reverse order, which also changes the other calls:16
| Using ClearOTag() | Using ClearOTagR() |
|---|---|
| ClearOTag(ot, OTSIZE) | ClearOTagR(ot, OTSIZE) |
| AddPrim(ot + OTSIZE - otz, &prim) | AddPrim(ot + otz, &prim) |
| DrawOTag(ot) | DrawOTag(ot + OTSIZE - 1) |
The normal OT suits two-dimensional sprite games and the reverse OT suits three-dimensional graphics. The reverse OT is initialized by a high-speed hardware function and the normal OT by software, so a large OT is initialized much faster in reverse order.17
To display a three-dimensional object, the object is broken into triangles and quadrilaterals, and the geometry library converts each vertex to screen coordinates. The screen position is h x Sx / Sz and h x Sy / Sz, where h is the distance from the viewpoint to the screen, and the OT index is Sz / 4.17
AddPrims() inserts an entire OT into another OT. This serves when more than one hierarchical coordinate system is in use. The link of the last entry of the child OT is replaced in this case, so no primitive may be registered in that entry.18
Reset
ResetGraph() resets the graphics system. Every level stops the drawing command in progress, cancels the requests in the queue and enters wait status. The levels differ in what they keep:18
| Reset level | Callback | DISPENV | DRAWENV | Command queue |
|---|---|---|---|---|
| 0 | Initialize | Initialize | Initialize | Initialize |
| 1 | Save | Save | Save | Initialize |
| 3 | Initialize | Save | Save | Initialize |
Level 0 is a complete reset that is executed once when the program starts. It sets the display mode to 256 x 240 and masks the display. Level 1 is used often when switching the double buffer. Level 3 is used at the start of a child process started with Exec(), because it switches the callbacks without disturbing the display set by the parent.18
Synchronization
A program detects the end of background work by polling or by callbacks. DrawSync() and VSync() poll as follows:19
| Call | Result |
|---|---|
| DrawSync(0) | Blocks until all requests in the queue are finished |
| DrawSync(1) | Returns the number of positions in the drawing queue |
| VSync(0) | Blocks until the next vertical blank period begins |
| VSync(1) | Returns the horizontal sync units since the last VSync(0) or VSync(n) |
| VSync(n) | Waits for the nth vertical blank period after the last call |
| VSync(-n) | Returns the number of vertical blank periods since the program started |
DrawSyncCallback() defines a function called when a non-blocking drawing operation such as DrawOTag() completes. VSyncCallback() defines a function called at the start of each vertical blank period, which can switch the display buffers and perform other work that must be synchronized with the display. VSync() and VSyncCallback() are part of libetc.1920
To avoid flicker, the drawing and display buffers are switched at the vertical synchronization with DrawSync() and VSync(). Drawing at 60 frames per second is achieved only when the CPU work of each frame ends within 1/60 second.2122
Packet Double Buffer
The memory for the OT and primitives is the packet buffer. The CPU cannot change the primitives and the OT until the graphics system has finished with them, so a single packet buffer prevents the CPU and the GPU from working in parallel. With two packet buffers, the CPU generates the OT and primitives in one while the GPU executes the other, and the two exchange tasks each frame. This is the packet double buffer.2223
In interlace mode the drawing must be updated every 1/60 second regardless of the calculation time. A callback can then issue DrawOTag() in each field, and when the new OT is not ready in time the previous OT is drawn again.2324
Texture Mapping
Texture mapping maps a two-dimensional bitmap called a texture pattern onto triangles and quadrilaterals. Textures are stored in texture pages, which are 256 x 256 bitmaps in the frame buffer outside the display and drawing areas. The X coordinate of a texture page is a multiple of 64 and the Y coordinate a multiple of 256, so texture pages may overlap horizontally.24
Each primitive may use one of three texture pattern modes:24
| Mode | Type | Colors | Texture page width |
|---|---|---|---|
| 4-bit | CLUT-based | 16 | 64 |
| 8-bit | CLUT-based | 256 | 128 |
| 16-bit | Direct RGB | 32767 | 256 |
In 16-bit mode the texel is used directly. It has 15 bits of RGB and 1 semi-transparent bit. The 4-bit and 8-bit modes use each texel as an index into a CLUT, which is a horizontal row of 16-bit pixels in the frame buffer with 16 or 256 entries. A 16-bit word holds one 16-bit texel or two 8-bit texels or four 4-bit texels. Consequently, a 256 x 256 texture page occupies from 256 x 256 (16-bit mode) to 64 x 256 (4-bit mode) of the frame buffer.24
LoadImage(), MoveImage() and StoreImage() address the frame buffer in 16-bit pixels, so the width of a 4-bit texture is divided by 4 and the width of an 8-bit texture by 2. An 8-bit texture is therefore a multiple of 2 pixels wide and a 4-bit texture a multiple of 4. LoadTPage() and LoadClut() load a texture page and a CLUT and return their IDs. Each primitive sets its own CLUT, several textures may share one CLUT, and a 4-bit texture can use any 16 entries of a larger CLUT.25
Unlike a polygon, a sprite primitive (SPRT) does not specify a texture page. The current texture page must therefore be correct when sprites execute. The drawing environment sets the first current texture page and a DR_MODE primitive changes it.2526
Transparent and Semi-Transparent Pixels
Bit 15 of each texel, or of its CLUT entry in 4-bit and 8-bit mode, is the semi-transparent (STP) bit. A texel of 0x0000 is transparent and is not drawn. A texel with STP set is semi-transparent when the primitive is set semi-transparent with SetSemiTrans(), and a texel with STP clear and a non-zero color is always opaque:26
| STP, B, G, R | Non-transparent primitive | Semi-transparent primitive |
|---|---|---|
| (0, 0, 0, 0) | Transparent | Transparent |
| (1, 0, 0, 0) | Black | Semi-transparent black |
| (0, n, n, n) | Non-transparent | Non-transparent |
| (1, n, n, n) | Non-transparent | Semi-transparent |
A primitive without texture mapping may also be set semi-transparent, and all its pixels are then semi-transparent. Semi-transparent drawing is much slower, because the existing pixels in the frame buffer must be read, processed and written back. The rate is chosen per primitive from the following, through the texture page or a DR_MODE primitive, and a brightness above the maximum is clipped:26
| Background brightness | Primitive brightness |
|---|---|
| 0.5 | 0.5 |
| 1.0 | 1.0 |
| 1.0 | -1.0 |
| 1.0 | 0.25 |
Texture Brightness
The r, g and b members of a textured primitive scale the brightness of its texels. With all three set to 128 the pixels are drawn at the brightness of the source texture, and a result above 255 is clipped to 255. A program sets r, g and b when it initializes a textured primitive, or turns the scaling off with SetShadeTex().2627
Texture Window
A texture window is part of a texture page within which a texture pattern repeats. It is set by the tw member of DRAWENV or by a DR_MODE primitive. The normal window is (0, 0) to (255, 255), which does not repeat, and a smaller window repeats the texture as needed. The U and V coordinates of the primitive must lie inside the window.27
Texture Cache
The GPU must read the texture pattern from the frame buffer to draw a textured polygon. To speed this up, it has a 2 KB texture cache, and texels that are already in the cache are read from it much faster than from the frame buffer. The cache uses two-dimensional addresses like the frame buffer, and its size depends on the pixel mode:2728
| Pixel mode | Size (width x length) |
|---|---|
| 4 bit/pixel | 64 x 64 |
| 8 bit/pixel | 64 x 32 |
| 16 bit/pixel | 32 x 32 |
A texture page is divided into cache blocks the size of the cache, so in 4-bit mode a page has 16 blocks. Each block is divided further into cache entries, and there are always 256 entries:2930
| Mode | Block | Number of blocks | Entry | Number of entries |
|---|---|---|---|---|
| 4 | 64 x 64 | 16 | 16 x 1 | 256 |
| 8 | 64 x 32 | 32 | 8 x 1 | 256 |
| 16 | 32 x 32 | 64 | 4 x 1 | 256 |
An entry holds 4 short words, so a 4-bit entry holds 16 texels, and each entry also holds the block number that decides a hit or a miss. Because each entry stores its own block number, texels of different blocks stay in the cache together as long as their entry numbers differ. For example, the cache holds all the texels of the rectangle (16, 16) to (79, 79) at once. The rows (8, 8) to (15, 8) and (64, 8) to (71, 8) use the same entries. Consequently, the cache cannot hold all the texels of the rectangle (8, 8) to (71, 71) at once.3130
Rendering Speed
DrawSync() shows whether the CPU or the GPU limits the speed. When the CPU is the bottleneck DrawSync() returns at once, and when the GPU is the bottleneck it blocks, and the time it waits measures the GPU latency. In the latter case optimizing the program code does not help.28
Rendering speed depends on the number of reads and writes to VRAM. A larger primitive writes more VRAM and takes longer, and semi-transparent drawing is slower than opaque drawing because it also reads. For the same area, TILE is fastest, followed by POLY_F and POLY_G and then the textured primitives. A texture cache hit is always faster, and on a miss 4-bit textures are faster than 8-bit and 8-bit faster than 16-bit.2832
The access cycles of the frame buffer are the following:32
| Access direction | Pixels per cycle | Notes |
|---|---|---|
| Write | 2 | SPRT, TILE, POLY_F3, POLY_F4 |
| Write | 1 | Other |
| Read | 1 | Texture mapping, semi-transparent rendering |
A 4-bit texel word holds four texels and an 8-bit word two, so one read fetches several texels. With 1:1 mapping, primitives of 100 x 100 pixels therefore take the following cycles:3233
| Primitive | 4-bit | 8-bit | 16-bit | Untextured |
|---|---|---|---|---|
| POLY_F4 | 5000 | |||
| POLY_G4 | 10000 | |||
| POLY_FT4, cache miss | 12500 | 15000 | 20000 | |
| SPRT, cache miss | 7500 | 10000 | 15000 | |
| SPRT, cache hit | 5000 | 5000 | 5000 |
A texture in the cache is drawn at the same speed in every mode. Reducing a texture by half horizontally does not halve the time, while an enlarged texture draws faster because the same texels are used several times. During clipping, the parts of a polygon to the left of and above the drawing area generate empty cycles, including empty texture reads.3329
Primitive Division
The PlayStation maps textures with an affine transformation, u = a0 x x + a1 x y + a2 and v = b0 x x + b1 x y + b2. This is correct only when the depth within the polygon is nearly constant. Consequently, a large quadrilateral with large depth changes, such as a ground surface, is drawn with a bent diagonal line.30
A large textured primitive also gains nothing from the texture cache. In 4-bit mode texels 64 apart share an entry. A primitive whose U or V spans more than 64 texels therefore always misses the cache. In the worst case, with the U and V directions at 90 degrees to X and Y, the speculatively read texels are flushed before use and the drawing speed halves. A large primitive also produces more empty clipping cycles, since it is less often entirely outside the drawing area.3034
Dividing a large primitive at its midpoints before drawing solves almost all of these problems. Perspective is calculated correctly at each new vertex, the U and V spans fall within the cache size, and more of the divided pieces fall wholly outside the drawing area.3435
Debug Environment
SetGraphDebug() sets the debug mode, in which each function checks its data as far as possible and prints a return code and the contents as a debug string. The Dump functions also print the contents of structures, and the Fnt functions display the strings on screen.35
libgpu has no functions for PlayStation data formats such as TIM and TMD. These formats are handled by libgs. OpenTIM(), ReadTIM(), OpenTMD() and ReadTMD() read the headers of TIM data and the polygons of TMD data for debugging the data only.35
Texture Polygon Coordinates
POLY primitives do not draw their right and bottom edges. Without this rule the edges shared by four adjacent polygons would be drawn twice, which would show in semi-transparent mode. As a consequence, an 8 x 8 POLY_FT4 must be given (x, y) = (0, 0) to (8, 8) and (u, v) = (0, 0) to (8, 8) to show all 8 x 8 texels. With (u, v) = (0, 0) to (7, 7) the last row and column of the texture are lost.363738
The same rule shifts a texture one dot when it is inverted or rotated by 90 degrees or more, and loses the right and bottom lines when a texture is enlarged two times or more. The lines at u = 255 and v = 255 cannot be shown in that case at all, because U and V are 8 bits and 256 overflows to zero. Subtracting 1 from U and V avoids these problems, but the texture is then drawn at 16:15 for a 16 x 16 pattern or 8:7 for an 8 x 8 pattern.394041
PAL Format
The descriptions above assume NTSC. PAL differs as follows:41
| Video format | NTSC | PAL |
|---|---|---|
| Field rate | 60 Hz | 50 Hz |
| Standard vertical resolution | 240 | 256 |
The PAL field rate is 50 Hz, so the maximum display rate is 50 frames per second, and a program timed by VSync runs at 5/6 of its NTSC speed. Its timing is therefore adjusted by 6/5. A PAL display also shows more lines, so the NTSC display area leaves the top or bottom of the screen dark. SetVideoMode(MODE_PAL) enables PAL mode, and the screen member of DISPENV centers the display.4142
Frame Buffer Update Timing
The display area may be updated at a rate different from the 1/60 second video rate. However, an update at an irregular rate makes the screen flicker, so buffer switching is synchronized with the vertical sync by a VSync(0). When the time to make a frame lies close to 1/60 second, the frame rate jitters between 60 and 30 frames per second and objects move unnaturally. VSync(2) fixes the rate at 30 frames per second. In the same way VSync(3) gives 20 frames per second and VSync(4) gives 15.4243
A program whose frame rate varies times its motion with an absolute counter such as VSync(-1) or RCnt3 instead of the frame count, so that objects move at the same speed when frames are skipped. In interlace mode, however, both calculation and rendering must end within 1/60 second, so VSync has priority over DrawSync and ResetGraph(1) cancels drawing that overruns the field.4344
VSync(1) returns the time since the last VSync(0) or VSync(n) in horizontal sync units. The value right after VSync(0) is not always close to 0, because sound callbacks and controller drivers run during the vertical blank.44
Interlace Mode Fields
In the interlace single buffer mode with 480 lines, the GPU draws only the even lines while an odd field is displayed and only the odd lines while an even field is displayed. During the vertical blank, however, the GPU always treats the field as even. VSyncCallback() runs at the start of the vertical blank, so the primitives drawn first, usually the background, reach only the even field and half of the background is not cleared.4445
Rendering must therefore start after the vertical blank ends. An H-Sync callback on RCnt2 can start it. GetODE(), introduced in library 3.7, returns the field that the GPU recognizes, which is not always the field of the video output.45
Structures
In the tables below, Introduced is the run-time library version that added the item.46
libgpu has the following structures:46
| Structure | Introduced | Purpose |
|---|---|---|
DISPENV |
2.x | Display environment. |
DRAWENV |
2.x | Drawing environment. |
DR_AREA |
3.0 | Drawing area change primitive. |
DR_ENV |
2.x | Drawing environment modification primitive. |
DR_LOAD |
3.4 | Load Image primitive. |
DR_MODE |
3.0 | Drawing mode modification primitive. |
DR_MOVE |
3.2 | Rectangle copy primitive. |
DR_OFFSET |
3.0 | Drawing offset modification primitive. |
DR_STP |
4.1 | STP bit updated primitive. |
DR_TPAGE |
3.5 | Texture page change primitive. |
DR_TWIN |
3.0 | Texture window change primitives. |
LINE_F2, LINE_F3, LINE_F4 |
2.x | One flat-shaded non-connecting line/ Two flat-shaded connected lines/ Three flat-shaded connected lines. |
LINE_G2, LINE_G3, LINE_G4 |
2.x | One Gouraud-shaded non-connecting line/ Two Gouraud-shaded connected lines/ Three Gouraud-shaded connected lines. |
POLY_F3, POLY_F4 |
2.x | Flat-shaded, non-textured mapped triangel/ Flat-shaded, not-textured mapped quad. |
POLY_FT3, POLY_FT4 |
2.x | Flat-shaded, texture-mapped triangle/ Flat-shaded, texture-mapped quad. |
POLY_G3, POLY_G4 |
2.x | Gouraud-shaded, non-textured mapped triangle/ Gouraud-shaded, non-textured mapped quad. |
POLY_GT3, POLY_GT4 |
2.x | Gouraud-shaded, texture-mapped triangle/ Gouraud-shaded, texture-mapped quad. |
RECT |
2.x | Frame buffer rectangular area. |
RECT32 |
4.3 | Rectangular area (32 bit). |
SPRT |
2.x | Sprite of any desired size. |
SPRT_8, SPRT_16 |
2.x | 8 x 8 fixed size, texture-mapped sprite / 16 x 16 fixed size, texture-mapped sprite. |
TILE |
2.x | Tile of any desired size. |
TILE_1, TILE_8, TILE_16 |
2.x | 1 x 1 fixed-size tile sprite / 8 x 8 fixed-size tile sprite / 16 x 16 fixed-size tile sprite. |
TIM_IMAGE |
2.x | TIM format image data header. |
TMD_PRIM |
2.x | TMD format model data header. |
Functions
libgpu has the following functions:47
| Function | Introduced | Purpose |
|---|---|---|
AddPrim, addPrim |
2.x | Register a primitive to the OT. |
AddPrims, addPrims |
2.x | Collectively register primitives to the OT. |
BreakDraw |
3.4 | Interrupt drawing. |
CatPrim, catPrim |
2.x | Concatenate primitives. |
CheckPrim |
2.x | Check validity of a primitive. |
ClearImage |
2.x | Clear Frame Buffer at high speed. |
ClearImage2 |
2.x | Clear Frame Buffer at high speed (interlace mode). |
ClearOTag |
2.x | Initialize an array to a linked list for use as an ordering table. |
ClearOTagR |
2.x | Initialize an array to a linked list for use as an ordering table. |
ContinueDraw |
2.x | Continue to draw the OT interrupted by BreakDraw(). |
DrawOTag |
3.0 | Execute a list of GPU primitives. |
DrawOTag2 |
4.1 | Execute a list of GPU primitives (immediate execution). |
DrawOTagEnv |
3.0 | Set the drawing environment and draw the primitives registered in the OT. |
DrawOTagIO |
3.0 | Draw the primitives registered in the OT. |
DrawPrim |
2.x | Draw a primitive. |
DrawSync |
2.x | Wait for all drawing to terminate. |
DrawSyncCallback |
2.x | Define a callback function to be called when the GPU is finished executing a primitive list. |
DumpClut, dumpClut |
2.x | Print contents of clut member of primitive. |
DumpDispEnv |
2.x | Print contents of display environment Structure. |
DumpDrawEnv |
2.x | Print contents of drawing environment structure. |
DumpOTag |
2.x | Print primitives registered in the OT. |
DumpTPage, dumpTPage |
2.x | Print contents of tpage member of primitive. |
FntFlush |
2.x | Draw contents of print stream. |
FntLoad |
2.x | Transmit font pattern. |
FntOpen |
2.x | Open a print stream. |
FntPrint |
2.x | Print a string. |
GetClut, getClut |
2.x | Calculate value of the CLUT member in a primitive. |
GetDispEnv |
2.x | Get current display environment. |
GetDrawArea |
4.3 | Get data for the current draw area. |
GetDrawEnv |
2.x | Get the current drawing environment. |
GetDrawMode |
4.3 | Get current draw mode data. |
GetDrawOffset |
4.3 | Get the current draw offset. |
GetGraphDebug |
3.0 | Get present debug level. |
GetODE |
2.x | Get field currently being drawn. |
GetTexWindow |
4.3 | Get current texture window data. |
GetTimSize |
3.0 | Calculate size of Tim data domain returned by Krom2Tim(). |
GetTPage, getTPage |
2.x | Calculate value of member tpage in a primitive. |
IsEndPrim, isendprim |
2.x | Determine if a primitive is the last in a list. |
IsIdleGPU |
3.6 | Check if drawing suspended by BreakDraw() was completed. |
KanjiFntClose |
3.0 | Close print streams. |
KanjiFntFlush |
3.0 | Draw contents of a Kanji print stream. |
KanjiFntOpen |
3.0 | Open a print stream. |
KanjiFntPrint |
3.0 | Print a string, in SJIS ZENKAKU format. |
Krom2Tim |
3.0 | Convert SJIS character string to 4-bit CLUT Tim data. |
LoadClut |
2.x | Load 256-color CLUT. |
LoadClut2 |
3.0 | Load 16-color CLUT. |
LoadImage |
2.x | Transfer data to a frame buffer. |
LoadImage2 |
4.1 | Transfer data to a frame buffer (immediate execution). |
LoadTPage |
2.x | Load a texture page. |
MargePrim |
3.0 | Link primitives. |
MoveImage |
2.x | Transfer data between two locations within the frame buffer. |
MoveImage2 |
4.1 | Transfer data between two locations within the frame buffer (immediate execution). |
NextPrim, nextPrim |
2.x | Get pointer to next primitive in primitive list. |
OpenTIM |
2.x | Open TIM data. |
OpenTMD |
2.x | Open TMD data. |
PutDispEnv |
2.x | Set the display environment. |
PutDrawEnv |
2.x | Set the drawing environment. |
ReadTIM |
2.x | Produce TIM header. |
ReadTMD |
2.x | Read contents of TMD primitives. |
ResetGraph |
2.x | Initialize drawing engine. |
SetDefDispEnv |
2.x | Set display environment structure members and screen display area. |
SetDefDrawEnv |
2.x | Set standard drawing environment structure. |
SetDispMask |
2.x | Set and cancel display mask. |
SetDrawArea |
2.x | Initialize content of drawing area setting primitive. |
SetDrawEnv |
2.x | Initialize content of drawing environment change primitive. |
SetDrawLoad |
2.x | Initialize content of the LoadImage primitive. |
SetDrawMode |
2.x | Initialize content of a drawing mode primitive. |
SetDrawMove |
2.x | Initialize rectangle copy primitive. |
SetDrawOffset |
2.x | Initialize drawing offset setting primitive. |
SetDrawStp |
4.1 | Initializes STP bit update primitive. |
SetDrawTPage, setDrawTPage |
2.x | Initialize texture page change primitive. |
SetDumpFnt |
2.x | Define stream for onscreen dump. |
SetGraphDebug |
2.x | Set debugging level. |
SetLineF2, SetLineF3, SetLineF4, setLineF2, setLineF3, setLineF4, SetLineG2, SetLineG3, SetLineG4, setLineG2, setLineG3, setLineG4 |
2.x | Initialize a line primitive. |
SetPolyF3, SetPolyF4, setPolyF3, setPolyF4, SetPolyG3, SetPolyG4, setPolyG3, setPolyG4, SetPolyGT3, SetPolyGT4, setPolyGT3, setPolyGT4 |
2.x | Initialize a polygon primitive. |
SetSemiTrans, setSemiTrans |
2.x | Set the semitransparent attribute of a primitive. |
SetShadeTex, setShadeTex |
2.x | Inhibit shading function. |
SetSprt, SetSprt8, SetSprt16, setSprt, setSprt8, setSprt16 |
2.x | Initialize a sprite primitive. |
SetTexWindow |
2.x | Initialize the content of a texture window primitive. |
SetTile, SetTile1, SetTile8, SetTile16, setTile, setTile1, setTile8, setTile16 |
2.x | Initialize a tile primitive. |
StoreImage |
2.x | Transfer image data from the frame buffer to main memory. |
StoreImage2 |
4.1 | Transfer data from a frame buffer (immediate execution). |
TermPrim, termPrim |
2.x | Terminate a primitive list. |
Macros
libgpu has the following macros:48
| Macro | Introduced | Purpose |
|---|---|---|
addVector |
2.x | Add vectors. |
applyVector |
3.4 | Apply arithmetic operation to a vector. |
copyVector |
2.x | Copy vectors. |
dumpMatrix |
4.3 | Display matrix contents. |
dumpRECT |
4.3 | Display contents of a rectangle. |
dumpVector |
4.3 | Display contents of vector. |
dump... |
4.3 | Display contents of a primitive. |
setClut |
4.3 | Set CLUT for primitive. |
setRECT |
2.x | Set rectangular area. |
setRGB0, setRGB1, setRGB2, setRGB3 |
2.x | Initialize RGB fields of a primitive. |
setTPage |
4.3 | Set texture page for primitive. |
setUV0, setUV3, setUV4 |
2.x | Set the u and v members of a primitive. |
setUVWH |
2.x | Set the u, v members of a primitive. |
setVector |
2.x | Set the values of a vector. |
setWH |
2.x | Set the w,h members of a primitive. |
setXY0, setXY2, setXY3, setXY4 |
2.x | Set the x and y parameters of a primitive. |
setXYWH |
4.3 | Set x, y members of a rectangular primitive. |
References
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-3.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page xi.
-
^ Sony Computer Entertainment Inc. Run-Time Library Reference. Run-Time Library 4.4. January 1999. Page 7-33.
-
^ Sony Computer Entertainment Inc. Programmer Tools CD (DTL-S2002), README.TXT. 11/26/96. Section "CD-ROM Contents - Highlights", directories \PSX and \PSYQ.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-4.
-
^ a b c d e Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-5.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-6.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-7.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-8.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-9.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-10.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-11.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-12.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-13.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-14.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-15.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-16.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-17.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-18.
-
^ Sony Computer Entertainment Inc. Run-Time Library Reference. Run-Time Library 4.4. January 1999. Page 7-116.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-19.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-20.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-21.
-
^ a b c d Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-22.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-23.
-
^ a b c d Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-24.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-25.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-26.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-29.
-
^ a b c d Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-31.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-30.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-27.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-28.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-32.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-33.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-34.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-35.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-36.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-37.
-
^ Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-38.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-39.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-40.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-41.
-
^ a b c Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-42.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. Run-Time Library 4.4. January 1999. Page 8-43.
-
^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. Run-Time Library 4.4. January 1999. Pages 7-4 to 7-32.
-
^ Sony Computer Entertainment Inc. Run-Time Library Reference. Run-Time Library 4.4. January 1999. Pages 7-33 to 7-115.
-
^ Sony Computer Entertainment Inc. Run-Time Library Reference. Run-Time Library 4.4. January 1999. Pages 7-118 to 7-134.