fixed LRU cache code

This commit is contained in:
stdgregwar 2020-12-28 14:00:53 +01:00 committed by Sam Lantinga
parent c1f152292b
commit fe405eb27b

View file

@ -56,6 +56,12 @@ static unsigned int __attribute__((aligned(16))) DisplayList[262144];
#define COL4444(r,g,b,a) ((r>>4) | ((g>>4)<<4) | ((b>>4)<<8) | ((a>>4)<<12))
#define COL8888(r,g,b,a) ((r) | ((g)<<8) | ((b)<<16) | ((a)<<24))
//#define LOGGING
#ifdef LOGGING
#define LOG(...) printf(__VA_ARGS__)
#else
#define LOG(...)
#endif
/**
* Holds psp specific texture data
*
@ -220,37 +226,31 @@ LRUTargetRelink(PSP_TextureData* psp_texture) {
}
}
static void
/*static void
LRUTargetFixTail(PSP_RenderData* data, PSP_TextureData* psp_texture) {
if(data->least_recent_target == psp_texture) {
data->least_recent_target = psp_texture->prevhotw;
} else if(!data->least_recent_target) {
data->least_recent_target = psp_texture;
}
}
}*/
static void
LRUTargetPushFront(PSP_RenderData* data, PSP_TextureData* psp_texture) {
LOG("Pushing %p (%dKB) front.\n", (void*)psp_texture, psp_texture->size / 1024);
psp_texture->nexthotw = data->most_recent_target;
if(data->most_recent_target) {
data->most_recent_target->prevhotw = psp_texture;
}
LRUTargetFixTail(data, psp_texture);
}
static void
LRUTargetBringFront(PSP_RenderData* data, PSP_TextureData* psp_texture) {
if(data->most_recent_target == psp_texture) {
return; //nothing to do
data->most_recent_target = psp_texture;
if(!data->least_recent_target) {
data->least_recent_target = psp_texture;
}
LRUTargetRelink(psp_texture);
psp_texture->prevhotw = NULL;
psp_texture->nexthotw = NULL;
LRUTargetPushFront(data, psp_texture);
}
static void
LRUTargetRemove(PSP_RenderData* data, PSP_TextureData* psp_texture) {
LOG("Removing %p (%dKB).\n", (void*)psp_texture, psp_texture->size/1024);
LRUTargetRelink(psp_texture);
if(data->most_recent_target == psp_texture) {
data->most_recent_target = psp_texture->nexthotw;
@ -262,6 +262,37 @@ LRUTargetRemove(PSP_RenderData* data, PSP_TextureData* psp_texture) {
psp_texture->nexthotw = NULL;
}
static void
LRUTargetBringFront(PSP_RenderData* data, PSP_TextureData* psp_texture) {
LOG("Bringing %p (%dKB) front.\n", (void*)psp_texture, psp_texture->size/1024);
if(data->most_recent_target == psp_texture) {
return; //nothing to do
}
//LRUTargetRelink(psp_texture);
LRUTargetRemove(data, psp_texture);
LRUTargetPushFront(data, psp_texture);
}
#ifdef LOGGING
static void
LRUWalk(PSP_RenderData* data) {
PSP_TextureData* tex = data->most_recent_target;
LOG("================\nLRU STATE:\n");
size_t size = 0;
while(tex) {
LOG("Tex %p (%dKB)\n", (void*)tex, tex->size/1024);
size+= tex->size;
if(tex->nexthotw && tex->nexthotw->prevhotw != tex) {
LOG("Spurious link!\n");
}
tex = tex->nexthotw;
}
LOG("Total Size : %dKB\n", size/1024);
size_t latest_size = data->least_recent_target ? data->least_recent_target->size : 0;
LOG("Least recent %p (%dKB)\n================\n", data->least_recent_target, latest_size / 1024);
}
#endif
static void
TextureStorageFree(void* storage) {
if(InVram(storage)) {
@ -436,13 +467,20 @@ TexturePromoteToVram(PSP_RenderData* data, PSP_TextureData* psp_texture, SDL_boo
}
static int
TextureSpillLRU(PSP_RenderData* data) {
TextureSpillLRU(PSP_RenderData* data, size_t wanted) {
PSP_TextureData* lru = data->least_recent_target;
if(lru) {
if(TextureSpillToSram(data, lru) < 0) {
return -1;
}
LOG("Spilled %p (%dKB) to ram", (void*)lru, lru->size/1024);
LRUTargetRemove(data, lru);
#ifdef LOGGING
LRUWalk(data);
#endif
} else {
SDL_SetError("Could not spill more VRAM to system memory. VRAM : %dKB,(%dKB), wanted %dKB", vmemavail()/1024, vlargestblock()/1024, wanted/1024);
return -1; //Asked to spill but there nothing to spill
}
return 0;
}
@ -451,7 +489,7 @@ static int
TextureSpillTargetsForSpace(PSP_RenderData* data, size_t size)
{
while(vlargestblock() < size) {
if(TextureSpillLRU(data) < 0) {
if(TextureSpillLRU(data, size) < 0) {
return -1;
}
}
@ -470,6 +508,9 @@ TextureBindAsTarget(PSP_RenderData* data, PSP_TextureData* psp_texture) {
}
}
LRUTargetBringFront(data, psp_texture);
#ifdef LOGGING
LRUWalk(data);
#endif
sceGuDrawBufferList(psp_texture->format, vrelptr(psp_texture->data), psp_texture->textureWidth);
return 0;
}