Fix bugs where we wouldn't properly decode punchthrough alpha in DXT

This commit is contained in:
Pavel Krajcevski 2016-09-29 23:48:00 -07:00
parent f43e934eb8
commit 5dd85e5896

View file

@ -23,20 +23,14 @@
#include "FasTC/Pixel.h" #include "FasTC/Pixel.h"
namespace DXTC namespace {
{ void DecompressDXT1Block(const uint8 *block, uint32 *outBuf, bool check_order) {
void DecompressDXT1Block(const uint8 *block, uint32 *outBuf) {
// When we call FasTC::Pixel::FromBits, we expect the bits // When we call FasTC::Pixel::FromBits, we expect the bits
// to be read out of memory in LSB (byte) order first. Hence, // to be read out of memory in LSB (byte) order first. Hence,
// we can't read the blocks directly as uint16 values out of // we can't read the blocks directly as uint16 values out of
// the DXT buffer and we have to swap the bytes before hand. // the DXT buffer and we have to swap the bytes before hand.
uint16 colorA = block[0]; uint16 colorA = block[1] | block[0] << 8;
colorA <<= 8; uint16 colorB = block[3] | block[2] << 8;
colorA |= block[1];
uint16 colorB = block[2];
colorB <<= 8;
colorB |= block[3];
uint32 mod = reinterpret_cast<const uint32 *>(block + 4)[0]; uint32 mod = reinterpret_cast<const uint32 *>(block + 4)[0];
@ -45,12 +39,20 @@ namespace DXTC
a.FromBits(reinterpret_cast<const uint8 *>(&colorA), kFiveSixFive); a.FromBits(reinterpret_cast<const uint8 *>(&colorA), kFiveSixFive);
b.FromBits(reinterpret_cast<const uint8 *>(&colorB), kFiveSixFive); b.FromBits(reinterpret_cast<const uint8 *>(&colorB), kFiveSixFive);
uint8 kFullDepth[4] = {8, 8, 8, 8}; uint8 kFullDepth[4] = { 8, 8, 8, 8 };
a.ChangeBitDepth(kFullDepth); a.ChangeBitDepth(kFullDepth);
b.ChangeBitDepth(kFullDepth); b.ChangeBitDepth(kFullDepth);
d = (a + b*2) / 3; // However, for the purposes of properly decoding DXT, we can read them as ints...
c = (a*2 + b) / 3; const uint16 *block_ptr = reinterpret_cast<const uint16 *>(block);
if (!check_order || block_ptr[0] > block_ptr[1]) {
c = (a * 2 + b) / 3;
d = (a + b * 2) / 3;
}
else {
c = (a + b) / 2;
// d already initialized to zero...
}
FasTC::Pixel *colors[4] = { &a, &b, &c, &d }; FasTC::Pixel *colors[4] = { &a, &b, &c, &d };
@ -60,6 +62,10 @@ namespace DXTC
} }
} }
} // namespace
namespace DXTC
{
void DecompressDXT1(const FasTC::DecompressionJob &dcj) void DecompressDXT1(const FasTC::DecompressionJob &dcj)
{ {
assert(!(dcj.Height() & 3)); assert(!(dcj.Height() & 3));
@ -73,11 +79,13 @@ namespace DXTC
uint32 *outPixels = reinterpret_cast<uint32 *>(dcj.OutBuf()); uint32 *outPixels = reinterpret_cast<uint32 *>(dcj.OutBuf());
uint32 outBlock[16]; uint32 outBlock[16];
memset(outBlock, 0xFF, sizeof(outBlock));
for(uint32 j = 0; j < blockH; j++) { for(uint32 j = 0; j < blockH; j++) {
for(uint32 i = 0; i < blockW; i++) { for(uint32 i = 0; i < blockW; i++) {
uint32 offset = (j * blockW + i) * blockSz; uint32 offset = (j * blockW + i) * blockSz;
DecompressDXT1Block(dcj.InBuf() + offset, outBlock); DecompressDXT1Block(dcj.InBuf() + offset, outBlock, true);
for(uint32 y = 0; y < 4; y++) for(uint32 y = 0; y < 4; y++)
for(uint32 x = 0; x < 4; x++) { for(uint32 x = 0; x < 4; x++) {