Yet Another Gamecube Documentation

17  Graphic Formats


index

17.1  YCbYCr


This is the Format used for image data in the external framebuffer (XFB). It exploits the fact that the resolution of color on a PAL/NTSC screen is lower than the resolution of luminance (brightness), and thus stores only separate luminance info for each pixel and combines the color information of two pixels each, saving 2 bytes versus traditional RGB-per-pixel framebuffers. This means that in XFB you cant modify the color of a single pixel without affecting its neighbour. (you can however, seperatly modify its luminance/brightness). It also means that you can not accurately convert one single pixel into XFB framebuffer format, you will always have to convert two pixels at once.

To convert two pixels to YCbYCr, first average their RGB values

R = (R1+R2)/2 
G = (G1+G2)/2 
B = (B1+B2)/2

now calculate the luminance portion of each pixel

Y1 = (77/256)R1 + (150/256)G1 + (29/256)B1 
Y2 = (77/256)R2 + (150/256)G2 + (29/256)B2

then calculate the combined color portion

Cb = -(44/256)R -  (87/256)G + (131/256)B + 128 
Cr = (131/256)R - (110/256)G -  (21/256)B + 128 

now a 32 bit value to be written to XFB (to a 32 bit aligned address of course) can be made up like this

31 24 23 16 15 8 7 0
1111 1111 bbbb bbbb 2222 2222 rrrr rrrr
bit(s)   description
24-31 1 Y1 - luminance Portion of first Pixel
16-23 b Cb - combined color
8-15 2 Y2 - luminance Portion of first Pixel
0-7 r Cr - combined color


converting a single pixel back to RGB looks like this

R = Y + 1.371(Cr - 128) 
G = Y - 0.698(Cr - 128) - 0.336(Cb - 128) 
B = Y + 1.732(Cb - 128) 
index

17.2  I4 (4bit indexed)


index

17.3  IA4 (4bit indexed with alpha)


index

17.4  I8 (8bit indexed)


index

17.5  IA8 (8bit indexed with alpha)


index

17.6  CI4 (compressed 4bit indexed)


index

17.7  CIA4 (compressed 4bit indexed with alpha)


index

17.8  CI8 (compressed 8bit indexed)


Used for Icons and Banners on Memory Card. This Format uses a palette in RGB5A1 Format, the Pixel data is stored in 8x4 pixel tiles.
index

17.9  CIA8 (compressed 8bit indexed with alpha)


index

17.10  RGB4A3


Used for Icons and Banners on Memory Card. This Format uses no palette and is stored in 4x4 pixel tiles.
index

17.10.1  RGB4A3 Pixel Format


15 8 7 0
.ttt rrrr gggg bbbb
bit(s)   description
15   unused (?)
12-14 t transparency
8-11 r red channel
4-7 g green channel
0-3 b blue channel

index

17.11  RGB5A1


Used for Icons and Banners on Memory Card. This Format uses no palette and is stored in 4x4 pixel tiles.
index

17.11.1  RGB5A1 Pixel Format


15 8 7 0
trrr rrgg gggb bbbb
bit(s)   description
15 t transparency
10-14 r red channel
5-9 g green channel
0-4 b blue channel


index

17.12  RGB565


index

17.12.1  RGB565 Pixel Format


15 8 7 0
rrrr rggg gggb bbbb
bit(s)   description
11-15 r red channel
5-10 g green channel
0-4 b blue channel


index

17.13  RGBA8


index

17.13.1  RGBA8 Pixel Format


31 24 23 16 15 8 7 0
rrrr rrrr gggg gggg bbbb bbbb aaaa aaaa
bit(s)   description
24-31 r red channel
16-23 g green channel
8-15 b blue channel
0-7 a alpha channel


index

17.14  S3TC


WARNING: this section is screwed! any advice/corrections/help/etcblabla welcomed! (thanx to Aaron Kaluszka for pointing this out)

S3TC is a compression method for textures, developed by S3 and licenced by Nintendo for the Gamecube (and also by Microsoft for DirectX 6.0). It basically gives you one more MIP level for free, with relatively small quality loss and a simple implementation in hardware. You basically store 2 colour values and then you have a few bits per pixel to interpolate between them. It works in blocks of 4x4 pixel.

There are 5 variants:

DXT1 allows one bit of alpha
DXT2/3 allows 4 bits of alpha
DXT4/5 stores 2 alpha values and has 3 bits to interpolate between them

The difference between DXT2/3 and 4/5 is, if colour values are pre-multiplied with alpha. The blending equation is normally (c*(1-a))+(t*a)), so with pre-multiplied alpha the texture contains (t*a) in each colour channel and the blending becomes (c*(1-a) + t).

Each image is made up of tiles placed linearly from left to right then top to bottom.

Each tile is made up of 4 blocks

0 1
2 3

Each block is made up of 8 words.  These 8 words represent 16 pixels using S3TC compression.

RRRRRGGG - GGGBBBBB - rrrrrggg - gggbbbbb - 00112233 - 44556677 - 8899UUVV- WWXXYYZZ

R = Color 0 Red
G = Color 0 Green
B = Color 0 Blue
r = Color 3 Red
g = Color 3 Green
b = Color 3 Blue
0 - 9, U - Z = Pixel color (2-bits each)
Colors 1 and 2 are interpolated from colors 0 and 3

The tiles are 32 bytes each. Depending on the image format the width and height of the tiles will differ. A 16bit format (ie RGB5 or RGB4A3) will have a 4x4 pixel tile since 4 * 4 * 2 bytes = 32. An 8bit format (ie Color Indexed) will have a 8x4 pixel tile since 8 * 4 * 1 byte = 32.

So a 32x32 image (like a memory card icon) that is in RGB5 format would be 8 tiles across and 8 tiles down.

index

17.14.1  CMPR


Like a usual texture, a CMPR-texture is divided on tiles, each 32-bytes to fit a texture cache line. Every tile is sub-tiled into four parts, in zigzag order :
0 1
2 3

The format of the sub-tiles is pretty simple, and looks like DXT1. First two base colors in RGB565, followed by 16 sub-tile texels. Every texel is 2-bit wide, to lookup from four colors : 00, 01, 10 and 11. First two are given already, and last two are interpolated from first ones, by the following rule :
index