libdragon
Data Structures | Files | Defines | Enumerations | Functions | Variables
Hardware Display Interface
Display Subsystem

Interface to the hardware sprite/triangle rasterizer (RDP). More...

Data Structures

struct  sprite_cache
 Cached sprite structure. More...

Files

file  rdp.c
 

Hardware Display Interface.


file  rdp.h
 

Hardware Display Interface.


Defines

#define __get_buffer(x)   __safe_buffer[(x)-1]
 Grab the texture buffer given a display context.
#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.

Enumerations

enum  mirror_t { MIRROR_DISABLED, MIRROR_ENABLED }
 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

static void __rdp_interrupt ()
 RDP interrupt handler.
static uint32_t __rdp_round_to_power (uint32_t number)
 Given a number, rount to a power of two.
static uint32_t __rdp_log2 (uint32_t number)
 Integer log base two of a number.
static uint32_t __rdp_ringbuffer_size (void)
 Return the size of the current command buffered in the ring buffer.
static void __rdp_ringbuffer_queue (uint32_t data)
 Queue 32 bits of a command to the ring buffer.
static void __rdp_ringbuffer_send (void)
 Send a completed command to the RDP that is queued in the ring buffer.
void rdp_init (void)
 Initialize the RDP system.
void rdp_close (void)
 Close the RDP system.
void rdp_attach_display (display_context_t disp)
 Attach the RDP to a display context.
void rdp_detach_display (void)
 Detach the RDP from a display context.
void rdp_sync (sync_t sync)
 Perform a sync operation.
void rdp_set_clipping (uint32_t tx, uint32_t ty, uint32_t bx, uint32_t by)
 Set the hardware clipping boundary.
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.
void rdp_enable_texture_copy (void)
 Enable display of 2D sprites.
static uint32_t __rdp_load_texture (uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite, int sl, int tl, int sh, int th)
 Load a texture from RDRAM into RDP TMEM.
uint32_t rdp_load_texture (uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite)
 Load a sprite into RDP TMEM.
uint32_t rdp_load_texture_stride (uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite, int offset)
 Load part of a sprite 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)
 Draw a textured rectangle with a scaled texture.
void rdp_draw_textured_rectangle (uint32_t texslot, int tx, int ty, int bx, int by)
 Draw a textured rectangle.
void rdp_draw_sprite (uint32_t texslot, int x, int y)
 Draw a texture to the screen as a sprite.
void rdp_draw_sprite_scaled (uint32_t texslot, int x, int y, double x_scale, double y_scale)
 Draw a texture to the screen as a scaled sprite.
void rdp_set_primitive_color (uint32_t color)
 Set the primitive draw color for subsequent filled primitive operations.
void rdp_draw_filled_rectangle (int tx, int ty, int bx, int by)
 Draw a filled rectangle.
void rdp_set_texture_flush (flush_t flush)
 Set the flush strategy for texture loads.

Variables

uint32_t __bitdepth
 Currently active bit depth.
uint32_t __width
 Currently active video width (calculated)
uint32_t __height
 Currently active video height (calculated)
void * __safe_buffer []
 Pointer to uncached 16-bit aligned version of buffers.
static uint32_t rdp_ringbuffer [RINGBUFFER_SIZE/4]
 Ringbuffer where partially assembled commands will be placed before sending to the RDP.
static uint32_t rdp_start = 0
 Start of the command in the ringbuffer.
static uint32_t rdp_end = 0
 End of the command in the ringbuffer.
static flush_t flush_strategy = FLUSH_STRATEGY_AUTOMATIC
 The current cache flushing strategy.
static volatile uint32_t wait_intr = 0
 Interrupt wait flag.
static sprite_cache cache [8]
 Array of cached textures in RDP TMEM indexed by the RDP texture slot.

Detailed Description

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_display. 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_display. 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_display 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.


Define Documentation

#define __get_buffer (   x)    __safe_buffer[(x)-1]

Grab the texture buffer given a display context.

Parameters:
[in]xThe display context returned from display_lock
Returns:
A pointer to the drawing surface for that display context.
#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.


Enumeration Type Documentation

enum flush_t

Caching strategy for loaded textures.

Enumerator:
FLUSH_STRATEGY_NONE 

Textures are assumed to be pre-flushed.

FLUSH_STRATEGY_AUTOMATIC 

Cache will be flushed on all incoming textures.

enum mirror_t

Mirror settings for textures.

Enumerator:
MIRROR_DISABLED 

Disable texture mirroring.

MIRROR_ENABLED 

Enable texture mirroring.

enum sync_t

RDP sync operations.

Enumerator:
SYNC_FULL 

Wait for any operation to complete before causing a DP interrupt.

SYNC_PIPE 

Sync the RDP pipeline.

SYNC_LOAD 

Block until all texture load operations are complete.

SYNC_TILE 

Block until all tile operations are complete.


Function Documentation

static void __rdp_interrupt ( ) [static]

RDP interrupt handler.

This interrupt is called when a Sync Full operation has completed and it is safe to use the output buffer with software

static uint32_t __rdp_load_texture ( uint32_t  texslot,
uint32_t  texloc,
mirror_t  mirror_enabled,
sprite_t sprite,
int  sl,
int  tl,
int  sh,
int  th 
) [static]

Load a texture from RDRAM into RDP TMEM.

This function will take a texture from a sprite and place it into RDP TMEM at the offset and texture slot specified. It is capable of pulling out a smaller texture from a larger sprite map.

Parameters:
[in]texslotThe texture slot (0-7) to assign this texture to
[in]texlocThe offset in RDP TMEM to place this texture
[in]mirror_enabledWhether to mirror this texture when displaying
[in]spritePointer to the sprite structure to load the texture out of
[in]slThe pixel offset S of the top left of the texture relative to sprite space
[in]tlThe pixel offset T of the top left of the texture relative to sprite space
[in]shThe pixel offset S of the bottom right of the texture relative to sprite space
[in]thThe pixel offset T of the bottom right of the texture relative to sprite space
Returns:
The amount of texture memory in bytes that was consumed by this texture.
static uint32_t __rdp_log2 ( uint32_t  number) [inline, static]

Integer log base two of a number.

Parameters:
[in]numberNumber to take the log base two of
Returns:
Log base two of the number passed in.
static void __rdp_ringbuffer_queue ( uint32_t  data) [static]

Queue 32 bits of a command to the ring buffer.

Parameters:
[in]data32 bits of data to be queued at the end of the current command
static void __rdp_ringbuffer_send ( void  ) [static]

Send a completed command to the RDP that is queued in the ring buffer.

Given a validly constructred command in the ring buffer, this command will prepare the memory region in the ring buffer to be sent to the RDP and then start a DMA transfer, kicking off execution of the command in the RDP. After calling this function, it is safe to start writing to the ring buffer again.

static uint32_t __rdp_ringbuffer_size ( void  ) [inline, static]

Return the size of the current command buffered in the ring buffer.

Returns:
The size of the command in bytes
static uint32_t __rdp_round_to_power ( uint32_t  number) [inline, static]

Given a number, rount to a power of two.

Parameters:
[in]numberA number that needs to be rounded
Returns:
The next power of two that is greater than the number passed in.

Attach the RDP to a display context.

This function allows the RDP to operate on display contexts fetched with display_lock. This should be performed before any other operations to ensure that the RDP has a valid output buffer to operate on.

Parameters:
[in]dispA display context as returned by display_lock
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_detach_display ( void  )

Detach the RDP from a display context.

Note:
This function requires interrupts to be enabled to operate properly.

This function will ensure that all hardware operations have completed on an output buffer before detaching the display context. This should be performed before displaying the finished output using display_show

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.

Parameters:
[in]txPixel X location of the top left of the rectangle
[in]tyPixel Y location of the top left of the rectangle
[in]bxPixel X location of the bottom right of the rectangle
[in]byPixel Y location of the bottom right of the rectangle
void rdp_draw_sprite ( uint32_t  texslot,
int  x,
int  y 
)

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.

Parameters:
[in]texslotThe texture slot that the texture was previously loaded into (0-7)
[in]xThe pixel X location of the top left of the sprite
[in]yThe pixel Y location of the top left of the sprite
void rdp_draw_sprite_scaled ( uint32_t  texslot,
int  x,
int  y,
double  x_scale,
double  y_scale 
)

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.

Parameters:
[in]texslotThe texture slot that the texture was previously loaded into (0-7)
[in]xThe pixel X location of the top left of the sprite
[in]yThe pixel Y location of the top left of the sprite
[in]x_scaleHorizontal scaling factor
[in]y_scaleVertical scaling factor
void rdp_draw_textured_rectangle ( uint32_t  texslot,
int  tx,
int  ty,
int  bx,
int  by 
)

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.

Parameters:
[in]texslotThe texture slot that the texture was previously loaded into (0-7)
[in]txThe pixel X location of the top left of the rectangle
[in]tyThe pixel Y location of the top left of the rectangle
[in]bxThe pixel X location of the bottom right of the rectangle
[in]byThe pixel Y location of the bottom right of the rectangle
void rdp_draw_textured_rectangle_scaled ( uint32_t  texslot,
int  tx,
int  ty,
int  bx,
int  by,
double  x_scale,
double  y_scale 
)

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.

Parameters:
[in]texslotThe texture slot that the texture was previously loaded into (0-7)
[in]txThe pixel X location of the top left of the rectangle
[in]tyThe pixel Y location of the top left of the rectangle
[in]bxThe pixel X location of the bottom right of the rectangle
[in]byThe pixel Y location of the bottom right of the rectangle
[in]x_scaleHorizontal scaling factor
[in]y_scaleVertical scaling factor
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_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.

uint32_t rdp_load_texture ( uint32_t  texslot,
uint32_t  texloc,
mirror_t  mirror_enabled,
sprite_t sprite 
)

Load a sprite into RDP TMEM.

Parameters:
[in]texslotThe RDP texture slot to load this sprite into (0-7)
[in]texlocThe RDP TMEM offset to place the texture at
[in]mirror_enabledWhether the sprite should be mirrored when displaying past boundaries
[in]spritePointer to sprite structure to load the texture from
Returns:
The number of bytes consumed in RDP TMEM by loading this sprite
uint32_t rdp_load_texture_stride ( uint32_t  texslot,
uint32_t  texloc,
mirror_t  mirror_enabled,
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 |
 *---*---*---*
 
Parameters:
[in]texslotThe RDP texture slot to load this sprite into (0-7)
[in]texlocThe RDP TMEM offset to place the texture at
[in]mirror_enabledWhether the sprite should be mirrored when displaying past boundaries
[in]spritePointer to sprite structure to load the texture from
[in]offsetOffset of the particular slice to load into RDP TMEM.
Returns:
The number of bytes consumed in RDP TMEM by loading this sprite
void rdp_set_clipping ( uint32_t  tx,
uint32_t  ty,
uint32_t  bx,
uint32_t  by 
)

Set the hardware clipping boundary.

Parameters:
[in]txTop left X coordinate in pixels
[in]tyTop left Y coordinate in pixels
[in]bxBottom right X coordinate in pixels
[in]byBottom right Y coordinate in pixels
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.

Parameters:
[in]colorColor to draw primitives in
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.

Parameters:
[in]flushThe cache strategy, either FLUSH_STRATEGY_NONE or FLUSH_STRATEGY_AUTOMATIC.
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.

Parameters:
[in]syncThe sync operation to perform on the RDP
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines