..

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. A diagram of the PSMCT32 format. (8 bits for each of ABGR)

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.

If you want to see an example of this optimization in action, I have a git repository with some code and a binary.

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.