DXTn texture format

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
jsgf
Posts: 254
Joined: Tue Jul 12, 2005 11:02 am
Contact:

DXTn texture format

Post by jsgf »

I've found that the PSP has DXTn texture support in hardware, and worked out the details of how to use it.

Texture formats 8, 9 and 10 are DXT1, DXT3 and DXT5. The hardware's format is a little different from the standard (as you'd find in a .DDS file, for example).

(See http://oss.sgi.com/projects/ogl-sample/ ... n_s3tc.txt or http://en.wikipedia.org/wiki/S3_Texture_Compression for a description of the DXTn texture formats to make sense of the below.)

For DXT1, each 4x4 texel block has 2 16-bit 565 colours, and 16 2-bit per-texel fields (8 bytes/block). The PSP hardware expects the per-texel bits to come first, followed by the two colours. It also expects the colours to be in (PSP-standard) BGR 565, rather than the standard RGB 565.

For DXT3 and DXT5, each 4x4 block has 8 bytes of alpha data followed by 8 bytes of pixel data. The PSP reverses this, so it wants the pixel data followed by alpha data. Also, the pixel data is normally encoded in the same way as the DXT1 blocks, which is almost true for the PSP. The encoding is the same as for DXT1 textures, except the colours are in RGB 565 format (!?).

Sample code:

Code: Select all

static inline unsigned short swizzle_565(unsigned short in)
{
	unsigned short r = (in & 0xf800) >> 11;
	unsigned short g = (in & 0x07e0);
	unsigned short b = &#40;in & 0x001f&#41; << 11;

	return b | g | r;
&#125;

void convert_dxt1&#40;void *to, const void *from, unsigned size&#41;
&#123;
	const unsigned short *src = from;
	unsigned short *dest = to;

	for&#40;; size >= 8; size -= 8&#41; &#123;
		dest&#91;0&#93; = src&#91;2&#93;;
		dest&#91;1&#93; = src&#91;3&#93;;
		dest&#91;2&#93; = swizzle_565&#40;src&#91;0&#93;&#41;;
		dest&#91;3&#93; = swizzle_565&#40;src&#91;1&#93;&#41;;

		dest += 4;
		src += 4;
	&#125;
&#125;

void convert_dxt35&#40;void *to, const void *from, unsigned size&#41;
&#123;
	const unsigned short *src = from;
	unsigned short *dest = to;

	for&#40;; size >= 16; size -= 16&#41; &#123;
		/* copy alpha */
		memcpy&#40;&dest&#91;4&#93;, &src&#91;0&#93;, 8&#41;;

		dest&#91;0&#93; = src&#91;6&#93;;
		dest&#91;1&#93; = src&#91;7&#93;;
		dest&#91;2&#93; = src&#91;4&#93;;
		dest&#91;3&#93; = src&#91;5&#93;;

		dest += 8;
		src += 8;
	&#125;
&#125;
chp
Posts: 313
Joined: Wed Jun 23, 2004 7:16 am

Post by chp »

Ah, nice, was waiting for someone to figure out those pixel formats. :) I'll add this info to the SDK asap.
GE Dominator
gr8dane
Posts: 16
Joined: Thu Aug 18, 2005 11:10 am

Post by gr8dane »

According to our testing the above code needs the following modifications to work correctly:

void PSPconvert_dxt35(unsigned char *data, unsigned int size)
{
unsigned short *src = (unsigned short *) data;

for(int j = 0; size >= 16; size -= 16, j++)
{
unsigned short converted[8];

// copy alpha
converted[4] = src[1];
converted[5] = src[2];
converted[6] = src[3];
converted[7] = src[0];

converted[0] = src[6];
converted[1] = src[7];
converted[2] = src[4];
converted[3] = src[5];

for (int i = 0; i < 8; i++) src = converted;

src += 8;
}
}


void PSPconvert_dxt1(unsigned char *data, unsigned int size)
{
unsigned short *src = (unsigned short *) data;

for(int j = 0; size >= 8; size -= 8, j++)
{
unsigned short converted[4];

converted[0] = src[2];
converted[1] = src[3];
converted[2] = src[0];
converted[3] = src[1];

for (int i = 0; i < 4; i++) src = converted;

src += 4;
}
}

Enjoy !
jsgf
Posts: 254
Joined: Tue Jul 12, 2005 11:02 am
Contact:

Post by jsgf »

So you found that the DXT1 colors didn't need R and B swapped? Odd. The texture I used, from Doom3, definitely needed the color swapped as a DXT1 texture.

And for DXT3/5 textures, you're swapping the alpha shorts around, but in a weird way. It's all shifted off by one short. Are you sure that's right?
holger
Posts: 204
Joined: Thu Aug 18, 2005 10:57 am

Post by holger »

Are you sure the Q3 texture was in RGBA format, not in ABGR? Quite a lot code developed on Windows platforms uses BGR as native pixelformat...
jsgf
Posts: 254
Joined: Tue Jul 12, 2005 11:02 am
Contact:

Post by jsgf »

It was a native DXT3-compressed texture, which means the pixel format of the colour terms are defined to be RGB 565.
gr8dane
Posts: 16
Joined: Thu Aug 18, 2005 11:10 am

Post by gr8dane »

The textures we used were either exported from Photoshop using the NVidia plugin or from a DOS command line using the NVidia nvdxt.exe converter.
jsgf
Posts: 254
Joined: Tue Jul 12, 2005 11:02 am
Contact:

Post by jsgf »

I tested things by making sure I got the same results on the PSP as I did on my Nvidia card; the code I posted is what I ended up with. I'm confused as to why you might be seeing something different.
jsgf
Posts: 254
Joined: Tue Jul 12, 2005 11:02 am
Contact:

Post by jsgf »

I found a bug/oversight in my DXT3->DXT1 converter which was swizzling the colours, which made me think the PSP needs its colours reversed in DXT1 texture format.

It doesn't; DXT1, 3 and 5 all have the colour respresented the same way within the compressed texture.

I'm pretty sure my description of how alpha is arranged for DXT1, 3 and 5 is still correct
Post Reply