libdragon
Loading...
Searching...
No Matches
rdpq.h
Go to the documentation of this file.
1
144#ifndef __LIBDRAGON_RDPQ_H
145#define __LIBDRAGON_RDPQ_H
146
147#include <stdint.h>
148#include <stdbool.h>
149#include <string.h>
150#include "graphics.h"
151#include "n64sys.h"
152#include "rdpq_macros.h"
153#include "surface.h"
154#include "debug.h"
155
157
158// Static overlay ID for RDP/RDPQ commands
159#define RDPQ_OVL_ID (0xC << 28)
160
161// List of RDPQ internal RSP commands.
162// NOTE: this is *NOT* part of the public API of rdpq.
163enum {
164 RDPQ_CMD_NOOP = 0x00,
165 RDPQ_CMD_SET_LOOKUP_ADDRESS = 0x01,
166 RDPQ_CMD_FILL_RECTANGLE_EX = 0x02,
167 RDPQ_CMD_RESET_RENDER_MODE = 0x04,
168 RDPQ_CMD_SET_COMBINE_MODE_2PASS = 0x05,
169 RDPQ_CMD_PUSH_RENDER_MODE = 0x06,
170 RDPQ_CMD_POP_RENDER_MODE = 0x07,
171 RDPQ_CMD_TRI = 0x08,
172 RDPQ_CMD_TRI_ZBUF = 0x09,
173 RDPQ_CMD_TRI_TEX = 0x0A,
174 RDPQ_CMD_TRI_TEX_ZBUF = 0x0B,
175 RDPQ_CMD_TRI_SHADE = 0x0C,
176 RDPQ_CMD_TRI_SHADE_ZBUF = 0x0D,
177 RDPQ_CMD_TRI_SHADE_TEX = 0x0E,
178 RDPQ_CMD_TRI_SHADE_TEX_ZBUF = 0x0F,
179
180 RDPQ_CMD_TEXTURE_RECTANGLE_EX = 0x10,
181 RDPQ_CMD_SET_DEBUG_MODE = 0x11,
182 RDPQ_CMD_SET_SCISSOR_EX = 0x12,
183 RDPQ_CMD_SET_PRIM_COLOR_COMPONENT = 0x13,
184 RDPQ_CMD_MODIFY_OTHER_MODES = 0x14,
185 RDPQ_CMD_SET_FILL_COLOR_32 = 0x16,
186 RDPQ_CMD_SET_BLENDING_MODE = 0x18,
187 RDPQ_CMD_SET_FOG_MODE = 0x19,
188 RDPQ_CMD_SET_COMBINE_MODE_1PASS = 0x1B,
189 RDPQ_CMD_AUTOTMEM_SET_ADDR = 0x1C,
190 RDPQ_CMD_AUTOTMEM_SET_TILE = 0x1D,
191 RDPQ_CMD_TRIANGLE = 0x1E,
192 RDPQ_CMD_TRIANGLE_DATA = 0x1F,
193
194 RDPQ_CMD_TEXTURE_RECTANGLE = 0x24,
195 RDPQ_CMD_TEXTURE_RECTANGLE_FLIP = 0x25,
196 RDPQ_CMD_SYNC_LOAD = 0x26,
197 RDPQ_CMD_SYNC_PIPE = 0x27,
198 RDPQ_CMD_SYNC_TILE = 0x28,
199 RDPQ_CMD_SYNC_FULL = 0x29,
200 RDPQ_CMD_SET_KEY_GB = 0x2A,
201 RDPQ_CMD_SET_KEY_R = 0x2B,
202 RDPQ_CMD_SET_CONVERT = 0x2C,
203 RDPQ_CMD_SET_SCISSOR = 0x2D,
204 RDPQ_CMD_SET_PRIM_DEPTH = 0x2E,
205 RDPQ_CMD_SET_OTHER_MODES = 0x2F,
206
207 RDPQ_CMD_LOAD_TLUT = 0x30,
208 RDPQ_CMD_DEBUG = 0x31,
209 RDPQ_CMD_SET_TILE_SIZE = 0x32,
210 RDPQ_CMD_LOAD_BLOCK = 0x33,
211 RDPQ_CMD_LOAD_TILE = 0x34,
212 RDPQ_CMD_SET_TILE = 0x35,
213 RDPQ_CMD_FILL_RECTANGLE = 0x36,
214 RDPQ_CMD_SET_FILL_COLOR = 0x37,
215 RDPQ_CMD_SET_FOG_COLOR = 0x38,
216 RDPQ_CMD_SET_BLEND_COLOR = 0x39,
217 RDPQ_CMD_SET_PRIM_COLOR = 0x3A,
218 RDPQ_CMD_SET_ENV_COLOR = 0x3B,
219 RDPQ_CMD_SET_COMBINE_MODE_RAW = 0x3C,
220 RDPQ_CMD_SET_TEXTURE_IMAGE = 0x3D,
221 RDPQ_CMD_SET_Z_IMAGE = 0x3E,
222 RDPQ_CMD_SET_COLOR_IMAGE = 0x3F,
223};
225
226#define RDPQ_CFG_AUTOSYNCPIPE (1 << 0)
227#define RDPQ_CFG_AUTOSYNCLOAD (1 << 1)
228#define RDPQ_CFG_AUTOSYNCTILE (1 << 2)
229#define RDPQ_CFG_AUTOSCISSOR (1 << 3)
230#define RDPQ_CFG_DEFAULT (0xFFFF)
231
233// Used in inline functions as part of the autosync engine. Not part of public API.
234#define AUTOSYNC_TILE(n) (1 << (0+(n))) // Autosync state: Bit used for tile N
235#define AUTOSYNC_TILES (0xFF << 0) // Autosync state: Mask for all bits regarding tile
236#define AUTOSYNC_TMEM(n) (1 << (8+(n))) // Autosync state: Bit used for tmem portion N
237#define AUTOSYNC_TMEMS (0xFF << 8) // Autosync state: Mask for all bits regarding TMEM
238#define AUTOSYNC_PIPE (1 << 16) // Autosync state: Bit used for pipe
240
242/* Used internally for bit-packing RDP commands. Not part of public API. */
243#define _carg(value, mask, shift) (((uint32_t)((value) & (mask))) << (shift))
245
251typedef enum {
252 TILE0 = 0,
253 TILE1 = 1,
254 TILE2 = 2,
255 TILE3 = 3,
256 TILE4 = 4,
257 TILE5 = 5,
258 TILE6 = 6,
259 TILE7 = 7,
261
262
273typedef struct {
274 uint8_t palette;
275
276 // Additional mapping parameters; Leave them as 0 if not required;
277
278 struct{
279 bool clamp;
280 bool mirror;
281 uint8_t mask;
282 int8_t shift;
283 } s,t; // S/T directions of the tile descriptor
284
286
288#define RDPQ_TILE_INTERNAL TILE7
289
290#ifdef __cplusplus
291extern "C" {
292#endif
293
295extern void __rdpq_set_scissor(uint32_t, uint32_t);
296
308void rdpq_init(void);
309
315void rdpq_close(void);
316
317
336uint32_t rdpq_config_set(uint32_t cfg);
337
351uint32_t rdpq_config_enable(uint32_t cfg_enable_bits);
352
353
382uint32_t rdpq_config_disable(uint32_t cfg_disable_bits);
383
387inline void rdpq_set_yuv_parms(uint16_t k0, uint16_t k1, uint16_t k2, uint16_t k3, uint16_t k4, uint16_t k5)
388{
389 extern void __rdpq_write8_syncchange(uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t autosync);
390 __rdpq_write8_syncchange(RDPQ_CMD_SET_CONVERT,
391 _carg(k0, 0x1FF, 13) | _carg(k1, 0x1FF, 4) | (((uint32_t)(k2 & 0x1FF)) >> 5),
392 _carg(k2, 0x1F, 27) | _carg(k3, 0x1FF, 18) | _carg(k4, 0x1FF, 9) | _carg(k5, 0x1FF, 0),
393 AUTOSYNC_PIPE);
394}
395
425#define rdpq_set_scissor(x0, y0, x1, y1) ({ \
426 int32_t x0fx = (x0)*4; \
427 int32_t y0fx = (y0)*4; \
428 int32_t x1fx = (x1)*4; \
429 int32_t y1fx = (y1)*4; \
430 assertf(x0fx <= x1fx, "x1 must be greater or equal to x0"); \
431 assertf(y0fx <= y1fx, "y1 must be greater or equal to y0"); \
432 assertf(x0fx >= 0, "x0 must be positive"); \
433 assertf(y0fx >= 0, "y0 must be positive"); \
434 assertf(x1fx <= 0xFFF, "x1 must be less than 1024"); \
435 assertf(y1fx <= 0xFFF, "y1 must be less than 1024"); \
436 __rdpq_set_scissor( \
437 _carg(x0fx, 0xFFF, 12) | _carg(y0fx, 0xFFF, 0), \
438 _carg(x1fx, 0xFFF, 12) | _carg(y1fx, 0xFFF, 0)); \
439})
440
466 inline void rdpq_set_prim_depth_raw(uint16_t prim_z, int16_t prim_dz)
467{
468 // NOTE: this does not require a pipe sync
469 extern void __rdpq_write8(uint32_t, uint32_t, uint32_t);
470 assertf(prim_z <= 0x7FFF, "prim_z must be in [0..0x7FFF]");
471 assertf((prim_dz & -prim_dz) == (prim_dz >= 0 ? prim_dz : -prim_dz),
472 "prim_dz must be a power of 2");
473 __rdpq_write8(RDPQ_CMD_SET_PRIM_DEPTH, 0, _carg(prim_z, 0xFFFF, 16) | _carg(prim_dz, 0xFFFF, 0));
474}
475
521#define rdpq_load_tile(tile, s0, t0, s1, t1) ({ \
522 assertf((s0) >= 0 && (t0) >= 0 && (s1) >= 0 && (t1) >= 0, "texture coordinates must be positive"); \
523 assertf((s0) < 1024 && (t0) < 1024 && (s1) < 1024 && (t1) < 1024, "texture coordinates must be smaller than 1024"); \
524 rdpq_load_tile_fx((tile), (s0)*4, (t0)*4, (s1)*4, (t1)*4); \
525})
526
550inline void rdpq_load_tile_fx(rdpq_tile_t tile, uint16_t s0, uint16_t t0, uint16_t s1, uint16_t t1)
551{
552 extern void __rdpq_write8_syncchangeuse(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
553 __rdpq_write8_syncchangeuse(RDPQ_CMD_LOAD_TILE,
554 _carg(s0, 0xFFF, 12) | _carg(t0, 0xFFF, 0),
555 _carg(tile, 0x7, 24) | _carg(s1-4, 0xFFF, 12) | _carg(t1-4, 0xFFF, 0),
556 AUTOSYNC_TMEM(0) | AUTOSYNC_TILE(tile),
557 AUTOSYNC_TILE(tile));
558}
559
560
591inline void rdpq_load_tlut_raw(rdpq_tile_t tile, int color_idx, int num_colors)
592{
593 extern void __rdpq_write8_syncchangeuse(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
594 __rdpq_write8_syncchangeuse(RDPQ_CMD_LOAD_TLUT,
595 _carg(color_idx, 0xFF, 14),
596 _carg(tile, 0x7, 24) | _carg(color_idx+num_colors-1, 0xFF, 14),
597 AUTOSYNC_TMEM(0),
598 AUTOSYNC_TILE(tile));
599}
600
627#define rdpq_set_tile_size(tile, s0, t0, s1, t1) ({ \
628 rdpq_set_tile_size_fx((tile), (s0)*4, (t0)*4, (s1)*4, (t1)*4); \
629})
630
646inline void rdpq_set_tile_size_fx(rdpq_tile_t tile, uint16_t s0, uint16_t t0, uint16_t s1, uint16_t t1)
647{
648 assertf((s0) >= 0 && (t0) >= 0 && (s1) >= 0 && (t1) >= 0, "texture coordinates must be positive");
649 assertf((s0) <= 1024*4 && (t0) <= 1024*4 && (s1) <= 1024*4 && (t1) <= 1024*4, "texture coordinates must be smaller than 1024");
650
651 extern void __rdpq_write8_syncchange(uint32_t, uint32_t, uint32_t, uint32_t);
652 __rdpq_write8_syncchange(RDPQ_CMD_SET_TILE_SIZE,
653 _carg(s0, 0xFFF, 12) | _carg(t0, 0xFFF, 0),
654 _carg(tile, 0x7, 24) | _carg(s1-4, 0xFFF, 12) | _carg(t1-4, 0xFFF, 0),
655 AUTOSYNC_TILE(tile));
656}
657
658
662inline void rdpq_load_block_fx(rdpq_tile_t tile, uint16_t s0, uint16_t t0, uint16_t num_texels, uint16_t dxt)
663{
664 extern void __rdpq_write8_syncchangeuse(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
665 __rdpq_write8_syncchangeuse(RDPQ_CMD_LOAD_BLOCK,
666 _carg(s0, 0xFFF, 12) | _carg(t0, 0xFFF, 0),
667 _carg(tile, 0x7, 24) | _carg(num_texels-1, 0xFFF, 12) | _carg(dxt, 0xFFF, 0),
668 AUTOSYNC_TMEM(0),
669 AUTOSYNC_TILE(tile));
670}
671
719inline void rdpq_load_block(rdpq_tile_t tile, uint16_t s0, uint16_t t0, uint16_t num_texels, uint16_t tmem_pitch)
720{
721 assertf(num_texels <= 2048, "invalid num_texels %d: must be smaller than 2048", num_texels);
722 assertf((tmem_pitch % 8) == 0, "invalid tmem_pitch %d: must be multiple of 8", tmem_pitch);
723 // Dxt is the reciprocal of the number of 64 bit words in a line in 1.11 format, rounded up
724 uint32_t words = tmem_pitch / 8;
725 rdpq_load_block_fx(tile, s0, t0, num_texels, (2048 + words - 1) / words);
726}
727
728
730#define RDPQ_AUTOTMEM (0x8000)
732#define RDPQ_AUTOTMEM_REUSE(offset) (0x4000 | ((offset)/8))
733
734
741inline void rdpq_set_tile(rdpq_tile_t tile,
742 tex_format_t format,
743 int32_t tmem_addr,
744 uint16_t tmem_pitch,
745 const rdpq_tileparms_t *parms)
746{
747 static const rdpq_tileparms_t default_parms = {0};
748 if (!parms) parms = &default_parms;
749 else {
750 assertf(parms->s.shift >= -5 && parms->s.shift <= 10, "invalid s shift %d: must be in [-5..10]", parms->s.shift);
751 assertf(parms->t.shift >= -5 && parms->t.shift <= 10, "invalid t shift %d: must be in [-5..10]", parms->t.shift);
752 assertf(parms->palette < 16, "invalid palette %d: must be in [0..15]", parms->palette);
753 }
754 bool fixup = false;
755 bool reuse = false;
756 uint32_t cmd_id = RDPQ_CMD_SET_TILE;
757 if (tmem_addr & (RDPQ_AUTOTMEM | RDPQ_AUTOTMEM_REUSE(0))) {
758 cmd_id = RDPQ_CMD_AUTOTMEM_SET_TILE;
759 reuse = (tmem_addr & RDPQ_AUTOTMEM_REUSE(0)) != 0;
760 fixup = true;
761 tmem_addr &= ~(RDPQ_AUTOTMEM | RDPQ_AUTOTMEM_REUSE(0));
762 } else {
763 assertf((tmem_addr % 8) == 0, "invalid tmem_addr %ld: must be multiple of 8", tmem_addr);
764 tmem_addr /= 8;
765 }
766 assertf((tmem_pitch % 8) == 0, "invalid tmem_pitch %d: must be multiple of 8", tmem_pitch);
767 extern void __rdpq_write8_syncchange(uint32_t, uint32_t, uint32_t, uint32_t);
768 extern void __rdpq_fixup_write8_syncchange(uint32_t, uint32_t, uint32_t, uint32_t);
770 _carg(format, 0x1F, 19) | _carg(reuse, 0x1, 18) | _carg(tmem_pitch/8, 0x1FF, 9) | _carg(tmem_addr, 0x1FF, 0),
771 _carg(tile, 0x7, 24) | _carg(parms->palette, 0xF, 20) |
772 _carg(parms->t.clamp | (parms->t.mask == 0), 0x1, 19) | _carg(parms->t.mirror, 0x1, 18) | _carg(parms->t.mask, 0xF, 14) | _carg(parms->t.shift, 0xF, 10) |
773 _carg(parms->s.clamp | (parms->s.mask == 0), 0x1, 9) | _carg(parms->s.mirror, 0x1, 8) | _carg(parms->s.mask, 0xF, 4) | _carg(parms->s.shift, 0xF, 0),
774 AUTOSYNC_TILE(tile));
775}
776
813void rdpq_set_tile_autotmem(int16_t tmem_bytes);
814
840inline void rdpq_set_fill_color(color_t color) {
841 extern void __rdpq_set_fill_color(uint32_t);
842 __rdpq_set_fill_color((color.r << 24) | (color.g << 16) | (color.b << 8) | (color.a << 0));
843}
844
863inline void rdpq_set_fill_color_stripes(color_t color1, color_t color2) {
864 extern void __rdpq_write8_syncchange(uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t autosync);
865 uint32_t c1 = (((int)color1.r >> 3) << 11) | (((int)color1.g >> 3) << 6) | (((int)color1.b >> 3) << 1) | (color1.a >> 7);
866 uint32_t c2 = (((int)color2.r >> 3) << 11) | (((int)color2.g >> 3) << 6) | (((int)color2.b >> 3) << 1) | (color2.a >> 7);
867 __rdpq_write8_syncchange(RDPQ_CMD_SET_FILL_COLOR, 0, (c1 << 16) | c2,
868 AUTOSYNC_PIPE);
869}
870
892inline void rdpq_set_fog_color(color_t color)
893{
894 extern void __rdpq_write8_syncchange(uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t autosync);
895 __rdpq_write8_syncchange(RDPQ_CMD_SET_FOG_COLOR, 0, color_to_packed32(color),
896 AUTOSYNC_PIPE);
897}
898
921{
922 extern void __rdpq_write8_syncchange(uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t autosync);
923 __rdpq_write8_syncchange(RDPQ_CMD_SET_BLEND_COLOR, 0, color_to_packed32(color),
924 AUTOSYNC_PIPE);
925}
926
954inline void rdpq_set_prim_color(color_t color)
955{
956 // NOTE: this does not require a pipe sync
957 extern void __rdpq_fixup_write8_syncchange(uint32_t, uint32_t, uint32_t, uint32_t);
958 __rdpq_fixup_write8_syncchange(RDPQ_CMD_SET_PRIM_COLOR_COMPONENT, (0<<16), color_to_packed32(color), 0);
959}
960
978inline void rdpq_set_detail_factor(float value)
979{
980 // NOTE: this does not require a pipe sync
981 int8_t conv = (1.0 - value) * 31;
982 extern void __rdpq_fixup_write8_syncchange(uint32_t, uint32_t, uint32_t, uint32_t);
983 __rdpq_fixup_write8_syncchange(RDPQ_CMD_SET_PRIM_COLOR_COMPONENT, ((conv & 0x1F) << 8) | (2<<16), 0, 0);
984}
985
1005inline void rdpq_set_prim_lod_frac(uint8_t value)
1006{
1007 // NOTE: this does not require a pipe sync
1008 extern void __rdpq_fixup_write8_syncchange(uint32_t, uint32_t, uint32_t, uint32_t);
1009 __rdpq_fixup_write8_syncchange(RDPQ_CMD_SET_PRIM_COLOR_COMPONENT, value | (1<<16), 0, 0);
1010}
1011
1043inline void rdpq_set_prim_register_raw(color_t color, uint8_t minlod, uint8_t primlod)
1044{
1045 extern void __rdpq_write8(uint32_t cmd_id, uint32_t arg0, uint32_t arg1);
1046 __rdpq_write8(RDPQ_CMD_SET_PRIM_COLOR, ((minlod & 0x1F) << 8) | primlod, color_to_packed32(color));
1047}
1048
1070inline void rdpq_set_env_color(color_t color)
1071{
1072 extern void __rdpq_write8_syncchange(uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t autosync);
1073 __rdpq_write8_syncchange(RDPQ_CMD_SET_ENV_COLOR, 0, color_to_packed32(color),
1074 AUTOSYNC_PIPE);
1075}
1076
1101void rdpq_set_color_image(const surface_t *surface);
1102
1121void rdpq_set_z_image(const surface_t* surface);
1122
1137void rdpq_set_texture_image(const surface_t* surface);
1138
1163inline 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)
1164{
1165 assertf(format == FMT_RGBA32 || format == FMT_RGBA16 ||
1166 format == FMT_I8 || format == FMT_CI8,
1167 "Image format is not supported as color image: %s\nIt must be FMT_RGBA32, FMT_RGBA16, FMT_I8 or FMT_CI8", tex_format_name(format));
1168 assertf(index <= 15, "Lookup address index out of range [0,15]: %d", index);
1169
1170 extern void __rdpq_set_color_image(uint32_t, uint32_t, uint32_t, uint32_t);
1172 _carg(format, 0x1F, 19) | _carg(TEX_FORMAT_BYTES2PIX(format, stride)-1, 0x3FF, 0) | _carg(height-1, 0x1FF, 10),
1173 _carg(index, 0xF, 28) | (offset & 0xFFFFFF) | _carg((height-1)>>9, 0x1, 31),
1174 _carg(0, 0xFFF, 12) | _carg(0, 0xFFF, 0), // for set_scissor
1175 _carg(width*4, 0xFFF, 12) | _carg(height*4, 0xFFF, 0)); // for set_scissor
1176}
1177
1197inline void rdpq_set_z_image_raw(uint8_t index, uint32_t offset)
1198{
1199 assertf(index <= 15, "Lookup address index out of range [0,15]: %d", index);
1200 extern void __rdpq_fixup_write8_syncchange(uint32_t, uint32_t, uint32_t, uint32_t);
1201 __rdpq_fixup_write8_syncchange(RDPQ_CMD_SET_Z_IMAGE,
1202 0,
1203 _carg(index, 0xF, 28) | (offset & 0xFFFFFF),
1204 AUTOSYNC_PIPE);
1205}
1206
1229inline void rdpq_set_texture_image_raw(uint8_t index, uint32_t offset, tex_format_t format, uint16_t width, uint16_t height)
1230{
1231 assertf(width <= 1024, "Texture width out of range [1,1024]: %d", width);
1232 assertf(height <= 1024, "Texture height out of range [1,1024]: %d", height);
1233 assertf(index <= 15, "Lookup address index out of range [0,15]: %d", index);
1234 extern void __rdpq_fixup_write8_syncchange(uint32_t, uint32_t, uint32_t, uint32_t);
1235 // NOTE: we also encode the texture height in the command (split in two halves...)
1236 // to help the validator to a better job. The RDP hardware ignores those bits.
1237 __rdpq_fixup_write8_syncchange(RDPQ_CMD_SET_TEXTURE_IMAGE,
1238 _carg(format, 0x1F, 19) | _carg(width-1, 0x3FF, 0) | _carg(height-1, 0x1FF, 10),
1239 _carg(index, 0xF, 28) | (offset & 0xFFFFFF) | _carg((height-1)>>9, 0x1, 31),
1240 AUTOSYNC_PIPE);
1241}
1242
1255inline void rdpq_load_block_linear(int32_t offset, void *buffer, uint16_t size)
1256{
1257 assertf((offset & 7) == 0, "invalid TMEM offset %ld: must be 8-byte aligned", offset);
1258 assertf((PhysicalAddr(buffer) & 7) == 0, "invalid buffer: %p, must be 8-byte aligned", buffer);
1259 assertf((size & 7) == 0, "invalid size %d: must be a multiple of 8", size);
1260 assertf(size <= 4096, "invalid size %d: must fit TMEM", size);
1261 rdpq_set_texture_image_raw(0, PhysicalAddr(buffer), FMT_RGBA16, 8, size / 8);
1262 rdpq_set_tile(RDPQ_TILE_INTERNAL, FMT_RGBA16, offset, 0, NULL);
1263 uint32_t num_texels = size / 2;
1264 rdpq_load_block(RDPQ_TILE_INTERNAL, 0, 0, num_texels, 16);
1265}
1266
1323inline void rdpq_set_lookup_address(uint8_t index, void* rdram_addr)
1324{
1325 assertf(index > 0 && index <= 15, "Lookup address index out of range [1,15]: %d", index);
1326 extern void __rdpq_write8(uint32_t, uint32_t, uint32_t);
1327 __rdpq_write8(RDPQ_CMD_SET_LOOKUP_ADDRESS, index << 2, PhysicalAddr(rdram_addr));
1328}
1329
1343void rdpq_sync_pipe(void);
1344
1358void rdpq_sync_tile(void);
1359
1373void rdpq_sync_load(void);
1374
1398void rdpq_sync_full(void (*callback)(void*), void* arg);
1399
1400
1417inline void rdpq_set_other_modes_raw(uint64_t mode)
1418{
1419 extern void __rdpq_set_other_modes(uint32_t, uint32_t);
1421 (mode >> 32) & 0x00FFFFFF,
1422 mode & 0xFFFFFFFF);
1423}
1424
1443inline void rdpq_change_other_modes_raw(uint64_t mask, uint64_t val)
1444{
1445 extern void __rdpq_change_other_modes(uint32_t, uint32_t, uint32_t);
1446
1447 if (mask >> 32)
1448 __rdpq_change_other_modes(0, ~(mask >> 32), val >> 32);
1449 if ((uint32_t)mask)
1450 __rdpq_change_other_modes(4, ~(uint32_t)mask, (uint32_t)val);
1451}
1452
1462uint64_t rdpq_get_other_modes_raw(void);
1463
1482inline void rdpq_set_combiner_raw(uint64_t comb) {
1483 extern void __rdpq_write8_syncchange(uint32_t cmd_id, uint32_t arg0, uint32_t arg1, uint32_t autosync);
1484 __rdpq_write8_syncchange(RDPQ_CMD_SET_COMBINE_MODE_RAW,
1485 (comb >> 32) & 0x00FFFFFF,
1486 comb & 0xFFFFFFFF,
1487 AUTOSYNC_PIPE);
1488}
1489
1510void rdpq_fence(void);
1511
1530void rdpq_exec(void *buffer, int size);
1531
1570#define rdpq_write(num_rdp_commands, ovl_id, cmd_id, ...) ({ \
1571 int __num_rdp_commands = (num_rdp_commands); \
1572 if (!__builtin_constant_p(__num_rdp_commands) || __num_rdp_commands != 0) { \
1573 if (__builtin_expect(rspq_block != NULL, 0)) { \
1574 __rdpq_block_reserve(__num_rdp_commands); \
1575 } \
1576 } \
1577 rspq_write(ovl_id, cmd_id, ##__VA_ARGS__); \
1578})
1579
1581// Declarations used by rdpq_write, not part of the public API.
1582typedef struct rspq_block_s rspq_block_t;
1583extern rspq_block_t *rspq_block;
1584extern void __rdpq_block_reserve(int); \
1586
1587
1588#ifdef __cplusplus
1589}
1590#endif
1591
1592#endif
Debugging Support.
#define assertf(expr, msg,...)
assertf() is like assert() with an attached printf().
Definition debug.h:196
2D Graphics
uint8_t a
Alpha component.
Definition graphics.h:62
uint8_t g
Green component.
Definition graphics.h:58
uint8_t b
Blue component.
Definition graphics.h:60
uint8_t r
Red component.
Definition graphics.h:56
uint32_t color_to_packed32(color_t c)
Convert a color_t to the 32-bit packed format used by a FMT_RGBA32 surface (RGBA 8888)
Definition graphics.h:104
Generic color structure.
Definition graphics.h:54
#define PhysicalAddr(_addr)
Return the physical memory address for a given virtual address (pointer)
Definition n64sys.h:84
N64 System Interface.
void __rdpq_set_scissor(uint32_t w0, uint32_t w1)
Out-of-line implementation of rdpq_set_scissor.
Definition rdpq.c:973
void __rdpq_set_fill_color(uint32_t w1)
Out-of-line implementation of rdpq_set_fill_color.
Definition rdpq.c:984
void __rdpq_change_other_modes(uint32_t w0, uint32_t w1, uint32_t w2)
Out-of-line implementation of rdpq_change_other_modes_raw.
Definition rdpq.c:1072
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.
Definition rdpq.c:929
void __rdpq_set_other_modes(uint32_t w0, uint32_t w1)
Out-of-line implementation of rdpq_set_other_modes_raw.
Definition rdpq.c:1057
void __rdpq_block_reserve(int num_rdp_commands)
Reserve space in the RDP static buffer for a number of RDP commands.
Definition rdpq.c:815
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.
Definition rdpq.c:992
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.
Definition rdpq.c:953
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
Definition rdpq.c:913
void __rdpq_write8(uint32_t cmd_id, uint32_t arg0, uint32_t arg1)
Write a standard 8-byte RDP command.
Definition rdpq.c:906
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.
Definition rdpq.h:662
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.
Definition rdpq.h:1163
#define RDPQ_TILE_INTERNAL
Tile descriptor internally used by some RDPQ functions. Avoid using if possible.
Definition rdpq.h:288
void rdpq_set_texture_image(const surface_t *surface)
Configure the texture to use (RDP command: SET_TEX_IMAGE)
Definition rdpq.c:1042
void rdpq_set_env_color(color_t color)
Set the RDP ENV combiner register (RDP command: SET_ENV_COLOR)
Definition rdpq.h:1070
void rdpq_close(void)
Shutdown the RDPQ library.
Definition rdpq.c:489
void rdpq_set_prim_lod_frac(uint8_t value)
Set the RDP PRIM LOD FRAC combiner register (RDP command: SET_PRIM_COLOR (partial))
Definition rdpq.h:1005
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)
Definition rdpq.h:741
void rdpq_set_combiner_raw(uint64_t comb)
Low-level function to change the RDP combiner.
Definition rdpq.h:1482
void rdpq_set_yuv_parms(uint16_t k0, uint16_t k1, uint16_t k2, uint16_t k3, uint16_t k4, uint16_t k5)
Low level functions to set the matrix coefficients for texture format conversion.
Definition rdpq.h:387
void rdpq_exec(void *buffer, int size)
Send to the RDP a buffer of RDP commands from RDRAM.
Definition rdpq.c:529
void rdpq_init(void)
Initialize the RDPQ library.
Definition rdpq.c:447
void rdpq_change_other_modes_raw(uint64_t mask, uint64_t val)
Low-level function to partly change the rendering mode register.
Definition rdpq.h:1443
void rdpq_set_fill_color(color_t color)
Enqueue a SET_FILL_COLOR RDP command.
Definition rdpq.h:840
void rdpq_sync_load(void)
Schedule a RDP SYNC_LOAD command.
Definition rdpq.c:1127
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)
Definition rdpq.h:1043
uint8_t palette
Optional palette associated to the texture. For textures in FMT_CI4 format, specify the palette index...
Definition rdpq.h:274
void rdpq_set_fog_color(color_t color)
Set the RDP FOG blender register.
Definition rdpq.h:892
void rdpq_load_block_linear(int32_t offset, void *buffer, uint16_t size)
Load a block of memory to TMEM with a single contiguous memory transfer.
Definition rdpq.h:1255
void rdpq_set_z_image(const surface_t *surface)
Configure the Z-buffer to use (RDP command: SET_Z_IMAGE)
Definition rdpq.c:1029
rdpq_tile_t
Tile descriptors.
Definition rdpq.h:251
@ TILE5
Tile #5 (for code readability)
Definition rdpq.h:257
@ TILE3
Tile #3 (for code readability)
Definition rdpq.h:255
@ TILE4
Tile #4 (for code readability)
Definition rdpq.h:256
@ TILE7
Tile #7 (for code readability)
Definition rdpq.h:259
@ TILE0
Tile #0 (for code readability)
Definition rdpq.h:252
@ TILE1
Tile #1 (for code readability)
Definition rdpq.h:253
@ TILE6
Tile #6 (for code readability)
Definition rdpq.h:258
@ TILE2
Tile #2 (for code readability)
Definition rdpq.h:254
void rdpq_set_color_image(const surface_t *surface)
Configure the framebuffer to render to (RDP command: SET_COLOR_IMAGE)
Definition rdpq.c:1003
void rdpq_set_detail_factor(float value)
Set the detail/sharpen blending factor (RDP command: SET_PRIM_COLOR (partial))
Definition rdpq.h:978
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)
Definition rdpq.h:719
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)
Definition rdpq.h:646
void rdpq_sync_full(void(*callback)(void *), void *arg)
Schedule a RDP SYNC_FULL command and register a callback when it is done.
Definition rdpq.c:1102
void rdpq_sync_tile(void)
Schedule a RDP SYNC_TILE command.
Definition rdpq.c:1121
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.
Definition rdpq.h:1229
void rdpq_set_fill_color_stripes(color_t color1, color_t color2)
Enqueue a SET_FILL_COLOR RDP command to draw a striped pattern.
Definition rdpq.h:863
void rdpq_set_prim_depth_raw(uint16_t prim_z, int16_t prim_dz)
Set a fixed Z value to be used instead of a per-pixel value (RDP command; SET_PRIM_DEPTH)
Definition rdpq.h:466
void rdpq_set_lookup_address(uint8_t index, void *rdram_addr)
Store an address into the rdpq lookup table.
Definition rdpq.h:1323
void rdpq_load_tlut_raw(rdpq_tile_t tile, int color_idx, int num_colors)
Load a palette of colors into TMEM (RDP command: LOAD_TLUT)
Definition rdpq.h:591
void rdpq_sync_pipe(void)
Schedule a RDP SYNC_PIPE command.
Definition rdpq.c:1115
uint64_t rdpq_get_other_modes_raw(void)
Read the current render mode register.
Definition rdpq.c:1087
void rdpq_set_prim_color(color_t color)
Set the RDP PRIM combiner register (color only) (RDP command: SET_PRIM_COLOR)
Definition rdpq.h:954
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)
Definition rdpq.h:550
#define RDPQ_AUTOTMEM
Special TMEM address to pass to rdpq_set_tile to use automatic TMEM allocation.
Definition rdpq.h:730
void rdpq_set_blend_color(color_t color)
Set the RDP BLEND blender register.
Definition rdpq.h:920
void rdpq_set_z_image_raw(uint8_t index, uint32_t offset)
Low-level version of rdpq_set_z_image, with address lookup capability.
Definition rdpq.h:1197
void rdpq_fence(void)
Add a fence to synchronize RSP with RDP commands.
Definition rdpq.c:519
uint32_t rdpq_config_disable(uint32_t cfg_disable_bits)
Disable a specific set of configuration flags.
Definition rdpq.c:514
uint32_t rdpq_config_enable(uint32_t cfg_enable_bits)
Enable a specific set of configuration flags.
Definition rdpq.c:509
uint32_t rdpq_config_set(uint32_t cfg)
Set the configuration of the RDPQ module.
Definition rdpq.c:502
void rdpq_set_tile_autotmem(int16_t tmem_bytes)
Configure the auto-TMEM feature of rdpq_set_tile.
Definition rdpq.c:1093
void rdpq_set_other_modes_raw(uint64_t mode)
Low-level function to set the rendering mode register.
Definition rdpq.h:1417
#define RDPQ_AUTOTMEM_REUSE(offset)
Special TMEM address to pass to rdpq_set_tile to configure a tile with the same address of previous t...
Definition rdpq.h:732
Tile parameters for rdpq_set_tile.
Definition rdpq.h:273
RDP command macros.
rspq_block_t * rspq_block
Pointer to the current block being built, or NULL.
Definition rspq.c:338
A rspq block: pre-recorded array of commands.
Definition rspq_internal.h:162
const char * tex_format_name(tex_format_t fmt)
Return the name of the texture format as a string (for debugging purposes)
Definition surface.c:15
Surface buffers used to draw images.
tex_format_t
Pixel format enum.
Definition surface.h:105
@ FMT_RGBA32
Format RGBA 8888 (32-bit)
Definition surface.h:109
@ FMT_CI8
Format CI8: color index 8-bit (paletted, 1 index per byte)
Definition surface.h:112
@ FMT_I8
Format I8: 8-bit intensity (8-bit per pixel)
Definition surface.h:117
@ FMT_RGBA16
Format RGBA 5551 (16-bit)
Definition surface.h:108
#define TEX_FORMAT_BYTES2PIX(fmt, bytes)
Convert the specified number of bytes to pixels.
Definition surface.h:91
A surface buffer for graphics.
Definition surface.h:140