new gxFIFO:
- fix for work with new emuloop; - add early implementation of pipeline;
This commit is contained in:
parent
6275b5d746
commit
aa84f1529e
|
@ -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);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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},
|
||||
|
|
Loading…
Reference in New Issue