From fe405eb27b9a21ff9f16543fa41a39eb0d72fd90 Mon Sep 17 00:00:00 2001
From: stdgregwar <[EMAIL REDACTED]>
Date: Mon, 28 Dec 2020 14:00:53 +0100
Subject: [PATCH] fixed LRU cache code
---
src/render/psp/SDL_render_psp.c | 71 ++++++++++++++++++++++++++-------
1 file changed, 56 insertions(+), 15 deletions(-)
diff --git a/src/render/psp/SDL_render_psp.c b/src/render/psp/SDL_render_psp.c
index 28e01c0e1d7..c93942837da 100644
--- a/src/render/psp/SDL_render_psp.c
+++ b/src/render/psp/SDL_render_psp.c
@@ -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;
}