From aa84f1529e7eda64355e8ed3ed4a1ca0ed8cfaa6 Mon Sep 17 00:00:00 2001 From: mtabachenko Date: Wed, 15 Jul 2009 22:46:33 +0000 Subject: [PATCH] new gxFIFO: - fix for work with new emuloop; - add early implementation of pipeline; --- desmume/src/FIFO.cpp | 123 +++++++++++++++++++++++++++++++----------- desmume/src/FIFO.h | 18 +++++-- desmume/src/MMU.cpp | 2 + desmume/src/gfx3d.cpp | 29 +++++----- 4 files changed, 126 insertions(+), 46 deletions(-) diff --git a/desmume/src/FIFO.cpp b/desmume/src/FIFO.cpp index 1dbfbe690..1081ef18a 100644 --- a/desmume/src/FIFO.cpp +++ b/desmume/src/FIFO.cpp @@ -137,8 +137,14 @@ void IPC_FIFOcnt(u8 proc, u16 val) } // ========================================================= GFX FIFO +GFX_PIPE gxPIPE; GFX_FIFO gxFIFO; +void GFX_PIPEclear() +{ + gxPIPE.tail = 0; +} + void GFX_FIFOclear() { u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); @@ -151,9 +157,30 @@ void GFX_FIFOclear() void GFX_FIFOsend(u8 cmd, u32 param) { - //INFO("GFX FIFO: Send GFX 3D cmd 0x%02X to FIFO - 0x%08X (%03i/%02X)\n", cmd, param, gxFIFO.tail, gxFIFO.tail); u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); - if (gxstat & 0x01000000) return; // full + + if (gxFIFO.tail == 0) // FIFO empty + { + if (gxPIPE.tail < 4) // pipe not full + { + gxPIPE.cmd[gxPIPE.tail] = cmd; + gxPIPE.param[gxPIPE.tail] = param; + gxPIPE.tail++; +#ifdef USE_GEOMETRY_FIFO_EMULATION + gxstat |= 0x08000000; // set busy flag + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); +#endif + NDS_RescheduleGXFIFO(); + return; + } + } + + //INFO("GFX FIFO: Send GFX 3D cmd 0x%02X to FIFO - 0x%08X (%03i/%02X)\n", cmd, param, gxFIFO.tail, gxFIFO.tail); + if (gxstat & 0x01000000) + { + //INFO("ERROR: gxFIFO is full\n"); + return; // full + } gxstat &= 0xF000FFFF; @@ -175,45 +202,29 @@ void GFX_FIFOsend(u8 cmd, u32 param) #endif T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); - + NDS_RescheduleGXFIFO(); } BOOL GFX_FIFOrecv(u8 *cmd, u32 *param) { u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); -#if 0 - if (gxstat & 0xC0000000) - { - setIF(0, (1<<21)); - //NDS_makeARM9Int(21); - } -#endif - if (gxFIFO.tail == 0) // empty + + if (gxFIFO.tail == 0) // empty { gxstat &= 0xF000FFFF; gxstat |= 0x06000000; T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); - if ((gxstat & 0x80000000)) // empty + if ((gxstat & 0x80000000)) // IRQ: empty { setIF(0, (1<<21)); - //NDS_makeARM9Int(21); } return FALSE; } if (gxstat & 0x40000000) // IRQ: less half { - if (gxstat & 0x02000000) - setIF(0, (1<<21)); - //NDS_makeARM9Int(21); - } - - if ((gxstat & 0x80000000)) // IRQ: empty - { - if (gxstat & 0x04000000) - setIF(0, (1<<21)); - //NDS_makeARM9Int(21); + if (gxstat & 0x02000000) setIF(0, (1<<21)); } gxstat &= 0xF000FFFF; @@ -226,28 +237,81 @@ BOOL GFX_FIFOrecv(u8 *cmd, u32 *param) gxFIFO.param[i] = gxFIFO.param[i+1]; } -#ifdef USE_GEOMETRY_FIFO_EMULATION - gxstat |= 0x08000000; // set busy flag -#endif - gxstat |= (gxFIFO.tail << 16); if (gxFIFO.tail < 128) gxstat |= 0x02000000; + if (gxFIFO.tail == 0) // empty + gxstat |= 0x04000000; + else + gxstat |= 0x08000000; // set busy flag + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); - NDS_RescheduleGXFIFO(); - return TRUE; } +BOOL GFX_PIPErecv(u8 *cmd, u32 *param) +{ + u8 tmp_cmd = 0; + u32 tmp_param = 0; + u32 gxstat = 0; + + if (gxPIPE.tail > 0) + { + *cmd = gxPIPE.cmd[0]; + *param = gxPIPE.param[0]; + gxPIPE.tail--; + for (int i=0; i < gxPIPE.tail; i++) + { + gxPIPE.cmd[i] = gxPIPE.cmd[i+1]; + gxPIPE.param[i] = gxPIPE.param[i+1]; + } + + if (gxPIPE.tail < 2) + { + if (GFX_FIFOrecv(&tmp_cmd, &tmp_param)) + { + gxPIPE.cmd[gxPIPE.tail] = tmp_cmd; + gxPIPE.param[gxPIPE.tail] = tmp_param; + gxPIPE.tail++; + + + if (GFX_FIFOrecv(&tmp_cmd, &tmp_param)) + { + gxPIPE.cmd[gxPIPE.tail] = tmp_cmd; + gxPIPE.param[gxPIPE.tail] = tmp_param; + gxPIPE.tail++; + } + } + } + + if (gxPIPE.tail == 0) + { + gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); + gxstat &= 0xF7FFFFFF; // clear busy flag + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); + } + return (TRUE); + } + gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); + gxstat &= 0xF7FFFFFF; // clear busy flag + if ((gxstat & 0x80000000)) // IRQ: empty + { + if (gxFIFO.tail == 0) setIF(0, (1<<21)); + } + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); + return FALSE; +} + void GFX_FIFOcnt(u32 val) { u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); //INFO("GFX FIFO: write context 0x%08X (prev 0x%08X) tail %i\n", val, gxstat, gxFIFO.tail); if (val & (1<<29)) // clear? (homebrew) { + GFX_PIPEclear(); GFX_FIFOclear(); return; } @@ -258,7 +322,6 @@ void GFX_FIFOcnt(u32 val) /*if (gxstat & 0xC0000000) { setIF(0, (1<<21)); - //NDS_makeARM9Int(21); }*/ } diff --git a/desmume/src/FIFO.h b/desmume/src/FIFO.h index d98db4df9..b7d8aebf4 100644 --- a/desmume/src/FIFO.h +++ b/desmume/src/FIFO.h @@ -26,7 +26,7 @@ #ifndef FIFO_H #define FIFO_H -//#define USE_GEOMETRY_FIFO_EMULATION //enables new experimental gxFIFO +//#define USE_GEOMETRY_FIFO_EMULATION //enable gxFIFO emulation #include "types.h" @@ -47,16 +47,26 @@ extern void IPC_FIFOcnt(u8 proc, u16 val); //=================================================== GFX FIFO typedef struct { - u8 cmd[261]; - u32 param[261]; + u8 cmd[257]; + u32 param[257]; u16 tail; // tail } GFX_FIFO; +typedef struct +{ + u8 cmd[5]; + u32 param[5]; + + u8 tail; +} GFX_PIPE; + +extern GFX_PIPE gxPIPE; extern GFX_FIFO gxFIFO; +extern void GFX_PIPEclear(); extern void GFX_FIFOclear(); extern void GFX_FIFOsend(u8 cmd, u32 param); -extern BOOL GFX_FIFOrecv(u8 *cmd, u32 *param); +extern BOOL GFX_PIPErecv(u8 *cmd, u32 *param); extern void GFX_FIFOcnt(u32 val); //=================================================== Display memory FIFO diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 6537e04bf..2503b6498 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -894,6 +894,7 @@ void MMU_Init(void) { IPC_FIFOinit(ARMCPU_ARM9); IPC_FIFOinit(ARMCPU_ARM7); + GFX_PIPEclear(); GFX_FIFOclear(); DISP_FIFOinit(); @@ -951,6 +952,7 @@ void MMU_clearMem() IPC_FIFOinit(ARMCPU_ARM9); IPC_FIFOinit(ARMCPU_ARM7); + GFX_PIPEclear(); GFX_FIFOclear(); DISP_FIFOinit(); diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 9c0225952..6001397df 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -61,10 +61,8 @@ in this function: */ static void gfx3d_doFlush(); #ifdef USE_GEOMETRY_FIFO_EMULATION -inline void GFX_DELAY(int x) { - MMU.gfx3dCycles = nds_timer + (2*x); NDS_RescheduleGXFIFO(); } -inline void GFX_DELAY_M2(int x) { - MMU.gfx3dCycles += (2*x); NDS_RescheduleGXFIFO(); } +#define GFX_DELAY(x) MMU.gfx3dCycles = nds_timer + (1*x); +#define GFX_DELAY_M2(x) MMU.gfx3dCycles += (1*x); #else #define GFX_DELAY(x) #define GFX_DELAY_M2(x) @@ -366,6 +364,7 @@ void gfx3d_reset() gfx3d.clearDepth = gfx3d_extendDepth_15_to_24(0x7FFF); + GFX_PIPEclear(); GFX_FIFOclear(); #ifdef USE_GEOMETRY_FIFO_EMULATION @@ -1528,8 +1527,9 @@ void gfx3d_execute(u8 cmd, u32 param) break; default: INFO("Unknown execute FIFO 3D command 0x%02X with param 0x%08X\n", cmd, param); - break; + return; } + NDS_RescheduleGXFIFO(); } void gfx3d_execute3D() @@ -1539,7 +1539,7 @@ void gfx3d_execute3D() if (isSwapBuffers) return; - if (GFX_FIFOrecv(&cmd, ¶m)) + if (GFX_PIPErecv(&cmd, ¶m)) { gfx3d_execute(cmd, param); #if 0 @@ -1631,6 +1631,7 @@ static void gfx3d_doFlush() gfx3d.frameCtr++; #ifndef USE_GEOMETRY_FIFO_EMULATION + GFX_PIPEclear(); GFX_FIFOclear(); // reset clInd = 0; @@ -1718,12 +1719,14 @@ void gfx3d_VBlankSignal() gfx3d_doFlush(); isSwapBuffers = false; GFX_DELAY(392); + NDS_RescheduleGXFIFO(); } #else //the 3d buffers are swapped when a vblank begins. //so, if we have a redraw pending, now is a safe time to do it if(!flushPending) { + GFX_PIPEclear(); GFX_FIFOclear(); return; } @@ -1748,11 +1751,10 @@ void gfx3d_VBlankEndSignal(bool skipFrame) { memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedScreen)); memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedAlpha)); + return; } - else - { - gpu3D->NDS_3D_Render(); - } + + gpu3D->NDS_3D_Render(); #else //if we are skipping 3d frames then the 3d rendering will get held up here. //but, as soon as we quit skipping frames, the held-up 3d frame will render @@ -2432,8 +2434,11 @@ SFORMAT SF_GFX3D[]={ { "GLPT", 4, 1, &PTind}, { "GLPC", 4, 4, PTcoords}, { "GLF9", 4, 1, &gxFIFO.tail}, - { "GLF9", 1, 261, &gxFIFO.cmd[0]}, - { "GLF9", 4, 261, &gxFIFO.param[0]}, + { "GLF9", 1, 257, &gxFIFO.cmd[0]}, + { "GLF9", 4, 257, &gxFIFO.param[0]}, + { "GLP9", 4, 1, &gxPIPE.tail}, + { "GLP9", 1, 5, &gxPIPE.cmd[0]}, + { "GLP9", 4, 5, &gxPIPE.param[0]}, { "GCOL", 1, 4, colorRGB}, { "GLCO", 4, 4, lightColor}, { "GLDI", 4, 4, lightDirection},