new gxFIFO:

- fix for work with new emuloop;
- add early implementation of pipeline;
This commit is contained in:
mtabachenko 2009-07-15 22:46:33 +00:00
parent 6275b5d746
commit aa84f1529e
4 changed files with 126 additions and 46 deletions

View File

@ -137,8 +137,14 @@ void IPC_FIFOcnt(u8 proc, u16 val)
} }
// ========================================================= GFX FIFO // ========================================================= GFX FIFO
GFX_PIPE gxPIPE;
GFX_FIFO gxFIFO; GFX_FIFO gxFIFO;
void GFX_PIPEclear()
{
gxPIPE.tail = 0;
}
void GFX_FIFOclear() void GFX_FIFOclear()
{ {
u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600);
@ -151,9 +157,30 @@ void GFX_FIFOclear()
void GFX_FIFOsend(u8 cmd, u32 param) 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); 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; gxstat &= 0xF000FFFF;
@ -182,38 +209,22 @@ void GFX_FIFOsend(u8 cmd, u32 param)
BOOL GFX_FIFOrecv(u8 *cmd, u32 *param) BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
{ {
u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); 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 &= 0xF000FFFF;
gxstat |= 0x06000000; gxstat |= 0x06000000;
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
if ((gxstat & 0x80000000)) // empty if ((gxstat & 0x80000000)) // IRQ: empty
{ {
setIF(0, (1<<21)); setIF(0, (1<<21));
//NDS_makeARM9Int(21);
} }
return FALSE; return FALSE;
} }
if (gxstat & 0x40000000) // IRQ: less half if (gxstat & 0x40000000) // IRQ: less half
{ {
if (gxstat & 0x02000000) if (gxstat & 0x02000000) setIF(0, (1<<21));
setIF(0, (1<<21));
//NDS_makeARM9Int(21);
}
if ((gxstat & 0x80000000)) // IRQ: empty
{
if (gxstat & 0x04000000)
setIF(0, (1<<21));
//NDS_makeARM9Int(21);
} }
gxstat &= 0xF000FFFF; gxstat &= 0xF000FFFF;
@ -226,28 +237,81 @@ BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
gxFIFO.param[i] = gxFIFO.param[i+1]; gxFIFO.param[i] = gxFIFO.param[i+1];
} }
#ifdef USE_GEOMETRY_FIFO_EMULATION
gxstat |= 0x08000000; // set busy flag
#endif
gxstat |= (gxFIFO.tail << 16); gxstat |= (gxFIFO.tail << 16);
if (gxFIFO.tail < 128) if (gxFIFO.tail < 128)
gxstat |= 0x02000000; gxstat |= 0x02000000;
if (gxFIFO.tail == 0) // empty
gxstat |= 0x04000000;
else
gxstat |= 0x08000000; // set busy flag
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
NDS_RescheduleGXFIFO();
return TRUE; 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) void GFX_FIFOcnt(u32 val)
{ {
u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); 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); //INFO("GFX FIFO: write context 0x%08X (prev 0x%08X) tail %i\n", val, gxstat, gxFIFO.tail);
if (val & (1<<29)) // clear? (homebrew) if (val & (1<<29)) // clear? (homebrew)
{ {
GFX_PIPEclear();
GFX_FIFOclear(); GFX_FIFOclear();
return; return;
} }
@ -258,7 +322,6 @@ void GFX_FIFOcnt(u32 val)
/*if (gxstat & 0xC0000000) /*if (gxstat & 0xC0000000)
{ {
setIF(0, (1<<21)); setIF(0, (1<<21));
//NDS_makeARM9Int(21);
}*/ }*/
} }

View File

@ -26,7 +26,7 @@
#ifndef FIFO_H #ifndef FIFO_H
#define 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" #include "types.h"
@ -47,16 +47,26 @@ extern void IPC_FIFOcnt(u8 proc, u16 val);
//=================================================== GFX FIFO //=================================================== GFX FIFO
typedef struct typedef struct
{ {
u8 cmd[261]; u8 cmd[257];
u32 param[261]; u32 param[257];
u16 tail; // tail u16 tail; // tail
} GFX_FIFO; } GFX_FIFO;
typedef struct
{
u8 cmd[5];
u32 param[5];
u8 tail;
} GFX_PIPE;
extern GFX_PIPE gxPIPE;
extern GFX_FIFO gxFIFO; extern GFX_FIFO gxFIFO;
extern void GFX_PIPEclear();
extern void GFX_FIFOclear(); extern void GFX_FIFOclear();
extern void GFX_FIFOsend(u8 cmd, u32 param); 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); extern void GFX_FIFOcnt(u32 val);
//=================================================== Display memory FIFO //=================================================== Display memory FIFO

View File

@ -894,6 +894,7 @@ void MMU_Init(void) {
IPC_FIFOinit(ARMCPU_ARM9); IPC_FIFOinit(ARMCPU_ARM9);
IPC_FIFOinit(ARMCPU_ARM7); IPC_FIFOinit(ARMCPU_ARM7);
GFX_PIPEclear();
GFX_FIFOclear(); GFX_FIFOclear();
DISP_FIFOinit(); DISP_FIFOinit();
@ -951,6 +952,7 @@ void MMU_clearMem()
IPC_FIFOinit(ARMCPU_ARM9); IPC_FIFOinit(ARMCPU_ARM9);
IPC_FIFOinit(ARMCPU_ARM7); IPC_FIFOinit(ARMCPU_ARM7);
GFX_PIPEclear();
GFX_FIFOclear(); GFX_FIFOclear();
DISP_FIFOinit(); DISP_FIFOinit();

View File

@ -61,10 +61,8 @@ in this function: */
static void gfx3d_doFlush(); static void gfx3d_doFlush();
#ifdef USE_GEOMETRY_FIFO_EMULATION #ifdef USE_GEOMETRY_FIFO_EMULATION
inline void GFX_DELAY(int x) { #define GFX_DELAY(x) MMU.gfx3dCycles = nds_timer + (1*x);
MMU.gfx3dCycles = nds_timer + (2*x); NDS_RescheduleGXFIFO(); } #define GFX_DELAY_M2(x) MMU.gfx3dCycles += (1*x);
inline void GFX_DELAY_M2(int x) {
MMU.gfx3dCycles += (2*x); NDS_RescheduleGXFIFO(); }
#else #else
#define GFX_DELAY(x) #define GFX_DELAY(x)
#define GFX_DELAY_M2(x) #define GFX_DELAY_M2(x)
@ -366,6 +364,7 @@ void gfx3d_reset()
gfx3d.clearDepth = gfx3d_extendDepth_15_to_24(0x7FFF); gfx3d.clearDepth = gfx3d_extendDepth_15_to_24(0x7FFF);
GFX_PIPEclear();
GFX_FIFOclear(); GFX_FIFOclear();
#ifdef USE_GEOMETRY_FIFO_EMULATION #ifdef USE_GEOMETRY_FIFO_EMULATION
@ -1528,8 +1527,9 @@ void gfx3d_execute(u8 cmd, u32 param)
break; break;
default: default:
INFO("Unknown execute FIFO 3D command 0x%02X with param 0x%08X\n", cmd, param); INFO("Unknown execute FIFO 3D command 0x%02X with param 0x%08X\n", cmd, param);
break; return;
} }
NDS_RescheduleGXFIFO();
} }
void gfx3d_execute3D() void gfx3d_execute3D()
@ -1539,7 +1539,7 @@ void gfx3d_execute3D()
if (isSwapBuffers) return; if (isSwapBuffers) return;
if (GFX_FIFOrecv(&cmd, &param)) if (GFX_PIPErecv(&cmd, &param))
{ {
gfx3d_execute(cmd, param); gfx3d_execute(cmd, param);
#if 0 #if 0
@ -1631,6 +1631,7 @@ static void gfx3d_doFlush()
gfx3d.frameCtr++; gfx3d.frameCtr++;
#ifndef USE_GEOMETRY_FIFO_EMULATION #ifndef USE_GEOMETRY_FIFO_EMULATION
GFX_PIPEclear();
GFX_FIFOclear(); GFX_FIFOclear();
// reset // reset
clInd = 0; clInd = 0;
@ -1718,12 +1719,14 @@ void gfx3d_VBlankSignal()
gfx3d_doFlush(); gfx3d_doFlush();
isSwapBuffers = false; isSwapBuffers = false;
GFX_DELAY(392); GFX_DELAY(392);
NDS_RescheduleGXFIFO();
} }
#else #else
//the 3d buffers are swapped when a vblank begins. //the 3d buffers are swapped when a vblank begins.
//so, if we have a redraw pending, now is a safe time to do it //so, if we have a redraw pending, now is a safe time to do it
if(!flushPending) if(!flushPending)
{ {
GFX_PIPEclear();
GFX_FIFOclear(); GFX_FIFOclear();
return; return;
} }
@ -1748,11 +1751,10 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
{ {
memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedScreen)); memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedScreen));
memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedAlpha)); memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedAlpha));
return;
} }
else
{
gpu3D->NDS_3D_Render(); gpu3D->NDS_3D_Render();
}
#else #else
//if we are skipping 3d frames then the 3d rendering will get held up here. //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 //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}, { "GLPT", 4, 1, &PTind},
{ "GLPC", 4, 4, PTcoords}, { "GLPC", 4, 4, PTcoords},
{ "GLF9", 4, 1, &gxFIFO.tail}, { "GLF9", 4, 1, &gxFIFO.tail},
{ "GLF9", 1, 261, &gxFIFO.cmd[0]}, { "GLF9", 1, 257, &gxFIFO.cmd[0]},
{ "GLF9", 4, 261, &gxFIFO.param[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}, { "GCOL", 1, 4, colorRGB},
{ "GLCO", 4, 4, lightColor}, { "GLCO", 4, 4, lightColor},
{ "GLDI", 4, 4, lightDirection}, { "GLDI", 4, 4, lightDirection},