zero dma src/dst addresses on reset; clean up dma code; fix texture dumping; cleanup in new texcache code
This commit is contained in:
parent
e6bc023301
commit
e502d5b656
|
@ -891,9 +891,6 @@ void MMU_DeInit(void) {
|
||||||
|
|
||||||
u32 rom_mask = 0;
|
u32 rom_mask = 0;
|
||||||
|
|
||||||
//u32 DMASrc[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
|
|
||||||
//u32 DMADst[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
|
|
||||||
|
|
||||||
void MMU_Reset()
|
void MMU_Reset()
|
||||||
{
|
{
|
||||||
memset(MMU.ARM9_DTCM, 0, sizeof(MMU.ARM9_DTCM));
|
memset(MMU.ARM9_DTCM, 0, sizeof(MMU.ARM9_DTCM));
|
||||||
|
@ -930,12 +927,6 @@ void MMU_Reset()
|
||||||
memset(MMU.reg_IE, 0, sizeof(u32) * 2);
|
memset(MMU.reg_IE, 0, sizeof(u32) * 2);
|
||||||
memset(MMU.reg_IF, 0, sizeof(u32) * 2);
|
memset(MMU.reg_IF, 0, sizeof(u32) * 2);
|
||||||
|
|
||||||
memset(MMU.DMAStartTime, 0, sizeof(u32) * 2 * 4);
|
|
||||||
memset(MMU.DMACycle, 0, sizeof(MMU.DMACycle));
|
|
||||||
memset(MMU.DMACrt, 0, sizeof(u32) * 2 * 4);
|
|
||||||
memset(MMU.DMAing, 0, sizeof(BOOL) * 2 * 4);
|
|
||||||
memset(MMU.DMACompleted, 0, sizeof(BOOL) * 2 * 4);
|
|
||||||
|
|
||||||
memset(MMU.dscard, 0, sizeof(nds_dscard) * 2);
|
memset(MMU.dscard, 0, sizeof(nds_dscard) * 2);
|
||||||
|
|
||||||
MMU.divRunning = 0;
|
MMU.divRunning = 0;
|
||||||
|
@ -1428,152 +1419,6 @@ u32 MMU_readFromGC()
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
//template<int PROCNUM>
|
|
||||||
//void FASTCALL MMU_doDMA(u32 num)
|
|
||||||
//{
|
|
||||||
// u32 src = DMASrc[PROCNUM][num];
|
|
||||||
// u32 dst = DMADst[PROCNUM][num];
|
|
||||||
// u32 taille = 0;
|
|
||||||
// bool paused = false;
|
|
||||||
//
|
|
||||||
// //if (dst == 0x022DD4E0)
|
|
||||||
// // printf("proc %i dma %i: src=%08X, dst=%08X, size=%i, repmode=%i\n",
|
|
||||||
// // PROCNUM, num, src, dst, (MMU.DMACrt[PROCNUM][num]&0x1FFFFF), MMU.DMAStartTime[PROCNUM][num]);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// if(src==dst)
|
|
||||||
// {
|
|
||||||
// T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0xB8 + (0xC*num), T1ReadLong(MMU.MMU_MEM[PROCNUM][0x40], 0xB8 + (0xC*num)) & 0x7FFFFFFF);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// if((!(MMU.DMACrt[PROCNUM][num]&(1<<31)))&&(!(MMU.DMACrt[PROCNUM][num]&(1<<25))))
|
|
||||||
// { /* not enabled and not to be repeated */
|
|
||||||
// MMU.DMAStartTime[PROCNUM][num] = 0;
|
|
||||||
// MMU.DMACycle[PROCNUM][num] = 0;
|
|
||||||
// //MMU.DMAing[PROCNUM][num] = FALSE;
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// //word count
|
|
||||||
// taille = (MMU.DMACrt[PROCNUM][num]&0x1FFFFF);
|
|
||||||
// if(taille == 0) taille = 0x200000; //according to gbatek..
|
|
||||||
//
|
|
||||||
// //for main memory display fifo dmas, check for normal conditions and then dma all 128 bytes at once
|
|
||||||
// //(theyll get sent to the fifo, which can handle more than it ought to be able to)
|
|
||||||
// if ((MMU.DMAStartTime[PROCNUM][num]==EDMAMode_MemDisplay) &&
|
|
||||||
// (taille==4) &&
|
|
||||||
// (((MMU.DMACrt[PROCNUM][num]>>26)&1) == 1))
|
|
||||||
// taille = 128;
|
|
||||||
//
|
|
||||||
// if(MMU.DMAStartTime[PROCNUM][num] == EDMAMode_Card)
|
|
||||||
// taille *= 0x80;
|
|
||||||
//
|
|
||||||
// if(MMU.DMAStartTime[PROCNUM][num] == EDMAMode_GXFifo) {
|
|
||||||
// u32 todo = std::min(taille,(u32)112);
|
|
||||||
// //not necessarily the best time to do this...
|
|
||||||
// //we send 112 words at a time to gxfifo.
|
|
||||||
// //we need to deduct whatever we send from the counter in the dma controller
|
|
||||||
// u32 remain = taille - todo;
|
|
||||||
// taille = todo;
|
|
||||||
// MMU.DMACrt[PROCNUM][num] &= ~0x1FFFFF;
|
|
||||||
// MMU.DMACrt[PROCNUM][num] |= remain;
|
|
||||||
// if(remain != 0) paused = true;
|
|
||||||
//
|
|
||||||
// //not a good time to do this either but i have no choice right now..
|
|
||||||
// if(remain == 0) {
|
|
||||||
// //disable the channel
|
|
||||||
// u8* regs = PROCNUM==0?MMU.ARM9_REG:MMU.ARM7_REG;
|
|
||||||
// T1WriteLong(regs, 0xB8 + (0xC*num), T1ReadLong(regs, 0xB8 + (0xC*num)) & 0x7FFFFFFF);
|
|
||||||
// MMU.DMACrt[PROCNUM][num] &= 0x7FFFFFFF; //blehhh i hate this shit being mirrored in memory
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// MMU.DMACycle[PROCNUM][num] = taille + nds_timer; //TODO - surely this is a gross simplification
|
|
||||||
//
|
|
||||||
// MMU.DMAing[PROCNUM][num] = TRUE;
|
|
||||||
// MMU.CheckDMAs |= (1<<(num+(PROCNUM<<2)));
|
|
||||||
//
|
|
||||||
// DMALOG("ARM%c: DMA%d run src=%08X dst=%08X start=%d taille=%d repeat=%s %08X\r\n",
|
|
||||||
// (PROCNUM==0)?'9':'7', num, src, dst, MMU.DMAStartTime[PROCNUM][num], taille,
|
|
||||||
// (MMU.DMACrt[PROCNUM][num]&(1<<25))?"on":"off",MMU.DMACrt[PROCNUM][num]);
|
|
||||||
//
|
|
||||||
// NDS_RescheduleDMA();
|
|
||||||
//
|
|
||||||
// // transfer
|
|
||||||
// {
|
|
||||||
// u32 i=0;
|
|
||||||
// // 32 bit or 16 bit transfer ?
|
|
||||||
// int sz = ((MMU.DMACrt[PROCNUM][num]>>26)&1)? 4 : 2;
|
|
||||||
// int dstinc,srcinc;
|
|
||||||
// int u=(MMU.DMACrt[PROCNUM][num]>>21);
|
|
||||||
// switch(u & 0x3) {
|
|
||||||
// case 0 : dstinc = sz; break;
|
|
||||||
// case 1 : dstinc = -sz; break;
|
|
||||||
// case 2 : dstinc = 0; break;
|
|
||||||
// case 3 : dstinc = sz; break; //reload
|
|
||||||
// default:
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// switch((u >> 2)&0x3) {
|
|
||||||
// case 0 : srcinc = sz; break;
|
|
||||||
// case 1 : srcinc = -sz; break;
|
|
||||||
// case 2 : srcinc = 0; break;
|
|
||||||
// case 3 : // reserved
|
|
||||||
// return;
|
|
||||||
// default:
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// //if these do not use MMU_AT_DMA and the corresponding code in the read/write routines,
|
|
||||||
// //then danny phantom title screen will be filled with a garbage char which is made by
|
|
||||||
// //dmaing from 0x00000000 to 0x06000000
|
|
||||||
// if ((MMU.DMACrt[PROCNUM][num]>>26)&1)
|
|
||||||
// for(; i < taille; ++i)
|
|
||||||
// {
|
|
||||||
// if (MMU.DMAStartTime[PROCNUM][num] == EDMAMode_GXFifo)
|
|
||||||
// {
|
|
||||||
// /*if ( gxFIFO.size > 255 )
|
|
||||||
// {
|
|
||||||
// paused = true;
|
|
||||||
// MMU.DMACrt[PROCNUM][num] &= 0xFFE00000;
|
|
||||||
// MMU.DMACrt[PROCNUM][num] |= ((taille-i) & 0x1FFFFF);
|
|
||||||
// MMU.DMAing[PROCNUM][num] = FALSE;
|
|
||||||
// MMU.DMACycle[PROCNUM][num] = nds_timer+1;
|
|
||||||
// break;
|
|
||||||
// }*/
|
|
||||||
//
|
|
||||||
// printf("DMAING TO GXFIFO FROM: %08X, val:%08X (fifosize:%d)\n",src,_MMU_read32<PROCNUM,MMU_AT_DMA>(src),gxFIFO.size);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// _MMU_write32<PROCNUM,MMU_AT_DMA>(dst, _MMU_read32<PROCNUM,MMU_AT_DMA>(src));
|
|
||||||
// dst += dstinc;
|
|
||||||
// src += srcinc;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// for(; i < taille; ++i)
|
|
||||||
// {
|
|
||||||
// _MMU_write16<PROCNUM,MMU_AT_DMA>(dst, _MMU_read16<PROCNUM,MMU_AT_DMA>(src));
|
|
||||||
// dst += dstinc;
|
|
||||||
// src += srcinc;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// //write back the addresses
|
|
||||||
// DMASrc[PROCNUM][num] = src;
|
|
||||||
// if((u & 0x3)!=3) //but dont write back dst if we were supposed to reload
|
|
||||||
// DMADst[PROCNUM][num] = dst;
|
|
||||||
//
|
|
||||||
// //this is probably not the best place to do it, but the dma code in ndssystem is so bad i didnt want to touch it
|
|
||||||
// //until it all gets rewritten. so this is here as a reminder, at least.
|
|
||||||
// //(there is no proof for this code, but it is reasonable)
|
|
||||||
// T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0xB0+12*num, DMASrc[PROCNUM][num]);
|
|
||||||
// T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0xB4+12*num, DMADst[PROCNUM][num]);
|
|
||||||
//
|
|
||||||
// if (!paused)
|
|
||||||
// MMU.DMACompleted[PROCNUM][num] = true;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
#ifdef MMU_ENABLE_ACL
|
#ifdef MMU_ENABLE_ACL
|
||||||
|
|
||||||
|
@ -1752,51 +1597,6 @@ static INLINE void write_timer(int proc, int timerIndex, u16 val)
|
||||||
NDS_RescheduleTimers();
|
NDS_RescheduleTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
//template<int proc> static INLINE void write_dma_hictrl(const int dmanum, const u16 val)
|
|
||||||
//{
|
|
||||||
// u32 baseAddr = 0xB0 + dmanum*12;
|
|
||||||
//
|
|
||||||
// //write this control value
|
|
||||||
// T1WriteWord(MMU.MMU_MEM[proc][0x40], baseAddr+10, val);
|
|
||||||
//
|
|
||||||
// //read back the src and dst addr
|
|
||||||
// DMASrc[proc][dmanum] = T1ReadLong(MMU.MMU_MEM[proc][0x40], baseAddr);
|
|
||||||
// DMADst[proc][dmanum] = T1ReadLong(MMU.MMU_MEM[proc][0x40], baseAddr+4);
|
|
||||||
//
|
|
||||||
// //analyze the control value
|
|
||||||
// u32 v = T1ReadLong(MMU.MMU_MEM[proc][0x40], baseAddr+8);
|
|
||||||
// if(proc==ARMCPU_ARM9) MMU.DMAStartTime[proc][dmanum] = (v>>27) & 0x7;
|
|
||||||
// else {
|
|
||||||
// static const EDMAMode lookup[] = {EDMAMode_Immediate,EDMAMode_VBlank,EDMAMode_Card,EDMAMode7_Wifi};
|
|
||||||
// MMU.DMAStartTime[proc][dmanum] = lookup[(v>>28) & 0x3];
|
|
||||||
// if(MMU.DMAStartTime[proc][dmanum] == EDMAMode7_Wifi && (dmanum==1 || dmanum==3))
|
|
||||||
// MMU.DMAStartTime[proc][dmanum] = EDMAMode7_GBASlot;
|
|
||||||
// }
|
|
||||||
// MMU.DMACrt[proc][dmanum] = v;
|
|
||||||
// MMU.DMACompleted[proc][dmanum] = false;
|
|
||||||
// MMU.DMAing[proc][dmanum] = false;
|
|
||||||
//
|
|
||||||
// if(MMU.DMAStartTime[proc][dmanum] == EDMAMode_Immediate)
|
|
||||||
// {
|
|
||||||
// MMU_doDMA<proc>(dmanum);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (MMU.DMAStartTime[proc][dmanum] == EDMAMode_GXFifo)
|
|
||||||
// {
|
|
||||||
////#ifdef _3DINFO
|
|
||||||
//// INFO("ARM%c: DMA%d control src=0x%08X dst=0x%08X %s (gxFIFO tail %03i)\n", (proc==0)?'9':'7', dmanum, DMASrc[proc][dmanum], DMADst[proc][dmanum], ((val>>15)&0x01)?"ON":"OFF", gxFIFO.tail);
|
|
||||||
////#endif
|
|
||||||
// //if the gxfifo is ready to receive a dma, we need to trigger it now
|
|
||||||
// if(gxFIFO.size <= 127)
|
|
||||||
// MMU_doDMA<proc>(dmanum);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// DMALOG("ARM%c: DMA%d control src=0x%08X dst=0x%08X %s\n", (proc==0)?'9':'7', dmanum, DMASrc[proc][dmanum], DMADst[proc][dmanum], ((val>>15)&0x01)?"ON":"OFF");
|
|
||||||
//
|
|
||||||
// NDS_RescheduleDMA();
|
|
||||||
//}
|
|
||||||
|
|
||||||
extern CACHE_ALIGN MatrixStack mtxStack[4];
|
extern CACHE_ALIGN MatrixStack mtxStack[4];
|
||||||
u32 TGXSTAT::read32()
|
u32 TGXSTAT::read32()
|
||||||
{
|
{
|
||||||
|
|
|
@ -172,6 +172,9 @@ public:
|
||||||
|
|
||||||
DmaController() :
|
DmaController() :
|
||||||
enable(0), irq(0), bitWidth(EDMABitWidth_16), repeatMode(0), _startmode(0),
|
enable(0), irq(0), bitWidth(EDMABitWidth_16), repeatMode(0), _startmode(0),
|
||||||
|
//if saddr isnt cleared then rings of fate will trigger copy protection
|
||||||
|
//by inspecting dma3 saddr when it boots
|
||||||
|
saddr(0), daddr(0),
|
||||||
sar(EDMASourceUpdate_Increment), dar(EDMADestinationUpdate_Increment),
|
sar(EDMASourceUpdate_Increment), dar(EDMADestinationUpdate_Increment),
|
||||||
wordcount(0), startmode(EDMAMode_Immediate),
|
wordcount(0), startmode(EDMAMode_Immediate),
|
||||||
sad(&saddr),
|
sad(&saddr),
|
||||||
|
@ -325,12 +328,6 @@ struct MMU_struct
|
||||||
u32 reg_IE[2];
|
u32 reg_IE[2];
|
||||||
u32 reg_IF[2];
|
u32 reg_IF[2];
|
||||||
|
|
||||||
u32 DMAStartTime[2][4];
|
|
||||||
u64 DMACycle[2][4];
|
|
||||||
u32 DMACrt[2][4];
|
|
||||||
BOOL DMAing[2][4];
|
|
||||||
BOOL DMACompleted[2][4];
|
|
||||||
|
|
||||||
BOOL divRunning;
|
BOOL divRunning;
|
||||||
s64 divResult;
|
s64 divResult;
|
||||||
s64 divMod;
|
s64 divMod;
|
||||||
|
@ -356,8 +353,6 @@ struct MMU_struct
|
||||||
memory_chip_t fw;
|
memory_chip_t fw;
|
||||||
|
|
||||||
nds_dscard dscard[2];
|
nds_dscard dscard[2];
|
||||||
//u32 CheckTimers;
|
|
||||||
//u32 CheckDMAs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//this contains things which can't be memzeroed because they are smarter classes
|
//this contains things which can't be memzeroed because they are smarter classes
|
||||||
|
|
|
@ -261,7 +261,7 @@ static GLuint hasTexLoc;
|
||||||
static GLuint texBlendLoc;
|
static GLuint texBlendLoc;
|
||||||
static bool hasTexture = false;
|
static bool hasTexture = false;
|
||||||
|
|
||||||
static ADPCMCacheItem* currTexture = NULL;
|
static TexCacheItem* currTexture = NULL;
|
||||||
|
|
||||||
/* Shaders init */
|
/* Shaders init */
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@ static void OGLClose()
|
||||||
ENDGL();
|
ENDGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void texDeleteCallback(ADPCMCacheItem* item)
|
static void texDeleteCallback(TexCacheItem* item)
|
||||||
{
|
{
|
||||||
freeTextureIds.push((GLuint)item->texid);
|
freeTextureIds.push((GLuint)item->texid);
|
||||||
if(currTexture == item)
|
if(currTexture == item)
|
||||||
|
@ -553,7 +553,7 @@ static void setTexture(unsigned int format, unsigned int texpal)
|
||||||
|
|
||||||
|
|
||||||
// texCacheUnit.TexCache_SetTexture<TexFormat_32bpp>(format, texpal);
|
// texCacheUnit.TexCache_SetTexture<TexFormat_32bpp>(format, texpal);
|
||||||
ADPCMCacheItem* newTexture = TexCache_SetTexture(TexFormat_32bpp,format,texpal);
|
TexCacheItem* newTexture = TexCache_SetTexture(TexFormat_32bpp,format,texpal);
|
||||||
if(newTexture != currTexture)
|
if(newTexture != currTexture)
|
||||||
{
|
{
|
||||||
currTexture = newTexture;
|
currTexture = newTexture;
|
||||||
|
|
|
@ -67,7 +67,7 @@ static u8 index_start_table[8];
|
||||||
|
|
||||||
static GFX3D_Clipper clipper;
|
static GFX3D_Clipper clipper;
|
||||||
static GFX3D_Clipper::TClippedPoly *clippedPolys = NULL;
|
static GFX3D_Clipper::TClippedPoly *clippedPolys = NULL;
|
||||||
static ADPCMCacheItem* polyTexKeys[POLYLIST_SIZE];
|
static TexCacheItem* polyTexKeys[POLYLIST_SIZE];
|
||||||
static bool polyVisible[POLYLIST_SIZE];
|
static bool polyVisible[POLYLIST_SIZE];
|
||||||
static bool polyBackfacing[POLYLIST_SIZE];
|
static bool polyBackfacing[POLYLIST_SIZE];
|
||||||
static int clippedPolyCounter;
|
static int clippedPolyCounter;
|
||||||
|
@ -347,7 +347,7 @@ public:
|
||||||
sampler.unit = this;
|
sampler.unit = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADPCMCacheItem* lastTexKey;
|
TexCacheItem* lastTexKey;
|
||||||
|
|
||||||
VERT* verts[MAX_CLIPPED_VERTS];
|
VERT* verts[MAX_CLIPPED_VERTS];
|
||||||
|
|
||||||
|
@ -1337,7 +1337,7 @@ static void SoftRastRender()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ADPCMCacheItem* lastTexKey = NULL;
|
TexCacheItem* lastTexKey = NULL;
|
||||||
u32 lastTextureFormat = 0, lastTexturePalette = 0;
|
u32 lastTextureFormat = 0, lastTexturePalette = 0;
|
||||||
bool needInitTexture = true;
|
bool needInitTexture = true;
|
||||||
for(int i=0;i<clippedPolyCounter;i++)
|
for(int i=0;i<clippedPolyCounter;i++)
|
||||||
|
|
|
@ -178,9 +178,6 @@ SFORMAT SF_NDS[]={
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
//extern u32 DMASrc[2][4];
|
|
||||||
//extern u32 DMADst[2][4];
|
|
||||||
|
|
||||||
SFORMAT SF_MMU[]={
|
SFORMAT SF_MMU[]={
|
||||||
{ "M7BI", 1, sizeof(MMU.ARM7_BIOS), MMU.ARM7_BIOS},
|
{ "M7BI", 1, sizeof(MMU.ARM7_BIOS), MMU.ARM7_BIOS},
|
||||||
{ "M7ER", 1, sizeof(MMU.ARM7_ERAM), MMU.ARM7_ERAM},
|
{ "M7ER", 1, sizeof(MMU.ARM7_ERAM), MMU.ARM7_ERAM},
|
||||||
|
@ -207,14 +204,6 @@ SFORMAT SF_MMU[]={
|
||||||
{ "MASX", 1, 2, &MMU.AUX_SPI_CNT},
|
{ "MASX", 1, 2, &MMU.AUX_SPI_CNT},
|
||||||
{ "MASC", 1, 2, &MMU.AUX_SPI_CMD},
|
{ "MASC", 1, 2, &MMU.AUX_SPI_CMD},
|
||||||
|
|
||||||
{ "MDST", 4, 8, MMU.DMAStartTime},
|
|
||||||
{ "MDCY", 8, 8, MMU.DMACycle},
|
|
||||||
{ "MDCR", 4, 8, MMU.DMACrt},
|
|
||||||
{ "MDMA", 4, 8, MMU.DMAing},
|
|
||||||
{ "MDMC", 4, 8, MMU.DMACompleted},
|
|
||||||
//{ "MDSR", 4, 8, DMASrc},
|
|
||||||
//{ "MDDS", 4, 8, DMADst},
|
|
||||||
|
|
||||||
{ "MDV1", 4, 1, &MMU.divRunning},
|
{ "MDV1", 4, 1, &MMU.divRunning},
|
||||||
{ "MDV2", 8, 1, &MMU.divResult},
|
{ "MDV2", 8, 1, &MMU.divResult},
|
||||||
{ "MDV3", 8, 1, &MMU.divMod},
|
{ "MDV3", 8, 1, &MMU.divMod},
|
||||||
|
|
|
@ -167,12 +167,14 @@ static MemSpan MemSpan_TexPalette(u32 ofs, u32 len)
|
||||||
|
|
||||||
#if defined (DEBUG_DUMP_TEXTURE) && defined (WIN32)
|
#if defined (DEBUG_DUMP_TEXTURE) && defined (WIN32)
|
||||||
#define DO_DEBUG_DUMP_TEXTURE
|
#define DO_DEBUG_DUMP_TEXTURE
|
||||||
static void DebugDumpTexture(int which)
|
static void DebugDumpTexture(TexCacheItem* item)
|
||||||
{
|
{
|
||||||
|
static int ctr=0;
|
||||||
char fname[100];
|
char fname[100];
|
||||||
sprintf(fname,"c:\\dump\\%d.bmp", which);
|
sprintf(fname,"c:\\dump\\%d.bmp", ctr);
|
||||||
|
ctr++;
|
||||||
|
|
||||||
NDS_WriteBMP_32bppBuffer(texcache[which].sizeX,texcache[which].sizeY,TexCache_texMAP,fname);
|
NDS_WriteBMP_32bppBuffer(item->sizeX,item->sizeY,item->decoded,fname);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -182,30 +184,30 @@ static void DebugDumpTexture(int which)
|
||||||
//I am really unhappy with the ref counting. this needs to be automatic.
|
//I am really unhappy with the ref counting. this needs to be automatic.
|
||||||
//We could do something better than a linear search through cache items, but it may not be worth it.
|
//We could do something better than a linear search through cache items, but it may not be worth it.
|
||||||
//Also we may need to rescan more often (every time a sample loops)
|
//Also we may need to rescan more often (every time a sample loops)
|
||||||
class ADPCMCache
|
class TexCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ADPCMCache()
|
TexCache()
|
||||||
: list_front(NULL)
|
: list_front(NULL)
|
||||||
, list_back(NULL)
|
, list_back(NULL)
|
||||||
, cache_size(0)
|
, cache_size(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ADPCMCacheItem *list_front, *list_back;
|
TexCacheItem *list_front, *list_back;
|
||||||
|
|
||||||
//this ought to be enough for anyone
|
//this ought to be enough for anyone
|
||||||
static const u32 kMaxCacheSize = 64*1024*1024;
|
static const u32 kMaxCacheSize = 64*1024*1024;
|
||||||
//this is not really precise, it is off by a constant factor
|
//this is not really precise, it is off by a constant factor
|
||||||
u32 cache_size;
|
u32 cache_size;
|
||||||
|
|
||||||
void list_remove(ADPCMCacheItem* item) {
|
void list_remove(TexCacheItem* item) {
|
||||||
if(item->next) item->next->prev = item->prev;
|
if(item->next) item->next->prev = item->prev;
|
||||||
if(item->prev) item->prev->next = item->next;
|
if(item->prev) item->prev->next = item->next;
|
||||||
if(item == list_front) list_front = item->next;
|
if(item == list_front) list_front = item->next;
|
||||||
if(item == list_back) list_back = item->prev;
|
if(item == list_back) list_back = item->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_push_front(ADPCMCacheItem* item)
|
void list_push_front(TexCacheItem* item)
|
||||||
{
|
{
|
||||||
item->next = list_front;
|
item->next = list_front;
|
||||||
if(list_front) list_front->prev = item;
|
if(list_front) list_front->prev = item;
|
||||||
|
@ -215,7 +217,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<TexCache_TexFormat TEXFORMAT>
|
template<TexCache_TexFormat TEXFORMAT>
|
||||||
ADPCMCacheItem* scan(u32 format, u32 texpal)
|
TexCacheItem* scan(u32 format, u32 texpal)
|
||||||
{
|
{
|
||||||
//for each texformat, number of palette entries
|
//for each texformat, number of palette entries
|
||||||
static const int palSizes[] = {0, 32, 4, 16, 256, 0, 8, 0};
|
static const int palSizes[] = {0, 32, 4, 16, 256, 0, 8, 0};
|
||||||
|
@ -282,7 +284,7 @@ public:
|
||||||
mspal.dump(pal);
|
mspal.dump(pal);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(ADPCMCacheItem* curr = list_front;curr;curr=curr->next)
|
for(TexCacheItem* curr = list_front;curr;curr=curr->next)
|
||||||
{
|
{
|
||||||
//conditions where we reject matches:
|
//conditions where we reject matches:
|
||||||
//when the teximage or texpal params dont match
|
//when the teximage or texpal params dont match
|
||||||
|
@ -330,7 +332,7 @@ public:
|
||||||
//evict(); //reduce the size of the cache if necessary
|
//evict(); //reduce the size of the cache if necessary
|
||||||
//TODO - as a peculiarity of the texcache, eviction must happen after the entire 3d frame runs
|
//TODO - as a peculiarity of the texcache, eviction must happen after the entire 3d frame runs
|
||||||
//to support separate cache and read passes
|
//to support separate cache and read passes
|
||||||
ADPCMCacheItem* newitem = new ADPCMCacheItem();
|
TexCacheItem* newitem = new TexCacheItem();
|
||||||
list_push_front(newitem);
|
list_push_front(newitem);
|
||||||
//newitem->lock();
|
//newitem->lock();
|
||||||
newitem->suspectedInvalid = false;
|
newitem->suspectedInvalid = false;
|
||||||
|
@ -621,16 +623,11 @@ public:
|
||||||
}
|
}
|
||||||
} //switch(texture format)
|
} //switch(texture format)
|
||||||
|
|
||||||
/*if(user)
|
|
||||||
user->BindTextureData(tx,TexCache_texMAP);
|
|
||||||
|
|
||||||
#ifdef DO_DEBUG_DUMP_TEXTURE
|
#ifdef DO_DEBUG_DUMP_TEXTURE
|
||||||
DebugDumpTexture(tx);
|
DebugDumpTexture(newitem);
|
||||||
#endif*/
|
#endif
|
||||||
|
|
||||||
return newitem;
|
return newitem;
|
||||||
|
|
||||||
|
|
||||||
} //scan()
|
} //scan()
|
||||||
|
|
||||||
void evict(const u32 target = kMaxCacheSize) {
|
void evict(const u32 target = kMaxCacheSize) {
|
||||||
|
@ -639,7 +636,7 @@ public:
|
||||||
//if we really wanted to hold ourselves to it, we could evict to kMaxCacheSize-nextItemSize
|
//if we really wanted to hold ourselves to it, we could evict to kMaxCacheSize-nextItemSize
|
||||||
while(cache_size > target)
|
while(cache_size > target)
|
||||||
{
|
{
|
||||||
ADPCMCacheItem *oldest = list_back;
|
TexCacheItem *oldest = list_back;
|
||||||
while(oldest && oldest->lockCount>0) oldest = oldest->prev; //find an unlocked one
|
while(oldest && oldest->lockCount>0) oldest = oldest->prev; //find an unlocked one
|
||||||
if(!oldest)
|
if(!oldest)
|
||||||
{
|
{
|
||||||
|
@ -653,7 +650,7 @@ public:
|
||||||
delete oldest;
|
delete oldest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} adpcmCache;
|
} texCache;
|
||||||
|
|
||||||
void TexCache_Reset()
|
void TexCache_Reset()
|
||||||
{
|
{
|
||||||
|
@ -664,7 +661,7 @@ void TexCache_Reset()
|
||||||
|
|
||||||
//texcache_start=0;
|
//texcache_start=0;
|
||||||
//texcache_stop=MAX_TEXTURE<<1;
|
//texcache_stop=MAX_TEXTURE<<1;
|
||||||
adpcmCache.evict(0);
|
texCache.evict(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexCache_Invalidate()
|
void TexCache_Invalidate()
|
||||||
|
@ -683,15 +680,15 @@ void TexCache_Invalidate()
|
||||||
// if(texcache[i].mode == TEXMODE_4X4)
|
// if(texcache[i].mode == TEXMODE_4X4)
|
||||||
// texcache[i].frm = 0;
|
// texcache[i].frm = 0;
|
||||||
//}
|
//}
|
||||||
adpcmCache.evict(0);
|
texCache.evict(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ADPCMCacheItem* TexCache_SetTexture(TexCache_TexFormat TEXFORMAT, u32 format, u32 texpal)
|
TexCacheItem* TexCache_SetTexture(TexCache_TexFormat TEXFORMAT, u32 format, u32 texpal)
|
||||||
{
|
{
|
||||||
switch(TEXFORMAT)
|
switch(TEXFORMAT)
|
||||||
{
|
{
|
||||||
case TexFormat_32bpp: return adpcmCache.scan<TexFormat_32bpp>(format,texpal);
|
case TexFormat_32bpp: return texCache.scan<TexFormat_32bpp>(format,texpal);
|
||||||
case TexFormat_15bpp: return adpcmCache.scan<TexFormat_15bpp>(format,texpal);
|
case TexFormat_15bpp: return texCache.scan<TexFormat_15bpp>(format,texpal);
|
||||||
default: assert(false); return NULL;
|
default: assert(false); return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -699,5 +696,5 @@ ADPCMCacheItem* TexCache_SetTexture(TexCache_TexFormat TEXFORMAT, u32 format, u3
|
||||||
//call this periodically to keep the tex cache clean
|
//call this periodically to keep the tex cache clean
|
||||||
void TexCache_EvictFrame()
|
void TexCache_EvictFrame()
|
||||||
{
|
{
|
||||||
adpcmCache.evict();
|
texCache.evict();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@ enum TexCache_TexFormat
|
||||||
TexFormat_15bpp //used by rasterizer
|
TexFormat_15bpp //used by rasterizer
|
||||||
};
|
};
|
||||||
|
|
||||||
class ADPCMCacheItem
|
class TexCacheItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ADPCMCacheItem()
|
TexCacheItem()
|
||||||
: decoded(NULL)
|
: decoded(NULL)
|
||||||
, decode_len(0)
|
, decode_len(0)
|
||||||
, next(NULL)
|
, next(NULL)
|
||||||
|
@ -23,7 +23,7 @@ public:
|
||||||
, deleteCallback(NULL)
|
, deleteCallback(NULL)
|
||||||
, suspectedInvalid(false)
|
, suspectedInvalid(false)
|
||||||
{}
|
{}
|
||||||
~ADPCMCacheItem() {
|
~TexCacheItem() {
|
||||||
delete[] decoded;
|
delete[] decoded;
|
||||||
if(deleteCallback) deleteCallback(this);
|
if(deleteCallback) deleteCallback(this);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public:
|
||||||
u32 decode_len;
|
u32 decode_len;
|
||||||
u32 mode;
|
u32 mode;
|
||||||
u8* decoded; //decoded texture data
|
u8* decoded; //decoded texture data
|
||||||
ADPCMCacheItem *next, *prev; //double linked list
|
TexCacheItem *next, *prev; //double linked list
|
||||||
int lockCount;
|
int lockCount;
|
||||||
bool suspectedInvalid;
|
bool suspectedInvalid;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ public:
|
||||||
float invSizeX, invSizeY;
|
float invSizeX, invSizeY;
|
||||||
|
|
||||||
u64 texid; //used by ogl renderer for the texid
|
u64 texid; //used by ogl renderer for the texid
|
||||||
void (*deleteCallback)(ADPCMCacheItem*);
|
void (*deleteCallback)(TexCacheItem*);
|
||||||
|
|
||||||
TexCache_TexFormat cacheFormat;
|
TexCache_TexFormat cacheFormat;
|
||||||
|
|
||||||
|
@ -61,6 +61,6 @@ void TexCache_Invalidate();
|
||||||
void TexCache_Reset();
|
void TexCache_Reset();
|
||||||
void TexCache_EvictFrame();
|
void TexCache_EvictFrame();
|
||||||
|
|
||||||
ADPCMCacheItem* TexCache_SetTexture(TexCache_TexFormat TEXFORMAT, u32 format, u32 texpal);
|
TexCacheItem* TexCache_SetTexture(TexCache_TexFormat TEXFORMAT, u32 format, u32 texpal);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue