libdragon
|
Interface to the hardware sprite/triangle rasterizer (RDP). More...
Files | |
file | rdp.c |
Hardware Display Interface. | |
file | rdp.h |
Hardware Display Interface. | |
Data Structures | |
struct | sprite_cache |
Cached sprite structure. More... | |
Macros | |
#define | RINGBUFFER_SIZE 4096 |
Size of the internal ringbuffer that holds pending RDP commands. | |
#define | RINGBUFFER_SLACK 1024 |
Size of the slack are of the ring buffer. More... | |
Enumerations | |
enum | mirror_t { MIRROR_DISABLED , MIRROR_X , MIRROR_Y , MIRROR_XY } |
Mirror settings for textures. More... | |
enum | sync_t { SYNC_FULL , SYNC_PIPE , SYNC_LOAD , SYNC_TILE } |
RDP sync operations. More... | |
enum | flush_t { FLUSH_STRATEGY_NONE , FLUSH_STRATEGY_AUTOMATIC } |
Caching strategy for loaded textures. More... | |
Functions | |
void | rdp_init (void) |
Initialize the RDP system. | |
void | rdp_close (void) |
Close the RDP system. More... | |
void | rdp_attach (surface_t *surface) |
Attach the RDP to a surface. More... | |
void | rdp_detach (void) |
Detach the RDP from the current surface, after the RDP will have finished writing to it. More... | |
void | rdp_sync (sync_t sync) |
Perform a sync operation. More... | |
void | rdp_set_clipping (uint32_t tx, uint32_t ty, uint32_t bx, uint32_t by) |
Set the hardware clipping boundary. More... | |
void | rdp_set_default_clipping (void) |
Set the hardware clipping boundary to the entire screen. | |
void | rdp_enable_primitive_fill (void) |
Enable display of 2D filled (untextured) rectangles. More... | |
void | rdp_enable_blend_fill (void) |
Enable display of 2D filled (untextured) triangles. More... | |
void | rdp_enable_texture_copy (void) |
Enable display of 2D sprites. More... | |
uint32_t | rdp_load_texture (uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite) |
Load a sprite into RDP TMEM. More... | |
uint32_t | rdp_load_texture_stride (uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite, int offset) |
Load part of a sprite into RDP TMEM. More... | |
void | rdp_draw_textured_rectangle_scaled (uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale, mirror_t mirror) |
Draw a textured rectangle with a scaled texture. More... | |
void | rdp_draw_textured_rectangle (uint32_t texslot, int tx, int ty, int bx, int by, mirror_t mirror) |
Draw a textured rectangle. More... | |
void | rdp_draw_sprite (uint32_t texslot, int x, int y, mirror_t mirror) |
Draw a texture to the screen as a sprite. More... | |
void | rdp_draw_sprite_scaled (uint32_t texslot, int x, int y, double x_scale, double y_scale, mirror_t mirror) |
Draw a texture to the screen as a scaled sprite. More... | |
void | rdp_set_primitive_color (uint32_t color) |
Set the primitive draw color for subsequent filled primitive operations. More... | |
void | rdp_set_blend_color (uint32_t color) |
Set the blend draw color for subsequent filled primitive operations. More... | |
void | rdp_draw_filled_rectangle (int tx, int ty, int bx, int by) |
Draw a filled rectangle. More... | |
void | rdp_draw_filled_triangle (float x1, float y1, float x2, float y2, float x3, float y3) |
Draw a filled triangle. More... | |
void | rdp_set_texture_flush (flush_t flush) |
Set the flush strategy for texture loads. More... | |
Interface to the hardware sprite/triangle rasterizer (RDP).
The hardware display interface sets up and talks with the RDP in order to render hardware sprites, triangles and rectangles. The RDP is a very low level rasterizer and needs data in a very specific format. The hardware display interface handles this by building commands to be sent to the RDP.
Before attempting to draw anything using the RDP, the hardware display interface should be initialized with rdp_init. After the RDP is no longer needed, be sure to free all resources using rdp_close.
Code wishing to use the hardware rasterizer should first acquire a display context using display_lock. Once a display context has been acquired, the RDP can be attached to the display context with rdp_attach. Once the display has been attached, the RDP can be used to draw sprites, rectangles and textured/untextured triangles to the display context. Note that some functions require additional setup, so read the descriptions for each function before use. After code has finished rendering hardware assisted graphics to the display context, the RDP can be detached from the context using rdp_detach. After calling thie function, it is safe to immediately display the rendered graphics to the screen using display_show, or additional software graphics manipulation can take place using functions from the 2D Graphics.
Careful use of the rdp_sync operation is required for proper rasterization. Before performing settings changes such as clipping changes or setting up texture or solid fill modes, code should perform a SYNC_PIPE. A SYNC_PIPE should be performed again before any new texture load. This is to ensure that the last texture operation is completed before attempting to change texture memory. Careful execution of texture operations can allow code to skip some sync operations. Be careful with excessive sync operations as it can stall the pipeline and cause triangles/rectangles to be drawn on the next display context instead of the current.
rdp_detach will automatically perform a SYNC_FULL to ensure that everything has been completed in the RDP. This call generates an interrupt when complete which signals the main thread that it is safe to detach. Consequently, interrupts must be enabled for proper operation. This also means that code should under normal circumstances never use SYNC_FULL.
struct sprite_cache |
Cached sprite structure.
#define RINGBUFFER_SLACK 1024 |
Size of the slack are of the ring buffer.
Data can be written into the slack area of the ring buffer by functions creating RDP commands. However, when sending a completed command to the RDP, if the buffer has advanced into the slack, it will be cleared and the pointer reset to start. This is to stop any commands from being split in the middle during wraparound.
enum mirror_t |
enum sync_t |
enum flush_t |
void rdp_close | ( | void | ) |
Close the RDP system.
This function closes out the RDP system and cleans up any internal memory allocated by rdp_init.
void rdp_attach | ( | surface_t * | surface | ) |
Attach the RDP to a surface.
This function allows the RDP to operate on surfaces, that is memory buffers that can be used as render targets. For instance, it can be used with framebuffers acquired by calling display_lock, or to render to an offscreen buffer created with surface_alloc or surface_make.
This should be performed before any rendering operations to ensure that the RDP has a valid output buffer to operate on.
[in] | surface | A surface pointer |
void rdp_detach | ( | void | ) |
Detach the RDP from the current surface, after the RDP will have finished writing to it.
This function will ensure that all RDP rendering operations have completed before detaching the surface.
void rdp_sync | ( | sync_t | sync | ) |
Perform a sync operation.
Do not use excessive sync operations between commands as this can cause the RDP to stall. If the RDP stalls due to too many sync operations, graphics may not be displayed until the next render cycle, causing bizarre artifacts. The rule of thumb is to only add a sync operation if the data you need is not yet available in the pipeline.
[in] | sync | The sync operation to perform on the RDP |
void rdp_set_clipping | ( | uint32_t | tx, |
uint32_t | ty, | ||
uint32_t | bx, | ||
uint32_t | by | ||
) |
Set the hardware clipping boundary.
[in] | tx | Top left X coordinate in pixels |
[in] | ty | Top left Y coordinate in pixels |
[in] | bx | Bottom right X coordinate in pixels |
[in] | by | Bottom right Y coordinate in pixels |
void rdp_enable_primitive_fill | ( | void | ) |
Enable display of 2D filled (untextured) rectangles.
This must be called before using rdp_draw_filled_rectangle.
void rdp_enable_blend_fill | ( | void | ) |
Enable display of 2D filled (untextured) triangles.
This must be called before using rdp_draw_filled_triangle.
void rdp_enable_texture_copy | ( | void | ) |
Enable display of 2D sprites.
This must be called before using rdp_draw_textured_rectangle_scaled, rdp_draw_textured_rectangle, rdp_draw_sprite or rdp_draw_sprite_scaled.
Load a sprite into RDP TMEM.
[in] | texslot | The RDP texture slot to load this sprite into (0-7) |
[in] | texloc | The RDP TMEM offset to place the texture at |
[in] | mirror | Whether the sprite should be mirrored when displaying past boundaries |
[in] | sprite | Pointer to sprite structure to load the texture from |
uint32_t rdp_load_texture_stride | ( | uint32_t | texslot, |
uint32_t | texloc, | ||
mirror_t | mirror, | ||
sprite_t * | sprite, | ||
int | offset | ||
) |
Load part of a sprite into RDP TMEM.
Given a sprite with vertical and horizontal slices defined, this function will load the slice specified in offset into texture memory. This is usefl for treating a large sprite as a tilemap.
Given a sprite with 3 horizontal slices and two vertical slices, the offsets are as follows:
*---*---*---* | 0 | 1 | 2 | *---*---*---* | 3 | 4 | 5 | *---*---*---*
[in] | texslot | The RDP texture slot to load this sprite into (0-7) |
[in] | texloc | The RDP TMEM offset to place the texture at |
[in] | mirror | Whether the sprite should be mirrored when displaying past boundaries |
[in] | sprite | Pointer to sprite structure to load the texture from |
[in] | offset | Offset of the particular slice to load into RDP TMEM. |
void rdp_draw_textured_rectangle_scaled | ( | uint32_t | texslot, |
int | tx, | ||
int | ty, | ||
int | bx, | ||
int | by, | ||
double | x_scale, | ||
double | y_scale, | ||
mirror_t | mirror | ||
) |
Draw a textured rectangle with a scaled texture.
Given an already loaded texture, this function will draw a rectangle textured with the loaded texture at a scale other than 1. This allows rectangles to be drawn with stretched or squashed textures. If the rectangle is larger than the texture after scaling, it will be tiled or mirrored based on the mirror setting given in the load texture command.
Before using this command to draw a textured rectangle, use rdp_enable_texture_copy to set the RDP up in texture mode.
[in] | texslot | The texture slot that the texture was previously loaded into (0-7) |
[in] | tx | The pixel X location of the top left of the rectangle |
[in] | ty | The pixel Y location of the top left of the rectangle |
[in] | bx | The pixel X location of the bottom right of the rectangle |
[in] | by | The pixel Y location of the bottom right of the rectangle |
[in] | x_scale | Horizontal scaling factor |
[in] | y_scale | Vertical scaling factor |
[in] | mirror | Whether the texture should be mirrored |
void rdp_draw_textured_rectangle | ( | uint32_t | texslot, |
int | tx, | ||
int | ty, | ||
int | bx, | ||
int | by, | ||
mirror_t | mirror | ||
) |
Draw a textured rectangle.
Given an already loaded texture, this function will draw a rectangle textured with the loaded texture. If the rectangle is larger than the texture, it will be tiled or mirrored based on the* mirror setting given in the load texture command.
Before using this command to draw a textured rectangle, use rdp_enable_texture_copy to set the RDP up in texture mode.
[in] | texslot | The texture slot that the texture was previously loaded into (0-7) |
[in] | tx | The pixel X location of the top left of the rectangle |
[in] | ty | The pixel Y location of the top left of the rectangle |
[in] | bx | The pixel X location of the bottom right of the rectangle |
[in] | by | The pixel Y location of the bottom right of the rectangle |
[in] | mirror | Whether the texture should be mirrored |
void rdp_draw_sprite | ( | uint32_t | texslot, |
int | x, | ||
int | y, | ||
mirror_t | mirror | ||
) |
Draw a texture to the screen as a sprite.
Given an already loaded texture, this function will draw a rectangle textured with the loaded texture.
Before using this command to draw a textured rectangle, use rdp_enable_texture_copy to set the RDP up in texture mode.
[in] | texslot | The texture slot that the texture was previously loaded into (0-7) |
[in] | x | The pixel X location of the top left of the sprite |
[in] | y | The pixel Y location of the top left of the sprite |
[in] | mirror | Whether the texture should be mirrored |
void rdp_draw_sprite_scaled | ( | uint32_t | texslot, |
int | x, | ||
int | y, | ||
double | x_scale, | ||
double | y_scale, | ||
mirror_t | mirror | ||
) |
Draw a texture to the screen as a scaled sprite.
Given an already loaded texture, this function will draw a rectangle textured with the loaded texture.
Before using this command to draw a textured rectangle, use rdp_enable_texture_copy to set the RDP up in texture mode.
[in] | texslot | The texture slot that the texture was previously loaded into (0-7) |
[in] | x | The pixel X location of the top left of the sprite |
[in] | y | The pixel Y location of the top left of the sprite |
[in] | x_scale | Horizontal scaling factor |
[in] | y_scale | Vertical scaling factor |
[in] | mirror | Whether the texture should be mirrored |
void rdp_set_primitive_color | ( | uint32_t | color | ) |
Set the primitive draw color for subsequent filled primitive operations.
This function sets the color of all rdp_draw_filled_rectangle operations that follow. Note that in 16 bpp mode, the color must be a packed color. This means that the high 16 bits and the low 16 bits must both be the same color. Use graphics_make_color or graphics_convert_color to generate valid colors.
[in] | color | Color to draw primitives in |
void rdp_set_blend_color | ( | uint32_t | color | ) |
Set the blend draw color for subsequent filled primitive operations.
This function sets the color of all rdp_draw_filled_triangle operations that follow.
[in] | color | Color to draw primitives in |
void rdp_draw_filled_rectangle | ( | int | tx, |
int | ty, | ||
int | bx, | ||
int | by | ||
) |
Draw a filled rectangle.
Given a color set with rdp_set_primitive_color, this will draw a filled rectangle to the screen. This is most often useful for erasing a buffer before drawing to it by displaying a black rectangle the size of the screen. This is much faster than setting the buffer blank in software. However, if you are planning on drawing to the entire screen, blanking may be unnecessary.
Before calling this function, make sure that the RDP is set to primitive mode by calling rdp_enable_primitive_fill.
[in] | tx | Pixel X location of the top left of the rectangle |
[in] | ty | Pixel Y location of the top left of the rectangle |
[in] | bx | Pixel X location of the bottom right of the rectangle |
[in] | by | Pixel Y location of the bottom right of the rectangle |
void rdp_draw_filled_triangle | ( | float | x1, |
float | y1, | ||
float | x2, | ||
float | y2, | ||
float | x3, | ||
float | y3 | ||
) |
Draw a filled triangle.
Given a color set with rdp_set_blend_color, this will draw a filled triangle to the screen. Vertex order is not important.
Before calling this function, make sure that the RDP is set to blend mode by calling rdp_enable_blend_fill.
[in] | x1 | Pixel X1 location of triangle |
[in] | y1 | Pixel Y1 location of triangle |
[in] | x2 | Pixel X2 location of triangle |
[in] | y2 | Pixel Y2 location of triangle |
[in] | x3 | Pixel X3 location of triangle |
[in] | y3 | Pixel Y3 location of triangle |
void rdp_set_texture_flush | ( | flush_t | flush | ) |
Set the flush strategy for texture loads.
If textures are guaranteed to be in uncached RDRAM or the cache is flushed before calling load operations, the RDP can be told to skip flushing the cache. This affords a good speedup. However, if you are changing textures in memory on the fly or otherwise do not want to deal with cache coherency, set the cache strategy to automatic to have the RDP flush cache before texture loads.
[in] | flush | The cache strategy, either FLUSH_STRATEGY_NONE or FLUSH_STRATEGY_AUTOMATIC. |