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 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);
|
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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, ¶m))
|
if (GFX_PIPErecv(&cmd, ¶m))
|
||||||
{
|
{
|
||||||
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},
|
||||||
|
|
Loading…
Reference in New Issue