| View previous topic :: View next topic |
| Author |
Message |
jsgf
Joined: 12 Jul 2005 Posts: 254
|
Posted: Tue Aug 16, 2005 6:13 am Post subject: DXTn texture format |
|
|
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/registry/EXT/texture_compression_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: |
static inline unsigned short swizzle_565(unsigned short in)
{
unsigned short r = (in & 0xf800) >> 11;
unsigned short g = (in & 0x07e0);
unsigned short b = (in & 0x001f) << 11;
return b | g | r;
}
void convert_dxt1(void *to, const void *from, unsigned size)
{
const unsigned short *src = from;
unsigned short *dest = to;
for(; size >= 8; size -= 8) {
dest[0] = src[2];
dest[1] = src[3];
dest[2] = swizzle_565(src[0]);
dest[3] = swizzle_565(src[1]);
dest += 4;
src += 4;
}
}
void convert_dxt35(void *to, const void *from, unsigned size)
{
const unsigned short *src = from;
unsigned short *dest = to;
for(; size >= 16; size -= 16) {
/* copy alpha */
memcpy(&dest[4], &src[0], 8);
dest[0] = src[6];
dest[1] = src[7];
dest[2] = src[4];
dest[3] = src[5];
dest += 8;
src += 8;
}
} |
|
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Wed Aug 17, 2005 4:18 pm Post subject: |
|
|
Ah, nice, was waiting for someone to figure out those pixel formats. :) I'll add this info to the SDK asap. _________________ GE Dominator |
|
| Back to top |
|
 |
gr8dane
Joined: 18 Aug 2005 Posts: 16
|
Posted: Tue Aug 23, 2005 8:43 pm Post subject: |
|
|
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[i] = converted[i];
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[i] = converted[i];
src += 4;
}
}
Enjoy ! |
|
| Back to top |
|
 |
jsgf
Joined: 12 Jul 2005 Posts: 254
|
Posted: Wed Aug 24, 2005 2:11 am Post subject: |
|
|
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? |
|
| Back to top |
|
 |
holger
Joined: 18 Aug 2005 Posts: 204
|
Posted: Wed Aug 24, 2005 3:58 am Post subject: |
|
|
| 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... |
|
| Back to top |
|
 |
jsgf
Joined: 12 Jul 2005 Posts: 254
|
Posted: Wed Aug 24, 2005 4:38 am Post subject: |
|
|
| It was a native DXT3-compressed texture, which means the pixel format of the colour terms are defined to be RGB 565. |
|
| Back to top |
|
 |
gr8dane
Joined: 18 Aug 2005 Posts: 16
|
Posted: Wed Aug 24, 2005 6:07 am Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
jsgf
Joined: 12 Jul 2005 Posts: 254
|
Posted: Wed Aug 24, 2005 9:03 am Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
jsgf
Joined: 12 Jul 2005 Posts: 254
|
Posted: Thu Aug 25, 2005 7:44 am Post subject: |
|
|
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 |
|
| Back to top |
|
 |
|