libdragon
|
RDP Command queue: internal functions. More...
Go to the source code of this file.
Data Structures | |
struct | rdpq_tracking_t |
RDP tracking state. More... | |
struct | rdpq_block_t |
A buffer that piggybacks onto rspq_block_t to store RDP commands. More... | |
struct | rdpq_block_state_t |
RDP block management state. More... | |
Macros | |
#define | rdpq_passthrough_write(rdp_cmd) |
Write a passthrough RDP command into the rspq queue. | |
Functions | |
void | rdpq_fence (void) |
Public rdpq_fence API, redefined it. | |
void | __rdpq_block_begin () |
Initialize RDP block mangament. | |
rdpq_block_t * | __rdpq_block_end () |
Finish creation of a RDP block. | |
void | __rdpq_block_free (rdpq_block_t *block) |
Free a block. | |
void | __rdpq_block_run (rdpq_block_t *block) |
Notify that a rspq block was run (called by rspq_block_run). | |
void | __rdpq_block_next_buffer (void) |
Allocate a new RDP block buffer, chaining it to the current one (if any) | |
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. | |
void | __rdpq_block_reserve (int num_rdp_commands) |
Reserve space in the RDP static buffer for a number of RDP commands. | |
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. | |
void | __rdpq_write8 (uint32_t cmd_id, uint32_t arg0, uint32_t arg1) |
Write a standard 8-byte RDP command. | |
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_triangle_cpu (const rdpq_trifmt_t *fmt, const float *v1, const float *v2, const float *v3) |
RDP triangle primitive assembled on the CPU. | |
void | rdpq_triangle_rsp (const rdpq_trifmt_t *fmt, const float *v1, const float *v2, const float *v3) |
RDP triangle primitive assembled on the RSP. | |
Variables | |
bool | __rdpq_inited |
True if the rdpq module was inited. | |
rdpq_tracking_t | rdpq_tracking |
Tracking state of RDP. | |
RDP Command queue: internal functions.
struct rdpq_tracking_t |
RDP tracking state.
This structure contains information that refer to the state of the RDP, tracked by the CPU as it enqueues RDP instructions.ì
Tracking the RDP state on the CPU is in general possible (as all RDP commands are supposed to go through rdpq, when it is used), but it doesn't fully work across blocks. In fact, blocks can be called in multiple call sites with different RDP states, so it would be wrong to do any assumption on the RDP state while generating the block.
Thus, this structure is reset at some default by __rdpq_block_begin, and then its previous state is restored by __rdpq_block_end.
struct rdpq_block_t |
A buffer that piggybacks onto rspq_block_t to store RDP commands.
In rspq blocks, raw RDP commands are not stored as passthroughs for performance. Instead, they are stored in a parallel buffer in RDRAM and the RSP block contains commands to send (portions of) this buffer directly to RDP via DMA. This saves memory bandwidth compared to doing passthrough for every command.
Since the buffer can grow during creation, it is stored as a linked list of buffers.
Data Fields | ||
---|---|---|
rdpq_block_t * | next | Link to next buffer (or NULL if this is the last one for this block) |
rdpq_tracking_t | tracking | Tracking state at the end of a block (this is populated only on the first link) |
uint32_t | cmds[] | RDP commands. |
struct rdpq_block_state_t |
RDP block management state.
This is the internal state used by rdpq.c to manage block creation.
Data Fields | ||
---|---|---|
volatile uint32_t * | wptr | During block creation, current write pointer within the RDP buffer. |
volatile uint32_t * | wend | During block creation, pointer to the end of the RDP buffer. |
volatile uint32_t * | pending_wptr | Previous wptr, swapped out to go back to dynamic buffer. |
volatile uint32_t * | pending_wend | Previous wend, swapped out to go back to dynamic buffer. |
rdpq_block_t * | last_node | Point to the RDP block being created. |
rdpq_block_t * | first_node | Point to the first link of the RDP block being created. |
int | bufsize | Current buffer size for RDP blocks. |
volatile uint32_t * | last_rdp_append_buffer |
During block creation, this variable points to the last RSPQ_CMD_RDP_APPEND_BUFFER command, that can be coalesced in case a pure RDP command is enqueued next. |
rdpq_tracking_t | previous_tracking | Tracking state before starting building the block. |
#define rdpq_passthrough_write | ( | rdp_cmd | ) |
Write a passthrough RDP command into the rspq queue.
This macro handles writing a single RDP command into the rspq queue. It must be used only with raw commands aka passthroughs, that is commands that are not intercepted by RSP in any way, but just forwarded to RDP.
In block mode, the RDP command will be written to the static RDP buffer instead, so that it will be sent directly to RDP without going through RSP at all.
Example syntax (notice the double parenthesis):
rdpq_passthrough_write((RDPQ_CMD_SYNC_PIPE, 0, 0));
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.
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.
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.
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
).
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.
wptr | New block's RDP write pointer |
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.
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.
|
extern |
True if the rdpq module was inited.
True if the rdpq module was inited.