Following on from last week's work, I've been busy fixing a few more issues relating to the way Daedalus handles textures.
To start with, I refactored the way that n64-format textures are converted to psp-format textures. Previously, I was converting the textures at the point at which they were loaded into texture memory on the n64. A result of this was that in order to support mirroring, I needed to keep a copy of the converted pixels in RAM. By moving the conversion process closer to the point that the textures are actually used on the psp, I've been able to remove this buffer and perform conversion and mirroring in the same step. This has approximately halved the memory needed for each texture, and is slightly faster than the previous approach.
The most significant change I've made is to fix a memory leak in the texture cache. I mentioned last week that I'd discovered that the texture cache was the biggest culprit for soaking up memory. It turned out that despite my fixes and support for 4-bit and 8-bit palettised textures, I was still running out of memory in certain situations. I did a bit more investigating, and discovered a resource leak that had been in the texture cache since it was first written (probably 7 or 8 years ago now!)
It turned out that in certain situations, several textures would hash to the same bucket in the hash table that I was using. This wasn't normally a problem, but occasionally the process which purges old textures from the cache was accidentally leaking textures. This was wasting video memory and causing the leaked textures to be re-converted on next frame.
The fix ended up being a very simple one-line change, and as a result the texture cache is now 100% leak-free. As an added bonus, it seems that the change has resulted in a nice 4-5% speedup - I suspect this is because the leaked textures are now no-longer being unnecessarily reconverted.
The final bit of work I've been doing is setting up a fixed-size pool for allocating textures from (well, there are actually two pools - one for fast VRAM and another of standard RAM for when this runs out). Despite the various improvements and fixes I've made to reduce the amount of memory being consumed by the texture cache, I wanted to put a hard limit on how much memory can ever be used. This change means that if the limit is ever reached, I just display white textures until some texture memory is freed up a little later. Previously Daedalus would just keep allocating RAM until it ran out of memory and crashed, so the new solution is much nicer :)
All in all I'm very happy with the state of R11. The changes I've made mean that I can permanently allocate 8MB for the Expansion Pak, and not worry about running out of memory. A welcome side-effect to all the texture changes I've made is an approximate 5-10% speedup over R11. On top of this Daedalus now remembers your preferences for each rom, so it's a little nicer to use.
I've still got a few small things to polish, but I'm hoping to release R11 by the weekend.