Fragmenting memory with the CT24 Format
This focuses on indexed textures. I’ve mentioned them in my palette shifting post.
If you need a quick refresher, here is a TLDR:
When using indexed texture formats, you upload both a look up table (CLUT) and your indexes. Instead of each texel being 32/24/16 bits of colour, it can instead be an index number into this CLUT (only 8 or 4 bits per texel). This in turn saves massive amounts of memory.
GS Texel Storage Formats
Let’s take a look at the ways the GS can store and load texels.
’#’ Denotes unused bits
PSMCT32
31 0
├─────────────────────────────────┤
│ RGBA32 │
└─────────────────────────────────┘
PSMCT24
31 24 0
├───────┼─────────────────────────┤
│ ##### │ RGB24 │
└───────┴─────────────────────────┘
PSMCT16
31 16 0
├────────────────┼────────────────┤
│ RGBA16 │ RGBA16 │
└────────────────┴────────────────┘
PSMT8
31 24 16 8 0
├────────┼────────┼───────┼───────┤
│ ITEX8 │ ITEX8 │ ITEX8 │ ITEX8 │
└────────┴────────┴───────┴───────┘
PSMT8H
31 24 0
├───────┼─────────────────────────┤
│ I8 │ ####################### │
└───────┴─────────────────────────┘
PSMT4
31 24 16 8 0
├───┬───┼───┬───┼───┬───┼───┬───┼
│I4 │I4 │I4 │I4 │I4 │I4 │I4 │I4 │
└───┴───┴───┴───┴───┴───┴───┴───┘
PSMT4HH
31 24 0
├───┼─────────────────────────────┤
│I4 │ ########################### |
└───┴─────────────────────────────┘
PSMT4HL
31 24 28 0
├───┼───┼─────────────────────────┤
│###│I4 | ####################### |
└───┴───┴─────────────────────────┘
What’s important to note is the unused bits. The indexed formats PSMT8H and PSMT4H(H/L) completely ignore the bottom 24 bits. And if you’re paying close attention you might have noticed that the PSMCT24 format ignores the top 8 bits.
Combining CT24 and Index High Storage Formats
By utilising the CT24 colour format for frame-buffers and textures, we can store both an RGB24 texture and one 8-bit texture or two 4-bit textures at the same location in memory (by using PSMT4HL and PSMT4HH).
Notice how I said frame-buffers? That’s right, if you don’t require the 8 bits of alpha in CT32, but need a colour depth greater than the CT16 format, you can put your indexed textures in the same memory as your frame-buffer and z-buffer. Just use the CT24 and Z24 formats.
Unfortunately, the graph (the one in the ps2sdk) and gskit vram allocators are basic and do not perform any sort of optimizations like this. If someone wants an intermediate project, a smarter vram allocator for the PS2 could be a project for you.
My font library also enables you to upload the itex data into the framebuffer, although I’d call that library far from user friendly :^)
I’ve recently added an atom feed. If you’d like to track my posts, add it to your Atom/Supported RSS readers. https://fobes.dev/feed.xml
Thanks for reading.