Add PC-native DXT1 support to VideoCommon and VideoOGL. Thanks to XTra.KrazzY and death2droid.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3159 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
05efaeeef1
commit
3ba23768e8
|
@ -323,6 +323,19 @@ void decodeDXTBlock(u32 *dst, const DXTBlock *src, int pitch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void copyDXTBlock(u8* dst, const u8* src)
|
||||||
|
{
|
||||||
|
((u16*)dst)[0] = Common::swap16(((u16*)src)[0]);
|
||||||
|
((u16*)dst)[1] = Common::swap16(((u16*)src)[1]);
|
||||||
|
u32 pixels = ((u32*)src)[1];
|
||||||
|
// A bit of trickiness here: the row are in the same order
|
||||||
|
// between the two formats, but the ordering within the rows
|
||||||
|
// is reversed.
|
||||||
|
pixels = ((pixels >> 4) & 0x0F0F0F0F) | ((pixels << 4) & 0xF0F0F0F0);
|
||||||
|
pixels = ((pixels >> 2) & 0x33333333) | ((pixels << 2) & 0xCCCCCCCC);
|
||||||
|
((u32*)dst)[1] = pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//switch endianness, unswizzle
|
//switch endianness, unswizzle
|
||||||
//TODO: to save memory, don't blindly convert everything to argb8888
|
//TODO: to save memory, don't blindly convert everything to argb8888
|
||||||
|
@ -439,24 +452,20 @@ PC_TexFormat TexDecoder_Decode_real(u8 *dst, const u8 *src, int width, int heigh
|
||||||
return PC_TEX_FMT_BGRA32;
|
return PC_TEX_FMT_BGRA32;
|
||||||
case GX_TF_CMPR: // speed critical
|
case GX_TF_CMPR: // speed critical
|
||||||
{
|
{
|
||||||
// TODO: Shuffle to PC S3TC (DXTC) format instead of converting
|
|
||||||
// 11111111 22222222 55555555 66666666
|
|
||||||
// 33333333 44444444 77777777 88888888
|
|
||||||
// The metroid games use this format almost exclusively.
|
|
||||||
for (int y = 0; y < height; y += 8)
|
for (int y = 0; y < height; y += 8)
|
||||||
for (int x = 0; x < width; x += 8)
|
for (int x = 0; x < width; x += 8)
|
||||||
{
|
{
|
||||||
decodeDXTBlock((u32*)dst+y*width+x, (DXTBlock*)src, width);
|
copyDXTBlock(dst+(y/2)*width+x*2, src);
|
||||||
src += sizeof(DXTBlock);
|
src += 8;
|
||||||
decodeDXTBlock((u32*)dst+y*width+x+4, (DXTBlock*)src, width);
|
copyDXTBlock(dst+(y/2)*width+x*2+8, src);
|
||||||
src += sizeof(DXTBlock);
|
src += 8;
|
||||||
decodeDXTBlock((u32*)dst+(y+4)*width+x, (DXTBlock*)src, width);
|
copyDXTBlock(dst+(y/2+2)*width+x*2, src);
|
||||||
src += sizeof(DXTBlock);
|
src += 8;
|
||||||
decodeDXTBlock((u32*)dst+(y+4)*width+x+4, (DXTBlock*)src, width);
|
copyDXTBlock(dst+(y/2+2)*width+x*2+8, src);
|
||||||
src += sizeof(DXTBlock);
|
src += 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PC_TEX_FMT_BGRA32;
|
return PC_TEX_FMT_DXT1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The "copy" texture formats, too?
|
// The "copy" texture formats, too?
|
||||||
|
|
|
@ -366,6 +366,8 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
if (expandedWidth != width)
|
if (expandedWidth != width)
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth);
|
||||||
|
|
||||||
|
if (dfmt != PC_TEX_FMT_DXT1)
|
||||||
|
{
|
||||||
int gl_format;
|
int gl_format;
|
||||||
int gl_iformat;
|
int gl_iformat;
|
||||||
int gl_type;
|
int gl_type;
|
||||||
|
@ -406,6 +408,20 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
glTexImage2D(target, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp);
|
glTexImage2D(target, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Round dimensions up to the next multiple of 4; this is an OpenGL
|
||||||
|
// requirement.
|
||||||
|
// FIXME: Why does the GameCube have compressed textures that aren't
|
||||||
|
// multiples of 4, and what is the best way to handle them?
|
||||||
|
// An example is in SSB Melee's Adventure Mode on the Paratroopas'
|
||||||
|
// wings.
|
||||||
|
int nativeWidth = (width + 3) & ~3;
|
||||||
|
int nativeHeight = (height + 3) & ~3;
|
||||||
|
glCompressedTexImage2D(target, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
|
||||||
|
nativeWidth, nativeHeight, 0, nativeWidth*nativeHeight/2, temp);
|
||||||
|
}
|
||||||
|
|
||||||
if (expandedWidth != width) // reset
|
if (expandedWidth != width) // reset
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
|
Loading…
Reference in New Issue