diff --git a/f3dex3.s b/f3dex3.s index 536529a..5a5b1d7 100644 --- a/f3dex3.s +++ b/f3dex3.s @@ -516,6 +516,7 @@ jumpTableEntry G_MOVEMEM_end // G_MOVEMEM, G_MTX (load) // RDP/Immediate Command Mini Table // 1 byte per entry, after << 2 points to an addr in first 1/4 of IMEM +miniTableEntry G_FLUSH_handler miniTableEntry G_MEMSET_handler miniTableEntry G_DMA_IO_handler miniTableEntry G_TEXTURE_handler @@ -1726,7 +1727,7 @@ tri_return_from_decal_fix_z: bltz $8, return_and_end_mat // Return if rdpCmdBufPtr < end+1 i.e. ptr <= end slv $v10[12], 0x00($10) // ZI:F // 156 cycles -flush_rdp_buffer: // $8 = rdpCmdBufPtr - rdpCmdBufEndP1 +flush_rdp_buffer: // Prereq: $8 = rdpCmdBufPtr - rdpCmdBufEndP1 mfc0 $11, SP_DMA_BUSY // Check if any DMA is in flight lw cmd_w1_dram, rdpFifoPos // FIFO pointer = end of RDP read, start of RSP write lw $10, OSTask + OSTask_output_buff_size // Load FIFO "size" (actually end addr) diff --git a/gbi.h b/gbi.h index 7b722f1..27d710f 100644 --- a/gbi.h +++ b/gbi.h @@ -55,7 +55,8 @@ of warnings if you use -Wpedantic. */ */ /*#define G_SPECIAL_3 0xD3 no-op in F3DEX2 */ /*#define G_SPECIAL_2 0xD4 no-op in F3DEX2 */ -/*#define G_SPECIAL_1 0xD5 triggered MVP recalculation, not supported in F3DEX3 */ +/*#define G_SPECIAL_1 0xD5 triggered MVP recalculation in F3DEX2 for debug */ +#define G_FLUSH 0xD4 #define G_MEMSET 0xD5 #define G_DMA_IO 0xD6 #define G_TEXTURE 0xD7 @@ -2463,22 +2464,31 @@ _DW({ \ gsDma0p(G_MEMSET, (dram), ((size) & 0xFFFFF0)) /** - * RSP short command (no DMA required) macros + * Flush the internal DMEM buffer of RDP commands to the RDP FIFO in DRAM, + * causing the RDP to immediately begin executing any previous commands. + * Without SPFlush, the RDP may not begin executing any given command until up + * to 46 more RDP commands after that have been processed by the RSP (or the + * final end of the display list for the frame). + * + * The primary use case is if your frame's display list begins with clearing + * the framebuffer and/or Z buffer, and then proceeds to things which take + * significant time on the RSP before emitting many RDP commands, such as + * matrix and lighting for drawing a character model. You should insert SPFlush + * after the first large buffer clear to cause the RDP to begin executing those + * long operations immediately while the RSP is continuing to work. If you are + * clearing both the framebuffer and Z buffer, you would usually only need one + * SPFlush after the first of these two DPFillRect commands. */ -#define gImmp0(pkt, c) \ -_DW({ \ - Gfx *_g = (Gfx *)(pkt); \ - \ - _g->words.w0 = _SHIFTL((c), 24, 8); \ -}) +#define gSPFlush(pkt) g1Word(pkt, G_FLUSH, 0) /** - * @copydetails gImmp0 + * @copydetails gSPFlush + */ +#define gsSPFlush() gs1Word( G_FLUSH, 0) + +/* + * RSP short command (no DMA required) macros */ -#define gsImmp0(c) \ -{ \ - _SHIFTL((c), 24, 8) \ -} #define gImmp1(pkt, c, p0) \ _DW({ \ @@ -2494,58 +2504,6 @@ _DW({ \ (unsigned int)(p0) \ } -#define gImmp2(pkt, c, p0, p1) \ -_DW({ \ - Gfx *_g = (Gfx *)(pkt); \ - \ - _g->words.w0 = _SHIFTL((c), 24, 8); \ - _g->words.w1 = (_SHIFTL((p0), 16, 16) | \ - _SHIFTL((p1), 8, 8)); \ -}) - -#define gsImmp2(c, p0, p1) \ -{ \ - _SHIFTL((c), 24, 8), \ - (_SHIFTL((p0), 16, 16) | \ - _SHIFTL((p1), 8, 8)) \ -} - -#define gImmp3(pkt, c, p0, p1, p2) \ -_DW({ \ - Gfx *_g = (Gfx *)(pkt); \ - \ - _g->words.w0 = _SHIFTL((c), 24, 8); \ - _g->words.w1 = (_SHIFTL((p0), 16, 16) | \ - _SHIFTL((p1), 8, 8) | \ - _SHIFTL((p2), 0, 8)); \ -}) - -#define gsImmp3(c, p0, p1, p2) \ -{ \ - _SHIFTL((c), 24, 8), \ - (_SHIFTL((p0), 16, 16) | \ - _SHIFTL((p1), 8, 8) | \ - _SHIFTL((p2), 0, 8)) \ -} - -#define gImmp21(pkt, c, p0, p1, dat) \ -_DW({ \ - Gfx *_g = (Gfx *)(pkt); \ - \ - _g->words.w0 = (_SHIFTL((c), 24, 8) | \ - _SHIFTL((p0), 8, 16) | \ - _SHIFTL((p1), 0, 8)); \ - _g->words.w1 = (unsigned int) (dat); \ -}) - -#define gsImmp21(c, p0, p1, dat) \ -{ \ - (_SHIFTL((c), 24, 8) | \ - _SHIFTL((p0), 8, 16) | \ - _SHIFTL((p1), 0, 8)), \ - (unsigned int) (dat) \ -} - #define gMoveWd(pkt, index, offset, data) \ gDma1p((pkt), G_MOVEWORD, data, (offset & 0xFFF), index) #define gsMoveWd( index, offset, data) \ @@ -5252,7 +5210,7 @@ _DW({ \ } #define gDPNoParam(pkt, cmd) g1Word(pkt, cmd, 0) -#define gsDPNoParam(cmd) gs1Word(pkt, cmd, 0) +#define gsDPNoParam(cmd) gs1Word( cmd, 0) #define gDPParam(pkt, cmd, param) \ _DW({ \ diff --git a/rsp/gbi.inc b/rsp/gbi.inc index c81d536..60ac4ea 100644 --- a/rsp/gbi.inc +++ b/rsp/gbi.inc @@ -31,6 +31,7 @@ G_SHADING_SMOOTH equ 0x00200000 G_TRI_FILL equ 0xc8 // not a GBI command +G_FLUSH equ 0xd4 G_MEMSET equ 0xd5 G_DMA_IO equ 0xd6 G_TEXTURE equ 0xd7