libdragon
Data Structures | Functions | Variables

RDP Command queue. More...

Data Structures

struct  rdpq_state_t
 State of the rdpq ucode overlay (partial). More...
 

Functions

 DEFINE_RSP_UCODE (rsp_rdpq,.assert_handler=rdpq_assert_handler)
 The rdpq ucode overlay.
 
void rdpq_init ()
 Initialize the RDPQ library. More...
 
void rdpq_close ()
 Shutdown the RDPQ library. More...
 
uint32_t rdpq_config_set (uint32_t cfg)
 Set the configuration of the RDPQ module. More...
 
uint32_t rdpq_config_enable (uint32_t cfg)
 Enable a specific set of configuration flags. More...
 
uint32_t rdpq_config_disable (uint32_t cfg)
 Disable a specific set of configuration flags. More...
 
void rdpq_fence (void)
 Public rdpq_fence API, redefined it. More...
 
void rdpq_exec (void *buffer, int size)
 Send to the RDP a buffer of RDP commands from RDRAM. More...
 
void __rdpq_autosync_use (uint32_t res)
 Autosync engine: mark certain resources as in use.
 
void __rdpq_autosync_change (uint32_t res)
 Autosync engine: mark certain resources as being changed. More...
 
void rdpq_set_fill_color (color_t color)
 Enqueue a SET_FILL_COLOR RDP command. More...
 
void rdpq_set_fill_color_stripes (color_t color1, color_t color2)
 Enqueue a SET_FILL_COLOR RDP command to draw a striped pattern. More...
 
void rdpq_set_fog_color (color_t color)
 Set the RDP FOG blender register. More...
 
void rdpq_set_blend_color (color_t color)
 Set the RDP BLEND blender register. More...
 
void rdpq_set_prim_color (color_t color)
 Set the RDP PRIM combiner register (color only) (RDP command: SET_PRIM_COLOR) More...
 
void rdpq_set_detail_factor (float value)
 Set the detail/sharpen blending factor (RDP command: SET_PRIM_COLOR (partial)) More...
 
void rdpq_set_prim_lod_frac (uint8_t value)
 Set the RDP PRIM LOD FRAC combiner register (RDP command: SET_PRIM_COLOR (partial)) More...
 
void rdpq_set_prim_register_raw (color_t color, uint8_t minlod, uint8_t primlod)
 Set the RDP PRIM combiner register (raw version) (RDP command: SET_PRIM_COLOR) More...
 
void rdpq_set_env_color (color_t color)
 Set the RDP ENV combiner register (RDP command: SET_ENV_COLOR) More...
 
void rdpq_set_prim_depth_raw (uint16_t primitive_z, int16_t primitive_delta_z)
 Set a fixed Z value to be used instead of a per-pixel value (RDP command; SET_PRIM_DEPTH) More...
 
void rdpq_load_tlut_raw (rdpq_tile_t tile, uint8_t lowidx, uint8_t highidx)
 Load a palette of colors into TMEM (RDP command: LOAD_TLUT) More...
 
void rdpq_set_tile_size_fx (rdpq_tile_t tile, uint16_t s0, uint16_t t0, uint16_t s1, uint16_t t1)
 Configure the extents of a tile descriptor – fixed point version (RDP command: SET_TILE_SIZE) More...
 
void rdpq_load_block (rdpq_tile_t tile, uint16_t s0, uint16_t t0, uint16_t num_texels, uint16_t tmem_pitch)
 Load a texture image into TMEM with a single contiguous memory transfer (RDP command: LOAD_BLOCK) More...
 
void rdpq_load_block_fx (rdpq_tile_t tile, uint16_t s0, uint16_t t0, uint16_t num_texels, uint16_t dxt)
 Low level function to load a texture image into TMEM in a single memory transfer.
 
void rdpq_load_tile_fx (rdpq_tile_t tile, uint16_t s0, uint16_t t0, uint16_t s1, uint16_t t1)
 Load a portion of a texture into TMEM – fixed point version (RDP command: LOAD_TILE) More...
 
void rdpq_set_combiner_raw (uint64_t cc)
 Low-level function to change the RDP combiner. More...
 
void rdpq_set_other_modes_raw (uint64_t mode)
 Low-level function to set the rendering mode register. More...
 
void rdpq_change_other_modes_raw (uint64_t mask, uint64_t val)
 Low-level function to partly change the rendering mode register. More...
 
void rdpq_set_color_image_raw (uint8_t index, uint32_t offset, tex_format_t format, uint32_t width, uint32_t height, uint32_t stride)
 Low-level version of rdpq_set_color_image, with address lookup capability. More...
 
void rdpq_set_z_image_raw (uint8_t index, uint32_t offset)
 Low-level version of rdpq_set_z_image, with address lookup capability. More...
 
void rdpq_set_texture_image_raw (uint8_t index, uint32_t offset, tex_format_t format, uint16_t width, uint16_t height)
 Low-level version of rdpq_set_texture_image, with address lookup capability. More...
 
void rdpq_set_lookup_address (uint8_t index, void *rdram_addr)
 Store an address into the rdpq lookup table. More...
 
void rdpq_set_tile (rdpq_tile_t tile, tex_format_t format, int32_t tmem_addr, uint16_t tmem_pitch, const rdpq_tileparms_t *parms)
 Enqueue a RDP SET_TILE command (full version) More...
 
RDP block management functions.

All the functions in this group are called in the context of creation of a RDP block (part of a rspq block). See the top-level documentation for a general overview of how RDP blocks work.

void __rdpq_block_begin ()
 Initialize RDP block mangament. More...
 
void __rdpq_block_next_buffer (void)
 Allocate a new RDP block buffer, chaining it to the current one (if any) More...
 
rdpq_block_t__rdpq_block_end ()
 Finish creation of a RDP block. More...
 
void __rdpq_block_run (rdpq_block_t *block)
 Run a block (called by rspq_block_run).
 
void __rdpq_block_free (rdpq_block_t *block)
 Free a block. More...
 
void __rdpq_block_reserve (int num_rdp_commands)
 Reserve space in the RDP static buffer for a number of RDP commands. More...
 
void __rdpq_block_update (volatile uint32_t *wptr)
 Set a new RDP write pointer, and enqueue a RSP command to run the buffer until there. More...
 
Helpers to write generic RDP commands

All the functions in this group are wrappers around rdpq_passthrough_write to help generating RDP commands. They are called by inlined functions in rdpq.h. See the top-level documentation about inline functions to understand the reason of this split.

void __rdpq_write8 (uint32_t cmd_id, uint32_t arg0, uint32_t arg1)
 Write a standard 8-byte RDP command.
 
void __rdpq_write8_syncchange (uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t autosync)
 Write a standard 8-byte RDP command, which changes some autosync resources

 
void __rdpq_write8_syncuse (uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t autosync)
 Write a standard 8-byte RDP command, which uses some autosync resources

 
void __rdpq_write8_syncchangeuse (uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t autosync_c, uint32_t autosync_u)
 Write a standard 8-byte RDP command, which changes some autosync resources and uses others.
 
void __rdpq_write16 (uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3)
 Write a standard 16-byte RDP command

 
void __rdpq_write16_syncuse (uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t autosync)
 Write a standard 16-byte RDP command, which uses some autosync resources

 
void __rdpq_fixup_write8_syncchange (uint32_t cmd_id, uint32_t w0, uint32_t w1, uint32_t autosync)
 Write a 8-byte RDP command fixup.
 
RDP fixups out-of-line implementations

These are the out-of line implementations of RDP commands which needs specific logic, mostly because they are fixups.

void __rdpq_set_scissor (uint32_t w0, uint32_t w1)
 Out-of-line implementation of rdpq_set_scissor.
 
void __rdpq_set_fill_color (uint32_t w1)
 Out-of-line implementation of rdpq_set_fill_color.
 
void __rdpq_set_color_image (uint32_t w0, uint32_t w1, uint32_t sw0, uint32_t sw1)
 Out-of-line implementation of rdpq_set_color_image.
 
void rdpq_set_color_image (const surface_t *surface)
 Configure the framebuffer to render to (RDP command: SET_COLOR_IMAGE) More...
 
void rdpq_set_z_image (const surface_t *surface)
 Configure the Z-buffer to use (RDP command: SET_Z_IMAGE) More...
 
void rdpq_set_texture_image (const surface_t *surface)
 Configure the texture to use (RDP command: SET_TEX_IMAGE) More...
 
void __rdpq_set_other_modes (uint32_t w0, uint32_t w1)
 Out-of-line implementation of rdpq_set_other_modes_raw.
 
void __rdpq_change_other_modes (uint32_t w0, uint32_t w1, uint32_t w2)
 Out-of-line implementation of rdpq_change_other_modes_raw.
 
uint64_t rdpq_get_other_modes_raw (void)
 Read the current render mode register. More...
 
void rdpq_set_tile_autotmem (int16_t tmem_bytes)
 Configure the auto-TMEM feature of rdpq_set_tile. More...
 
void rdpq_sync_full (void(*callback)(void *), void *arg)
 Schedule a RDP SYNC_FULL command and register a callback when it is done. More...
 
void rdpq_sync_pipe (void)
 Schedule a RDP SYNC_PIPE command. More...
 
void rdpq_sync_tile (void)
 Schedule a RDP SYNC_TILE command. More...
 
void rdpq_sync_load (void)
 Schedule a RDP SYNC_LOAD command. More...
 

Variables

bool __rdpq_inited = false
 True if rdpq_init was called. More...
 
rdpq_block_state_t rdpq_block_state
 RDP block management state.
 
rdpq_tracking_t rdpq_tracking
 Tracking state of RDP.
 

Detailed Description

RDP Command queue.

RDP Queue: implementation details

This documentation block describes the internal workings of the RDP Queue. This is useful to understand the implementation, but it is not required to read or understand this to use rdpq.

For description of the API of the RDP queue, see rdpq.h

Improvements over raw hardware programming

RDPQ provides a very low-level API over the RDP graphics chips, exposing all its settings and most of its limits. Still, rdpq tries to hide a few low-level hardware details to make programming the RDP less surprising and more orthogonal. To do so, it "patches" some RDP commands, typically via RSP code and depending on the current RDP state. We called these improvements "fixups".

The documentation of the public rdpq API does not explicitly mention which behavior has been adjusted via fixups. Instead, this section explains in details all the fixups performed by rdpq. Reading this section is not necessary to understand and use rdpq, but it might be useful for people that are familiar with RDP outside of libdragon (eg: libultra programmers), to avoid getting confused in places where rdpq deviates from RDP (even if for the better).

Scissoring and texrects: consistent coordinates

The RDP SET_SCISSOR and TEXTURE_RECTANGLE commands accept a rectangle whose major bounds (bottom and right) are either inclusive or exclusive, depending on the current RDP cycle type (fill/copy: exclusive, 1cyc/2cyc: inclusive). rdpq_set_scissor and rdpq_texture_rectangle, instead, always use exclusive major bounds, and automatically adjust them depending on the current RDP cycle type.

Moreover, any time the RDP cycle type changes, the current scissoring is adjusted to guarantee consistent results. This is especially important where the scissoring covers the whole framebuffer, because otherwise the RDP might overflow the buffer while drawing.

Avoid color image buffer overflows with auto-scissoring

The RDP SET_COLOR_IMAGE command only contains a memory pointer and a pitch: the RDP is not aware of the actual size of the buffer in terms of width/height, and expects commands to be correctly clipped, or scissoring to be configured. To avoid mistakes leading to memory corruption, rdpq_set_color_image always reconfigures scissoring to respect the actual buffer size.

Note also that when the RDP is cold-booted, the internal scissoring register contains random data. This means that this auto-scissoring fixup also provides a workaround to this, by making sure scissoring is always configured at least once. In fact, by forgetting to configure scissoring, the RDP can happily draw outside the framebuffer, or draw nothing, or even freeze.

Autosync

The RDP has different internal parallel units and exposes three different syncing primitives to stall and avoid write-during-use bugs: SYNC_PIPE, SYNC_LOAD and SYNC_TILE. Correct usage of these commands is not complicated but it can be complex to get right, and require extensive hardware testing because emulators do not implement the bugs caused by the absence of RDP stalls.

rdpq implements a smart auto-syncing engine that tracks the commands sent to RDP (on the CPU) and automatically inserts syncing whenever necessary. Insertion of syncing primitives is optimal for SYNC_PIPE and SYNC_TILE, and conservative for SYNC_LOAD (it does not currently handle partial TMEM updates).

Autosync also works within blocks, but since it is not possible to know the context in which a block will be run, it has to be conservative and might issue more stalls than necessary.

More details on the autosync engine are below.

Partial render mode changes

The RDP command SET_OTHER_MODES contains most the RDP mode settings. Unfortunately the command does not allow to change only some settings, but all of them must be reconfigured. This is in contrast with most graphics APIs that allow to configure each render mode setting by itself (eg: it is possible to just change the dithering algorithm).

rdpq instead tracks the current render mode on the RSP, and allows to do partial updates via either the low-level rdpq_change_other_modes_raw function (where it is possible to change only a subset of the 56 bits), or via the high-level rdpq_mode_* APIs (eg: rdpq_mode_dithering), which mostly build upon rdpq_change_other_modes_raw in their implementation.

Automatic 1/2 cycle type selection

The RDP has two main operating modes: 1 cycle per pixel and 2 cycles per pixel. The latter is twice as slow, as the name implies, but it allows more complex color combiners and/or blenders. Moreover, 2-cycles mode also allows for multi-texturing.

At the hardware level, it is up to the programmer to explicitly activate either 1-cycle or 2-cycle mode. The problem with this is that there are specific rules to follow for either mode, which does not compose cleanly with partial mode changes. For instance, fogging is typically implemented using the 2-cycle mode as it requires two passes in the blender. If the user disables fogging for some meshes, it might be more performant to switch back to 1-cycle mode, but that requires also reconfiguring the combiner.

To solve this problem, the higher level rdpq mode APIs (rdpq_mode_*) automatically select the best cycle type depending on the current settings. More specifically, 1-cycle mode is preferred as it is faster, but 2-cycle mode is activated whenever one of the following conditions is true:

The correct cycle-type is automatically reconfigured any time that either the blender or the combiner settings are changed. Notice that this means that rdpq also transparently handles a few more details for the user, to make it for an easier API:

Fill color as standard 32-bit color

The RDP command SET_FILL_COLOR (used to configure the color register to be used in fill cycle type) has a very low-level interface: its argument is basically a 32-bit value which is copied to the framebuffer as-is, irrespective of the framebuffer color depth. For a 16-bit buffer, then, it must be programmed with two copies of the same 16-bit color.

rdpq_set_fill_color, instead, accepts a color_t argument and does the conversion to the "packed" format internally, depending on the current framebuffer's color depth.

Usage of inline functions vs no-inline

Most of the rdpq APIs are defined as inline functions in the header rdpq.h, but they then internally call some non-public function to do emit the command. So basically the actual function is split in tow parts: an inlined part and a non-inlined part.

The reason for this split is to help the compiler generate better code. In fact, it is extremely common to call rdpq functions using many constant parameters, and we want those constants to be propagated into the various bit shifts and masks to be assembled into single words. Once the (often constant) arguments have been handled, the rest of the operation can normally be performed in a separate out-of-line function.

Sending commands to RDP

This section describes in general how the commands flow from CPU to RDP via RSP. There are several different code-paths here depending on whether the command has a fixup or not, and it is part of a block.

RDRAM vs XBUS

In general, the rdpq library sends the commands to RDP using a buffer in RDRAM. The hardware feature called XBUS (which allows to send commands from RSP DMEM to RDP directly) is not used or supported. There are a few reasons for this architectural choice:

The buffer in RDRAM where RDP commands are enqueued by RSP is called "RDP dynamic buffer". It is used as a ring buffer, so once full, it is recycled, making sure not to overwrite commands that the RDP has not executed yet.

RDP commands in standard mode

Let's check the workflow for a standard RDP command, that is one for which rdpq provides no fixups:

RDP fixups in standard mode

Now let's see the workflow for a RDP fixup: these are the RDP commands which are modified/tweaked by RSP to provide a more sane programming interface to the programmer.

The overall workflow is similar to the passthrough, but the command is tweaked by RSP in the process.

RDP commands in block mode

In block mode, rdpq completely changes its way of operating.

A rspq block (as described in rspq.c) is a buffer containing a sequence of rspq commands that can be played back by RSP itself, with the CPU just triggering it via rspq_block_run. When using rdpq, the rspq block contains one additional buffer: a "RDP static buffer", which contains RDP commands.

At block creation time, in fact, RDP commands are not enqueued as rspq commands, but are rather written into this separate buffer. The goal is to avoid the passthrough overhead: since RDP commands don't change during the block execution, they can be sent directly to RDP by RSP, referencing the RDP static buffer, without ever transferring them into RSP DMEM and back.

Let's check the sequence at block compilation time:

And now at block run time:

enqueues a rspq command for the rdpq overlay. This command does not need to have the same encoding of a real RDP command, but it is usually similar (to simplify work on the RSP). For instance, in our example the rdpq command is 0xD2, which is meaningless if sent to RDP, but has otherwise the same encoding of a real SET_SCISSOR (whose ID would be 0xED).

Autosync engine

As explained above, the autosync engine is able to emit sync commands (SYNC_PIPE, SYNC_TILE, SYNC_LOAD) automatically when necessary, liberating the developer from this additional task. This section describes how it works.

The autosync engine works around one simple abstraction and logic. There are "hardware resources" that can be either "used" or "changed" (aka configured) by RDP commands. If a resource is in use, a command changing it requires a sync before. Each resource is tracked by one bit in a single 32-bit word called the "autosync state".

The following resources are tracked:

Note that there is a limit with the current implementation: the RDP can use multiple tiles with a single command (eg: when using multi-texturing or LODs), but we are not able to track that correctly: all drawing commands for now assume that a single tile will be used. If this proves to be a problem, it is always possible to call rdpq_sync_tile to manually issue a sync.

Autosync also works with blocks, albeit conservatively. When recording a block, it is not possible to know what the autosync state will be at the point of call (and obviously, it could be called in different situations with different states). The engine thus handles the worst case: at the beginning of a block, it assumes that all resources are "in use". This might cause some sync commands to be run in situations where it would not be strictly required, but the performance impact is unlikely to be noticeable.

Autosync engine can be enabled or disabled via rdpq_config_enable / rdpq_config_disable. Remember that manually issuing sync commands require careful debugging on real hardware, as no emulator today is able to reproduce the effects of a missing sync command.


Data Structure Documentation

◆ rdpq_state_t

struct rdpq_state_t

State of the rdpq ucode overlay (partial).

This must be kept in sync with rsp_rdpq.S.

We don't map the whole state here as we don't need to access it from C in whole. We just map the initial part of the state, which is what we need.

Data Fields
uint64_t sync_full Last SYNC_FULL command.
uint32_t rspq_syncpoint_id Syncpoint ID at the time of the last SYNC_FULL command.
uint32_t padding Padding.
uint32_t rdram_state_address Address of this state structure in RDRAM.
uint32_t rdram_syncpoint_id Address of the syncpoint ID in RDRAM.

Function Documentation

◆ rdpq_init()

void rdpq_init ( void  )

Initialize the RDPQ library.

This should be called by the initialization functions of the higher-level libraries using RDPQ to emit RDP commands, and/or by the application main if the application itself calls rdpq functions.

It is safe to call this function multiple times (it does nothing), so that multiple independent libraries using rdpq can call rdpq_init with no side effects.

◆ rdpq_close()

void rdpq_close ( void  )

Shutdown the RDPQ library.

This is mainly used for testing.

◆ rdpq_config_set()

uint32_t rdpq_config_set ( uint32_t  cfg)

Set the configuration of the RDPQ module.

This function allows you to change the configuration of rdpq to enable/disable features. This is useful mainly for advanced users that want to manually tune RDP programming, disabling some automatisms performed by rdpq.

The configuration is a bitmask that can be composed using the RDPQ_CFG_* macros.

To enable or disable specific configuration options use rdpq_config_enable or rdpq_config_disable.

Parameters
cfgThe new configuration to set
Returns
The previous configuration
See also
rdpq_config_enable
rdpq_config_disable

◆ rdpq_config_enable()

uint32_t rdpq_config_enable ( uint32_t  cfg_enable_bits)

Enable a specific set of configuration flags.

This function allows you to modify the configuration of rdpq activating a specific set of features. It can be useful to temporarily modify the configuration and then restore it.

Parameters
cfg_enable_bitsConfiguration flags to enable
Returns
The previous configuration
See also
rdpq_config_set
rdpq_config_disable

◆ rdpq_config_disable()

uint32_t rdpq_config_disable ( uint32_t  cfg_disable_bits)

Disable a specific set of configuration flags.

This function allows you to modify the configuration of rdpq disabling a specific set of features. It can be useful to temporarily modify the configuration and then restore it.

// Disable automatic scissor generation
// This will change the render target but will NOT issue a corresponding SET_SCISSOR.
// This is dangerous as the currently-configured scissor might allow to draw outside of
// the surface boundary, but an advanced user will know if this is correct.
[...]
// Restore the previous configuration
rdpq_config_set(old_cfg);
uint32_t rdpq_config_disable(uint32_t cfg)
Disable a specific set of configuration flags.
Definition: rdpq.c:512
void rdpq_set_color_image(const surface_t *surface)
Configure the framebuffer to render to (RDP command: SET_COLOR_IMAGE)
Definition: rdpq.c:992
uint32_t rdpq_config_set(uint32_t cfg)
Set the configuration of the RDPQ module.
Definition: rdpq.c:500
#define RDPQ_CFG_AUTOSCISSOR
Configuration flag: enable automatic generation of SET_SCISSOR commands on render target change.
Definition: rdpq.h:227
Parameters
cfg_disable_bitsConfiguration flags to disable
Returns
The previous configuration
See also
rdpq_config_set
rdpq_config_enable

◆ rdpq_fence()

void rdpq_fence ( void  )

Public rdpq_fence API, redefined it.

Add a fence to synchronize RSP with RDP commands.

◆ rdpq_exec()

void rdpq_exec ( void *  buffer,
int  size 
)

Send to the RDP a buffer of RDP commands from RDRAM.

This command can be used to execute raw RDP commands from RDRAM. It is normally not necessary to call this function as normal rdpq functions will simply enqueue the commands in the RSP queue, but there can be cases where commands have been prepared in RAM somehow (especially, for compatibility with existing code that assembled RDP commands in RDRAM, or to playback RDP command lists prepared with offline tools).

This function fully interoperates with the rest of RDPQ, so you can freely intermix it with standard rdpq calls.

Parameters
bufferPointer to the buffer containing RDP commands
sizeSize of the buffer, in bytes (must be a multiple of 8)
Note
This function cannot be called within a block.

◆ __rdpq_autosync_change()

void __rdpq_autosync_change ( uint32_t  res)

Autosync engine: mark certain resources as being changed.

This is the core of the autosync engine. Whenever a resource is "changed" while "in use", a SYNC command must be issued. This is a slightly conservative approach, as the RDP might already have finished using that resource, but we have no way to know it. The SYNC command will then reset the "use" status of each respective resource.

◆ __rdpq_block_begin()

void __rdpq_block_begin ( )

Initialize RDP block mangament.

This is called by rspq_block_begin. It resets all the block management state to default.

Notice that no allocation is performed. This is because we do block allocation lazily as soon as a rdpq command is issued. In fact, if the block does not contain rdpq commands, it would be a waste of time and memory to allocate a RDP buffer. The allocations will be performed by __rdpq_block_next_buffer as soon as a rdpq command is written.

See also
rspq_block_begin
__rdpq_block_next_buffer

◆ __rdpq_block_next_buffer()

void __rdpq_block_next_buffer ( void  )

Allocate a new RDP block buffer, chaining it to the current one (if any)

This function is called by rdpq_passthrough_write and rdpq_write when we are about to write a rdpq command in a block, and the current RDP buffer is full (wptr + cmdsize >= wend). By extension, it is also called when the current RDP buffer has not been allocated yet (wptr == wend == NULL).

See also
rdpq_write
rdpq_passthrough_write

◆ __rdpq_block_end()

rdpq_block_t * __rdpq_block_end ( )

Finish creation of a RDP block.

This is called by rspq_block_end. It finalizes block creation and return a pointer to the first node of the block, which will be put within the rspq_block_t structure, so to be able to reference it in __rdpq_block_run and __rdpq_block_free.

Returns
rdpq_block_t* The created block (first node)
See also
rspq_block_end
__rdpq_block_run
__rdpq_block_free

◆ __rdpq_block_free()

void __rdpq_block_free ( rdpq_block_t block)

Free a block.

This function is called when a block is freed. It is called by rspq_block_free.

See also
rspq_block_free.

◆ __rdpq_block_reserve()

void __rdpq_block_reserve ( int  num_rdp_commands)

Reserve space in the RDP static buffer for a number of RDP commands.

This is called by rdpq_write when run within a block. It makes sure that the static buffer has enough space for the specified number of RDP commands, and also switch back to the dynamic buffer if the command is going to generate a large or unbounded number of commands.

◆ __rdpq_block_update()

void __rdpq_block_update ( volatile uint32_t *  wptr)

Set a new RDP write pointer, and enqueue a RSP command to run the buffer until there.

This function is called by rdpq_passthrough_write after some RDP commands have been written into the block's RDP buffer. A rspq command RSPQ_CMD_RDP_APPEND_BUFFER will be issued so that the RSP will tell the RDP to fetch and run the new commands, appended at the end of the current buffer.

If possible, though, this function will coalesce the command with an immediately preceding RSPQ_CMD_RDP_APPEND_BUFFER (or even RSPQ_CMD_RDP_SET_BUFFER, if we are at the start of the buffer), so that only a single RSP command is issued, which covers multiple RDP commands.

Parameters
wptrNew block's RDP write pointer

◆ rdpq_set_color_image()

void rdpq_set_color_image ( const surface_t surface)

Configure the framebuffer to render to (RDP command: SET_COLOR_IMAGE)

This command is used to specify the render target that the RDP will draw to.

Calling this function also automatically configures scissoring (via rdpq_set_scissor), so that all draw commands are clipped within the buffer, to avoid overwriting memory around it. Use rdpq_config_disable(RDPQ_CFG_AUTOSCISSOR) if you need to disable this behavior.

If you have a raw pointer instead of a surface_t, you can use surface_make to create a temporary surface structure to pass the information to rdpq_set_color_image.

If the passed surface is NULL, rdpq will be detached from the render target. If a drawing command is issued without a render target, it will be silently ignored (but the validator will flag it as an error).

The only valid formats for a surface to be used as a render target are: FMT_RGBA16, FMT_RGBA32, and FMT_I8.

Parameters
[in]surfaceSurface to set as render target
See also
rdpq_set_color_image_raw

◆ rdpq_set_z_image()

void rdpq_set_z_image ( const surface_t surface)

Configure the Z-buffer to use (RDP command: SET_Z_IMAGE)

This commands is used to specify the Z-buffer that will be used by RDP for the next rendering commands.

The surface must have the same width and height of the surface set as render target (via rdpq_set_color_image or rdpq_set_color_image_raw). The color format should be FMT_RGBA16, even though Z values will be written to it.

If the passed surface is NULL, rdpq will be detached from the Z buffer. If a drawing command using Z is issued without a Z buffer, the behaviour will be undefined (but the validator will flag it as an error).

Parameters
surfaceSurface to set as Z buffer
See also
rdpq_set_z_image_raw

◆ rdpq_set_texture_image()

void rdpq_set_texture_image ( const surface_t surface)

Configure the texture to use (RDP command: SET_TEX_IMAGE)

This commands is used to specify the texture image that will be used by RDP for the next load commands (rdpq_load_tile and rdpq_load_block).

The surface must have the same width and height of the surface set as render target (via rdpq_set_color_image or rdpq_set_color_image_raw). The color format should be FMT_RGBA16, even though Z values will be written to it.

Parameters
surfaceSurface to set as texture
See also
rdpq_set_texture_image_raw

◆ rdpq_get_other_modes_raw()

uint64_t rdpq_get_other_modes_raw ( void  )

Read the current render mode register.

This function executes a full sync (rspq_wait) and then extracts the current raw render mode from the RSP state. This should be used only for debugging purposes.

Returns
THe current value of the render mode register.

◆ rdpq_set_tile_autotmem()

void rdpq_set_tile_autotmem ( int16_t  tmem_bytes)

Configure the auto-TMEM feature of rdpq_set_tile.

This function is used to manage the auto-TMEM allocation feature for rdpq_set_tile. It allows to keep track of the allocated space in TMEM, which can be a simplification. It is used by the rdpq_tex module (eg: rdpq_tex_upload).

The feature works like this:

  • First, start auto-TMEM via rdpq_set_tile_autotmem(0)
  • Load a texture and configure a tile for it. When configuring the tile, pass RDPQ_AUTOTMEM as tmem_addr. This will allocate the texture in the first available space.
  • Call rdpq_set_tile_autotmem again passing the number of used bytes in TMEM. Notice that rdpq can't know this by itself.
  • Continue loading the other textures/mipmaps just like before, with RDPQ_AUTOTMEM.
  • If the TMEM is full, a RSP assertion will be triggered.
  • When you are done, call rdpq_set_tile_autotmem passing -1 to finish. This allows reentrant calls to work, and also helps generating errors in case of misuses.

While this API might seem as a small simplification over manually tracking TMEM allocation, it might help modularizing the code, and also allows to record rspq blocks that handle texture loading without hardcoding the TMEM position.

Note
This function is part of the raw API. For a higher-level API on texture loading, see rdpq_tex_upload.
Parameters
tmem_bytes0: begin, -1: end, >0: number of additional bytes that were used in TMEM.
See also
rdpq_set_tile
rdpq_tex_upload

◆ rdpq_sync_full()

void rdpq_sync_full ( void(*)(void *)  callback,
void *  arg 
)

Schedule a RDP SYNC_FULL command and register a callback when it is done.

This function schedules a RDP SYNC_FULL command into the RSP queue. This command basically forces the RDP to finish drawing everything that has been sent to it before it, and then generate an interrupt when it is done.

This is normally useful at the end of the frame. For instance, it is used internally by rdpq_detach to make sure RDP is finished drawing on the target display before detaching it.

The function can be passed an optional callback that will be called when the RDP interrupt triggers. This can be useful to perform some operations asynchronously.

Parameters
callbackA callback to invoke under interrupt when the RDP is finished drawing, or NULL if no callback is necessary.
argOpaque argument that will be passed to the callback.
See also
rspq_wait
rdpq_fence

◆ rdpq_sync_pipe()

void rdpq_sync_pipe ( void  )

Schedule a RDP SYNC_PIPE command.

This command must be sent before changing the RDP pipeline configuration (eg: color combiner, blender, colors, etc.) if the RDP is currently drawing.

Normally, you do not need to call this function because rdpq automatically emits sync commands whenever necessary. You must call this function only if you have disabled autosync for SYNC_PIPE (see RDPQ_CFG_AUTOSYNCPIPE).

Note
No software emulator currently requires this command, so manually sending SYNC_PIPE should be developed on real hardware.

◆ rdpq_sync_tile()

void rdpq_sync_tile ( void  )

Schedule a RDP SYNC_TILE command.

This command must be sent before changing a RDP tile configuration if the RDP is currently drawing using that same tile.

Normally, you do not need to call this function because rdpq automatically emits sync commands whenever necessary. You must call this function only if you have disabled autosync for SYNC_TILE (see RDPQ_CFG_AUTOSYNCTILE).

Note
No software emulator currently requires this command, so manually sending SYNC_TILE should be developed on real hardware.

◆ rdpq_sync_load()

void rdpq_sync_load ( void  )

Schedule a RDP SYNC_LOAD command.

This command must be sent before loading an area of TMEM if the RDP is currently drawing using that same area.

Normally, you do not need to call this function because rdpq automatically emits sync commands whenever necessary. You must call this function only if you have disabled autosync for SYNC_LOAD (see RDPQ_CFG_AUTOSYNCLOAD).

Note
No software emulator currently requires this command, so manually sending SYNC_LOAD should be developed on real hardware.

◆ rdpq_set_fill_color()

void rdpq_set_fill_color ( color_t  color)
inline

Enqueue a SET_FILL_COLOR RDP command.

This command is used to configure the color used by RDP when running in FILL mode (rdpq_set_mode_fill) and normally used by rdpq_fill_rectangle.

Notice that rdpq_set_mode_fill automatically calls this function, because in general it makes no sense to configure the FILL mode without also setting a FILL color.

// Fill top half of the screen in red
rdpq_set_mode_fill(RGBA32(255, 0, 0, 0));
rdpq_fill_rectangle(0, 0, 320, 120);
// Fill bottom half of the screen in blue.
// No need to change mode again (it's already in fill mode),
// so just change the fill color.
rdpq_set_fill_color(RGBA32(0, 0, 255, 0));
rdpq_fill_rectangle(0, 120, 320, 240);
#define RGBA32(rx, gx, bx, ax)
Create a color_t from the R,G,B,A components in the RGBA32 range (0-255).
Definition: graphics.h:49
void rdpq_set_fill_color(color_t color)
Enqueue a SET_FILL_COLOR RDP command.
Definition: rdpq.h:835
void rdpq_set_mode_fill(color_t color)
Reset render mode to FILL type.
Definition: rdpq_mode.h:299
#define rdpq_fill_rectangle(x0, y0, x1, y1)
Draw a filled rectangle (RDP command: FILL_RECTANGLE)
Definition: rdpq_rect.h:235
Parameters
[in]colorThe color to use to fill
See also
rdpq_set_mode_fill

◆ rdpq_set_fill_color_stripes()

void rdpq_set_fill_color_stripes ( color_t  color1,
color_t  color2 
)
inline

Enqueue a SET_FILL_COLOR RDP command to draw a striped pattern.

This command is similar to rdpq_set_fill_color, but allows to configure two colors, and creates a fill pattern that alternates horizontally between them every 2 pixels (creating vertical stripes).

This command relies on a low-level hack of how RDP works in filling primitives, so there is no configuration knob: it only works with RGBA 16-bit target buffers, it only allows two colors, and the vertical stripes are exactly 2 pixel width.

Parameters
[in]color1Color of the first vertical stripe
[in]color2Color of the second vertical stripe
See also
rdpq_set_fill_color

◆ rdpq_set_fog_color()

void rdpq_set_fog_color ( color_t  color)
inline

Set the RDP FOG blender register.

This function sets the internal RDP FOG register, part of the blender unit. As the name implies, this register is normally used as part of fog calculation, but it is actually a generic color register that can be used in custom blender formulas.

Another similar blender register is the BLEND register, configured via rdpq_set_blend_color.

See RDPQ_BLENDER and RDPQ_BLENDER2 on how to configure the blender (typically, via rdpq_mode_blender).

Parameters
[in]colorColor to set the FOG register to
See also
RDPQ_BLENDER
RDPQ_BLENDER2
rdpq_set_blend_color
rdpq_mode_blender

◆ rdpq_set_blend_color()

void rdpq_set_blend_color ( color_t  color)
inline

Set the RDP BLEND blender register.

This function sets the internal RDP BLEND register, part of the blender unit. As the name implies, this register is normally used as part of fog calculation, but it is actually a generic color register that can be used in custom blender formulas.

Another similar blender register is the FOG register, configured via rdpq_set_fog_color.

See RDPQ_BLENDER and RDPQ_BLENDER2 on how to configure the blender (typically, via rdpq_mode_blender).

Parameters
[in]colorColor to set the BLEND register to
See also
RDPQ_BLENDER
RDPQ_BLENDER2
rdpq_set_fog_color
rdpq_mode_blender

◆ rdpq_set_prim_color()

void rdpq_set_prim_color ( color_t  color)
inline

Set the RDP PRIM combiner register (color only) (RDP command: SET_PRIM_COLOR)

This function sets the internal RDP PRIM register, part of the color combiner unit. Naming aside, it is a generic color register that can be used in custom color combiner formulas.

Another similar blender register is the ENV register, configured via rdpq_set_env_color.

See RDPQ_COMBINER1 and RDPQ_COMBINER2 on how to configure the color combiner (typicall, via rdpq_mode_combiner).

If you wish to set PRIM LOD or PRIM MIN LOD values of the PRIM register, see rdpq_set_prim_lod_frac, rdpq_set_detail_factor or rdpq_set_prim_register_raw.

Parameters
[in]colorColor to set the PRIM register to
See also
RDPQ_COMBINER1
RDPQ_COMBINER2
rdpq_set_env_color
rdpq_mode_combiner
rdpq_set_prim_lod_frac
rdpq_set_detail_factor
rdpq_set_prim_register_raw

◆ rdpq_set_detail_factor()

void rdpq_set_detail_factor ( float  value)
inline

Set the detail/sharpen blending factor (RDP command: SET_PRIM_COLOR (partial))

This function sets the internal minimum clamp for LOD fraction, that is used for determining the interpolation blend factor of a detail or sharpen texture at high magnification.

Range is [0..1] where 0 means no influence, and 1 means full influence. The range is internally inverted and converted to [0..31] for the RDP hardware

Parameters
[in]valueValue to set the register to in range [0..1]
See also
RDPQ_COMBINER1
RDPQ_COMBINER2
rdpq_mode_combiner

◆ rdpq_set_prim_lod_frac()

void rdpq_set_prim_lod_frac ( uint8_t  value)
inline

Set the RDP PRIM LOD FRAC combiner register (RDP command: SET_PRIM_COLOR (partial))

This function sets the internal Level of Detail fraction for primitive register, that is used for custom linear interpolation between any two colors in a Color Combiner.

See RDPQ_COMBINER1 and RDPQ_COMBINER2 on how to configure the color combiner (typicall, via rdpq_mode_combiner).

If you wish to set PRIM MIN LOD value, see rdpq_set_detail_factor.

Parameters
[in]valueValue to set the PRIM LOD register to in range [0..255]
See also
RDPQ_COMBINER1
RDPQ_COMBINER2
rdpq_mode_combiner
rdpq_set_detail_factor

◆ rdpq_set_prim_register_raw()

void rdpq_set_prim_register_raw ( color_t  color,
uint8_t  minlod,
uint8_t  primlod 
)
inline

Set the RDP PRIM combiner register (raw version) (RDP command: SET_PRIM_COLOR)

This function sets the internal RDP PRIM register, part of the color combiner unit. Naming aside, it is a generic color register that can be used in custom color combiner formulas.

It also sets the PRIM LOD FRAC and PRIM MIN LOD FRAC values for the PRIM register For more information, see rdpq_set_prim_lod_frac, rdpq_set_detail_factor.

Another similar blender register is the ENV register, configured via rdpq_set_env_color.

See RDPQ_COMBINER1 and RDPQ_COMBINER2 on how to configure the color combiner (typicall, via rdpq_mode_combiner).

If you wish to set PRIM COLOR or PRIM LOD or PRIM MIN LOD values individually, see rdpq_set_prim_lod_frac, rdpq_set_detail_factor or rdpq_set_prim_color.

Parameters
[in]colorColor to set the PRIM register to
[in]minlodMinimum LOD fraction to set the PRIM register to
[in]primlodPrimitive LOD fraction to set the PRIM register to
See also
RDPQ_COMBINER1
RDPQ_COMBINER2
rdpq_set_env_color
rdpq_set_prim_color
rdpq_set_prim_lod_frac
rdpq_set_detail_factor

◆ rdpq_set_env_color()

void rdpq_set_env_color ( color_t  color)
inline

Set the RDP ENV combiner register (RDP command: SET_ENV_COLOR)

This function sets the internal RDP ENV register, part of the color combiner unit. Naming aside, it is a generic color register that can be used in custom color combiner formulas.

Another similar blender register is the PRIM register, configured via rdpq_set_prim_color.

See RDPQ_COMBINER1 and RDPQ_COMBINER2 on how to configure the color combiner (typically, via rdpq_mode_combiner).

Parameters
[in]colorColor to set the ENV register to
See also
RDPQ_COMBINER1
RDPQ_COMBINER2
rdpq_set_prim_color
rdpq_mode_combiner

◆ rdpq_set_prim_depth_raw()

void rdpq_set_prim_depth_raw ( uint16_t  prim_z,
int16_t  prim_dz 
)
inline

Set a fixed Z value to be used instead of a per-pixel value (RDP command; SET_PRIM_DEPTH)

When using z-buffering, normally the Z value used for z-buffering is calculated by interpolating the Z of each vertex onto each pixel. The RDP allows for usage of a fixed Z value instead, for special effects like particles or decals.

This function allows to configure the RDP register that holds the fixed Z value. It is then necessary to activate this special RDP mode: either manually turning on SOM_ZSOURCE_PRIM via rdpq_change_other_modes_raw.

For beginners, it is suggested to use the mode API instead, via rdpq_mode_zoverride.

Parameters
[in]prim_zFixed Z value (in range 0..0x7FFF)
[in]prim_dzDelta Z value (must be a signed power of two). Pass 0 initially, and increment to next power of two in case of problems with objects with the same Z.
Note
Pending further investigation of the exact usage of this function, and specifically the prim_dz parameter, rdpq does not currently offer a higher-level function (rdpq_set_prim_depth).

◆ rdpq_load_tlut_raw()

void rdpq_load_tlut_raw ( rdpq_tile_t  tile,
uint8_t  color_idx,
uint8_t  num_colors 
)
inline

Load a palette of colors into TMEM (RDP command: LOAD_TLUT)

This command is used to load a palette into TMEM. TMEM can hold up to 256 16-bit colors in total to be used as palette, and they must be stored in the upper half of TMEM. These colors are arranged as a single 256-color palette when drawing FMT_CI8 images, or 16 16-colors palettes when drawing FMT_CI4 images.

Storage of colors in TMEM is a bit wasteful, as each color is replicated four times (in fact, 256 colors * 16-bit + 4 = 2048 bytes, which is in fact half of TMEM). This command should be preferred for palette loading as it automatically handles this replication.

Loading a palette manually is a bit involved. It requires configuring the palette in RDRAM via rdpq_set_texture_image, and also configure a tile descriptor with the TMEM destination address (via rdpq_set_tile). Instead, prefer using the simpler rdpq texture API (rdpq_tex.h), via rdpq_tex_upload_tlut.

Parameters
[in]tileTile descriptor to use (TILE0-TILE7). This is used to extract the destination TMEM address (all other fields of the descriptor are ignored).
[in]color_idxIndex of the first color to load into TMEM (0-255). This is a 16-bit offset into the RDRAM buffer set via rdpq_set_texture_image.
[in]num_colorsNumber of colors to load (1-256).
See also
rdpq_tex_upload_tlut

◆ rdpq_set_tile_size_fx()

void rdpq_set_tile_size_fx ( rdpq_tile_t  tile,
uint16_t  s0,
uint16_t  t0,
uint16_t  s1,
uint16_t  t1 
)
inline

Configure the extents of a tile descriptor – fixed point version (RDP command: SET_TILE_SIZE)

This function is similar to rdpq_set_tile_size, but coordinates must be specified using fixed point numbers (10.2).

Parameters
tileTile descriptor (TILE0-TILE7)
[in]s0Top-left X texture coordinate to store in the descriptor (fx 10.2)
[in]t0Top-left Y texture coordinate to store in the descriptor (fx 10.2)
[in]s1Bottom-right exclusive X texture coordinate to store in the descriptor (fx 10.2)
[in]t1Bottom-right exclusive Y texture coordinate to store in the descriptor (fx 10.2)
See also
rdpq_tex_upload
rdpq_set_tile_size

◆ rdpq_load_block()

void rdpq_load_block ( rdpq_tile_t  tile,
uint16_t  s0,
uint16_t  t0,
uint16_t  num_texels,
uint16_t  tmem_pitch 
)
inline

Load a texture image into TMEM with a single contiguous memory transfer (RDP command: LOAD_BLOCK)

This is a command alternative to rdpq_load_tile to load data from RDRAM into TMEM. It is faster than rdpq_load_tile but only allows to transfer a consecutive block of data; the block can cover multiple lines, but not a sub-rectangle of the texture image.

Note
Beginners are advised to use the rdpq texture API (rdpq_tex.h), for instance rdpq_tex_upload that takes care of everything required, including using rdpq_load_block for performance whenever possible.

Before calling rdpq_load_block, the tile must have been configured using rdpq_set_tile to specify the TMEM address, and the texture in RDRAM must have been set via rdpq_set_texture_image.

Note
It is important to notice that the RDP will interpret the tile pitch configured in the tile descriptor with a different semantic: it is used as a number of texels that must be skipped between lines in RDRAM. Normally, for a compact texture, it should then be set to zero in the call to rdpq_set_tile. Instead, The real pitch of the texture in TMEM must be provided to rdpq_load_block itself.

After the call to rdpq_load_block, it is not possible to reuse the tile descriptor for performing a draw. So a new tile descriptor should be configured from scratch using rdpq_set_tile.

The maximum number of texels that can be transferred by a single call is

  1. This allows to fill the TMEM only if a 16-bit or 32-bit texture is used. If you need to load a 4-bit or 8-bit texture, consider configuring the tile descriptor as 16-bit and adjusting the number of texels accordingly. For instance, to transfer a 80x64 4-bit texture (5120 texels), do the transfer as if it was a 20x64 16-bit texture (1280 texels). It doesn't matter if you lie to the RDP during the texture load: what it matters is that the tile descriptor that you will later use for drawing is configured with the correct pixel format.
Parameters
[in]tileTile descriptor (TILE0-TILE7)
[in]s0Top-left X texture coordinate to load
[in]t0Top-left Y texture coordinate to load
[in]num_texelsNumber of texels to load (max: 2048)
[in]tmem_pitchPitch of the texture in TMEM (in bytes)
See also
rdpq_load_tile
rdpq_load_block_fx
rdpq_set_tile
rdpq_tex_upload

◆ rdpq_load_tile_fx()

void rdpq_load_tile_fx ( rdpq_tile_t  tile,
uint16_t  s0,
uint16_t  t0,
uint16_t  s1,
uint16_t  t1 
)
inline

Load a portion of a texture into TMEM – fixed point version (RDP command: LOAD_TILE)

This function is similar to rdpq_load_tile, but coordinates can be specified in fixed point format (0.10.2). Refer to rdpq_load_tile for increased performance

Note
Beginners are advised to use the rdpq texture API (rdpq_tex.h), for instance rdpq_tex_upload that takes care of everything required.
Parameters
[in]tileTile descriptor to use (TILE0-TILE7).
[in]s0Upper-left X coordinate of the portion of the texture to load (fx 0.10.2). Range: 0-4096
[in]t0Upper-left Y coordinate of the portion of the texture to load (fx 0.10.2), Range: 0-4096
[in]s1Bottom-right X coordinate of the portion of the texture to load (fx 0.10.2), Range: 0-4096
[in]t1Bottom-right Y coordinate of the portion of the texture to load (fx 0.10.2), Range: 0-4096
See also
rdpq_load_tile
rdpq_tex_upload

◆ rdpq_set_combiner_raw()

void rdpq_set_combiner_raw ( uint64_t  comb)
inline

Low-level function to change the RDP combiner.

This function enqueues a low-level SET_COMBINE RDP command that changes the RDP combiner, setting it to a new value. You can use RDPQ_COMBINER1 and RDPQ_COMBINER2 to create the combiner settings for respectively a 1-pass or 2-pass combiner.

Note
Prefer using rdpq_mode_combiner (part of the RDPQ mode API), as it better handles integration with other render mode changes.
Parameters
combThe new combiner setting
See also
rdpq_mode_combiner
RDPQ_COMBINER1
RDPQ_COMBINER2

◆ rdpq_set_other_modes_raw()

void rdpq_set_other_modes_raw ( uint64_t  mode)
inline

Low-level function to set the rendering mode register.

This function enqueues a low-level SET_OTHER_MODES RDP command that changes the RDP render mode, setting it to a new value

This function is very low level and requires very good knowledge of internal RDP state management. Moreover, it completely overwrites any existing configuration for all bits, so it must be used with caution within a block.

Note
If possible, prefer using the RDPQ mode API (defined in rdpq_mode.h), that expose a higher level API for changing the RDP modes
Parameters
modeThe new render mode. See the RDP_RM

◆ rdpq_change_other_modes_raw()

void rdpq_change_other_modes_raw ( uint64_t  mask,
uint64_t  val 
)
inline

Low-level function to partly change the rendering mode register.

This function is very low level and requires very good knowledge of internal RDP state management.

It allows to partially change the RDP render mode register, enqueuing a command that will modify only the requested bits. This function is to be preferred to rdpq_set_other_modes_raw as it preservers existing render mode for all the other bits, so it allows for easier composition.

Note
If possible, prefer using the RDPQ mode API (defined in rdpq_mode.h), that expose a higher level API for changing the RDP modes
Parameters
[in]maskMask of bits of the SOM register that must be changed
[in]valNew value for the bits selected by the mask.

◆ rdpq_set_color_image_raw()

void rdpq_set_color_image_raw ( uint8_t  index,
uint32_t  offset,
tex_format_t  format,
uint32_t  width,
uint32_t  height,
uint32_t  stride 
)
inline

Low-level version of rdpq_set_color_image, with address lookup capability.

This is a low-level version of rdpq_set_color_image, that exposes the address lookup capability. It allows to either pass a direct buffer, or to use a buffer already stored in the address lookup table, adding optionally an offset. See rdpq_set_lookup_address for more information.

RDP a physical constraint of 64-byte alignment for render targets, so make sure to respect that while configuring a buffer. The validator will flag such a mistake.

Parameters
indexIndex in the rdpq lookup table of the buffer to set as render target.
offsetByte offset to add to the buffer stored in the lookup table. Notice that if index is 0, this can be a physical address to a buffer (use PhysicalAddr to convert a C pointer to a physical address).
formatFormat of the buffer. Only FMT_RGBA32, FMT_RGBA16 or FMT_I8 are possible to use as a render target.
widthWidth of the buffer in pixel
heightHeight of the buffer in pixel
strideStride of the buffer in bytes (length of a row)
See also
rdpq_set_color_image
rdpq_set_lookup_address

◆ rdpq_set_z_image_raw()

void rdpq_set_z_image_raw ( uint8_t  index,
uint32_t  offset 
)
inline

Low-level version of rdpq_set_z_image, with address lookup capability.

This is a low-level version of rdpq_set_z_image, that exposes the address lookup capability. It allows to either pass a direct buffer, or to use a buffer already stored in the address lookup table, adding optionally an offset. See rdpq_set_lookup_address for more information.

RDP a physical constraint of 64-byte alignment for render targets, so make sure to respect that while configuring a buffer. The validator will flag such a mistake.

Parameters
indexIndex in the rdpq lookup table of the buffer to set as render target.
offsetByte offset to add to the buffer stored in the lookup table. Notice that if index is 0, this can be a physical address to a buffer (use PhysicalAddr to convert a C pointer to a physical address).
See also
rdpq_set_z_image
rdpq_set_lookup_address

◆ rdpq_set_texture_image_raw()

void rdpq_set_texture_image_raw ( uint8_t  index,
uint32_t  offset,
tex_format_t  format,
uint16_t  width,
uint16_t  height 
)
inline

Low-level version of rdpq_set_texture_image, with address lookup capability.

This is a low-level version of rdpq_set_texture_image, that exposes the address lookup capability. It allows to either pass a direct buffer, or to use a buffer already stored in the address lookup table, adding optionally an offset. See rdpq_set_lookup_address for more information.

RDP a physical constraint of 8-byte alignment for textures, so make sure to respect that while configuring a buffer. The validator will flag such a mistake.

Parameters
indexIndex in the rdpq lookup table of the buffer to set as texture image.
offsetByte offset to add to the buffer stored in the lookup table. Notice that if index is 0, this can be a physical address to a buffer (use PhysicalAddr to convert a C pointer to a physical address).
formatFormat of the texture (tex_format_t)
widthWidth of the texture in pixel (max 1024)
heightHeight of the texture in pixel (max 1024)
See also
rdpq_set_texture_image
rdpq_set_lookup_address

◆ rdpq_set_lookup_address()

void rdpq_set_lookup_address ( uint8_t  index,
void *  rdram_addr 
)
inline

Store an address into the rdpq lookup table.

This function is for advanced usages, it is not normally required to call it.

This function modifies the internal RDPQ address lookup table, by storing an address into on of the available slots.

The lookup table is used to allow for an indirect access to surface pointers. For instance, some library code might want to record a block that manipulates several surfaces, but without saving the actual surface pointers within the block. Instead, all commands referring to a surface, will actually refer to an index into the lookup table. The caller of the block will then store the actual buffer pointers in the table, before playing back the block.

While recording, you can create a placeholder surface via surface_make_placeholder or surface_make_placeholder_linear that is just an "index" into the lookup table.

// Create placeholder surfaces with indices 3 and 4
// Start recording a block.
// Load texture from lookup table (slot 3) and draw it to the screen
rdpq_load_tile(0, 0, 32, 32);
rdpq_texture_rectangle(0, 0, 32, 32);
// Load texture from lookup table (slot 4) and draw it to the screen
rdpq_load_tile(0, 0, 32, 32);
rdpq_texture_rectangle(32, 0, 64, 32);
[...]
// Set two real textures into the the lookup table and call the block
rdpq_set_lookup_address(3, robot->buffer);
rdpq_set_lookup_address(4, dragon->buffer);
void rdpq_set_texture_image(const surface_t *surface)
Configure the texture to use (RDP command: SET_TEX_IMAGE)
Definition: rdpq.c:1023
void rdpq_set_lookup_address(uint8_t index, void *rdram_addr)
Store an address into the rdpq lookup table.
Definition: rdpq.h:1294
#define rdpq_load_tile(tile, s0, t0, s1, t1)
Load a portion of a texture into TMEM (RDP command: LOAD_TILE)
Definition: rdpq.h:517
void rdpq_set_mode_standard(void)
Reset render mode to standard.
Definition: rdpq_mode.c:92
#define rdpq_texture_rectangle(tile, x0, y0, x1, y1, s, t)
Draw a textured rectangle (RDP command: TEXTURE_RECTANGLE)
Definition: rdpq_rect.h:293
void rspq_block_begin(void)
Begin creating a new block.
Definition: rspq.c:1102
rspq_block_t * rspq_block_end(void)
Finish creating a block.
Definition: rspq.c:1121
void rspq_block_run(rspq_block_t *block)
Add to the RSP queue a command that runs a block.
Definition: rspq.c:1177
A rspq block: pre-recorded array of commands.
Definition: rspq_internal.h:160
@ FMT_RGBA16
Format RGBA 5551 (16-bit)
Definition: surface.h:106
surface_t surface_make_placeholder_linear(int index, tex_format_t format, uint32_t width, uint32_t height)
Create a linear placeholder surface, that can be used during rdpq block recording.
Definition: surface.h:318
A surface buffer for graphics.
Definition: surface.h:138
Note
RDP has some alignment constraints: color and Z buffers must be 64-byte aligned, and textures must be 8-byte aligned.
Parameters
indexIndex of the slot in the table. Available slots are 1-15 (slot 0 is reserved).
rdram_addrPointer of the buffer to store into the address table.

◆ rdpq_set_tile()

void rdpq_set_tile ( rdpq_tile_t  tile,
tex_format_t  format,
int32_t  tmem_addr,
uint16_t  tmem_pitch,
const rdpq_tileparms_t parms 
)
inline

Enqueue a RDP SET_TILE command (full version)

Parameters
[in]tileTile descriptor index (0-7)
[in]formatTexture format for the tile. Cannot be 0. Should correspond to X_get_format in surface_t or sprite_t;
[in]tmem_addrAddress in tmem where the texture is (or will be loaded). Must be multiple of 8;
[in]tmem_pitchPitch of the texture in tmem in bytes. Must be multiple of 8. Should correspond to srtide in surface_t;
[in]parmsAdditional optional parameters for the tile. Can be left NULL or all 0. More information about the struct is in rdpq_tileparms_t

Variable Documentation

◆ __rdpq_inited

bool __rdpq_inited = false

True if rdpq_init was called.

True if the rdpq module was inited.