in Texdiag/texdiag.cpp [1665:3200]
HRESULT DumpBCImage(const Image& image, int pixelx, int pixely)
{
size_t sbpp;
switch (image.format)
{
case DXGI_FORMAT_BC1_UNORM:
case DXGI_FORMAT_BC1_UNORM_SRGB:
case DXGI_FORMAT_BC4_UNORM:
case DXGI_FORMAT_BC4_SNORM:
sbpp = 8;
break;
case DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT_BC2_UNORM_SRGB:
case DXGI_FORMAT_BC3_UNORM:
case DXGI_FORMAT_BC3_UNORM_SRGB:
case DXGI_FORMAT_BC5_UNORM:
case DXGI_FORMAT_BC5_SNORM:
case DXGI_FORMAT_BC6H_UF16:
case DXGI_FORMAT_BC6H_SF16:
case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB:
sbpp = 16;
break;
default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}
const uint8_t *pSrc = image.pixels;
const size_t rowPitch = image.rowPitch;
size_t nblock = 0;
for (size_t h = 0; h < image.height; h += 4, pSrc += rowPitch)
{
if (pixely >= 0)
{
if ((pixely < int(h)) || (pixely >= int(h + 4)))
continue;
}
const uint8_t *sptr = pSrc;
size_t w = 0;
for (size_t count = 0; count < rowPitch; count += sbpp, w += 4, ++nblock, sptr += sbpp)
{
if (pixelx >= 0)
{
if ((pixelx < int(w)) || (pixelx >= int(w + 4)))
continue;
}
wprintf(L" Block %zu (pixel: %zu x %zu)\n", nblock, w, h);
switch (image.format)
{
case DXGI_FORMAT_BC1_UNORM:
case DXGI_FORMAT_BC1_UNORM_SRGB:
{
auto block = reinterpret_cast<const BC1Block*>(sptr);
if (block->rgb[0] <= block->rgb[1])
{
// Transparent block
wprintf(L"\tTransparent - E0: ");
}
else
{
// Opaque block
wprintf(L"\t Opaque - E0: ");
}
Print565(block->rgb[0]);
wprintf(L"\n\t E1: ");
Print565(block->rgb[1]);
wprintf(L"\n\t Index: ");
PrintIndex2bpp(block->bitmap);
wprintf(L"\n");
}
break;
case DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT_BC2_UNORM_SRGB:
{
auto block = reinterpret_cast<const BC2Block*>(sptr);
wprintf(L"\tColor - E0: ");
Print565(block->bc1.rgb[0]);
wprintf(L"\n\t E1: ");
Print565(block->bc1.rgb[1]);
wprintf(L"\n\t Index: ");
PrintIndex2bpp(block->bc1.bitmap);
wprintf(L"\n");
wprintf(L"\tAlpha - ");
size_t j = 0;
uint32_t bitmap = block->bitmap[0];
for (; j < (NUM_PIXELS_PER_BLOCK / 2); ++j, bitmap >>= 4)
{
wprintf(L"%X%ls", bitmap & 0xF, ((j % 4) == 3) ? L" | " : L" ");
}
bitmap = block->bitmap[1];
for (; j < NUM_PIXELS_PER_BLOCK; ++j, bitmap >>= 4)
{
wprintf(L"%X%ls", bitmap & 0xF, ((j < (NUM_PIXELS_PER_BLOCK - 1)) && ((j % 4) == 3)) ? L" | " : L" ");
}
wprintf(L"\n");
}
break;
case DXGI_FORMAT_BC3_UNORM:
case DXGI_FORMAT_BC3_UNORM_SRGB:
{
auto block = reinterpret_cast<const BC3Block*>(sptr);
wprintf(L"\tColor - E0: ");
Print565(block->bc1.rgb[0]);
wprintf(L"\n\t E1: ");
Print565(block->bc1.rgb[1]);
wprintf(L"\n\t Index: ");
PrintIndex2bpp(block->bc1.bitmap);
wprintf(L"\n");
wprintf(L"\tAlpha - E0: %0.3f E1: %0.3f (%u)\n\t Index: ",
(float(block->alpha[0]) / 255.f),
(float(block->alpha[1]) / 255.f), (block->alpha[0] > block->alpha[1]) ? 8u : 6u);
PrintIndex3bpp(block->bitmap);
wprintf(L"\n");
}
break;
case DXGI_FORMAT_BC4_UNORM:
{
auto block = reinterpret_cast<const BC4UBlock*>(sptr);
wprintf(L"\t E0: %0.3f E1: %0.3f (%u)\n\tIndex: ",
(float(block->red_0) / 255.f),
(float(block->red_1) / 255.f), (block->red_0 > block->red_1) ? 8u : 6u);
PrintIndex3bpp(block->indices);
wprintf(L"\n");
}
break;
case DXGI_FORMAT_BC4_SNORM:
{
auto block = reinterpret_cast<const BC4SBlock*>(sptr);
wprintf(L"\t E0: %0.3f E1: %0.3f (%u)\n\tIndex: ",
(float(block->red_0) / 127.f),
(float(block->red_1) / 127.f), (block->red_0 > block->red_1) ? 8u : 6u);
PrintIndex3bpp(block->indices);
wprintf(L"\n");
}
break;
case DXGI_FORMAT_BC5_UNORM:
{
auto block = reinterpret_cast<const BC5UBlock*>(sptr);
wprintf(L"\tU - E0: %0.3f E1: %0.3f (%u)\n\t Index: ",
(float(block->u.red_0) / 255.f),
(float(block->u.red_1) / 255.f), (block->u.red_0 > block->u.red_1) ? 8u : 6u);
PrintIndex3bpp(block->u.indices);
wprintf(L"\n");
wprintf(L"\tV - E0: %0.3f E1: %0.3f (%u)\n\t Index: ",
(float(block->v.red_0) / 255.f),
(float(block->v.red_1) / 255.f), (block->v.red_0 > block->v.red_1) ? 8u : 6u);
PrintIndex3bpp(block->v.indices);
wprintf(L"\n");
}
break;
case DXGI_FORMAT_BC5_SNORM:
{
auto block = reinterpret_cast<const BC5SBlock*>(sptr);
wprintf(L"\tU - E0: %0.3f E1: %0.3f (%u)\n\t Index: ",
(float(block->u.red_0) / 127.f),
(float(block->u.red_1) / 127.f), (block->u.red_0 > block->u.red_1) ? 8u : 6u);
PrintIndex3bpp(block->u.indices);
wprintf(L"\n");
wprintf(L"\tV - E0: %0.3f E1: %0.3f (%u)\n\t Index: ",
(float(block->v.red_0) / 127.f),
(float(block->v.red_1) / 127.f), (block->v.red_0 > block->v.red_1) ? 8u : 6u);
PrintIndex3bpp(block->v.indices);
wprintf(L"\n");
}
break;
case DXGI_FORMAT_BC6H_UF16:
case DXGI_FORMAT_BC6H_SF16:
// http://msdn.microsoft.com/en-us/library/windows/desktop/hh308952.aspx#decoding_the_bc6h_format
switch (*sptr & 0x03)
{
case 0x00:
// Mode 1 (2 bits, 00)
{
struct bc6h_mode1
{
uint64_t mode : 2; // { M, 0}, { M, 1}
uint64_t gy4 : 1; // {GY, 4}
uint64_t by4 : 1; // {BY, 4}
uint64_t bz4 : 1; // {BZ, 4}
uint64_t rw : 10; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
uint64_t gw : 10; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
uint64_t bw : 10; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
uint64_t rx : 5; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}
uint64_t gz4 : 1; // {GZ, 4}
uint64_t gy : 4; // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
uint64_t gx : 5; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}
uint64_t bz0 : 1; // {BZ, 0},
uint64_t gz : 4; // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
uint64_t bx : 5; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}
uint64_t bz1 : 1; // {BZ, 1}
uint64_t by : 3; // {BY, 0}, {BY, 1}, {BY, 2}
uint64_t by3 : 1; // {BY, 3}
uint64_t ry : 5; // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}
uint64_t bz2 : 1; // {BZ, 2}
uint64_t rz : 5; // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}
uint64_t bz3 : 1; // {BZ, 3}
uint64_t d : 5; // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
uint64_t indices : 46;
};
static_assert(sizeof(bc6h_mode1) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode1*>(sptr);
XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
XMINT3 e1_A(int(m->ry),
int(m->gy | (m->gy4 << 4)),
int(m->by | (m->by3 << 3) | (m->by4 << 4)));
XMINT3 e1_B(int(m->rz),
int(m->gz | (m->gz4 << 4)),
int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 10);
e0_A.y = SIGN_EXTEND(e0_A.y, 10);
e0_A.z = SIGN_EXTEND(e0_A.z, 10);
e0_B.x = SIGN_EXTEND(e0_B.x, 5);
e0_B.y = SIGN_EXTEND(e0_B.y, 5);
e0_B.z = SIGN_EXTEND(e0_B.z, 5);
e1_A.x = SIGN_EXTEND(e1_A.x, 5);
e1_A.y = SIGN_EXTEND(e1_A.y, 5);
e1_A.z = SIGN_EXTEND(e1_A.z, 5);
e1_B.x = SIGN_EXTEND(e1_B.x, 5);
e1_B.y = SIGN_EXTEND(e1_B.y, 5);
e1_B.z = SIGN_EXTEND(e1_B.z, 5);
}
wprintf(L"\tMode 1 - [10 5 5 5] shape %llu\n", m->d);
wprintf(L"\t E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
wprintf(L"\t E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->indices, 1, m->d);
wprintf(L"\n");
}
break;
case 0x01:
// Mode 2 (2 bits, 01)
{
struct bc6h_mode2
{
uint64_t mode : 2; // { M, 0}, { M, 1}
uint64_t gy5 : 1; // {GY, 5}
uint64_t gz45 : 2; // {GZ, 4}, {GZ, 5}
uint64_t rw : 7; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}
uint64_t bz : 2; // {BZ, 0}, {BZ, 1}
uint64_t by4 : 1; // {BY, 4},
uint64_t gw : 7; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}
uint64_t by5 : 1; // {BY, 5}
uint64_t bz2 : 1; // {BZ, 2}
uint64_t gy4 : 1; // {GY, 4}
uint64_t bw : 7; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}
uint64_t bz3 : 1; // {BZ, 3}
uint64_t bz5 : 1; // {BZ, 5}
uint64_t bz4 : 1; // {BZ, 4}
uint64_t rx : 6; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}
uint64_t gy : 4; // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
uint64_t gx : 6; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}
uint64_t gz : 4; // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
uint64_t bx : 5; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}
uint64_t by : 4; // {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}
uint64_t ry : 6; // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {RY, 5}
uint64_t rz : 6; // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {RZ, 5},
uint64_t d : 5; // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
uint64_t indices : 46;
};
static_assert(sizeof(bc6h_mode2) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode2*>(sptr);
XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
XMINT3 e1_A(int(m->ry),
int(m->gy | (m->gy4 << 4) | (m->gy5 << 5)),
int(m->by | (m->by4 << 4) | (m->by5 << 5)));
XMINT3 e1_B(int(m->rz),
int(m->gz | (m->gz45 << 4)),
int(m->bz | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4) | (m->bz5 << 5)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 7);
e0_A.y = SIGN_EXTEND(e0_A.y, 7);
e0_A.z = SIGN_EXTEND(e0_A.z, 7);
e0_B.x = SIGN_EXTEND(e0_B.x, 6);
e0_B.y = SIGN_EXTEND(e0_B.y, 6);
e0_B.z = SIGN_EXTEND(e0_B.z, 6);
e1_A.x = SIGN_EXTEND(e1_A.x, 6);
e1_A.y = SIGN_EXTEND(e1_A.y, 6);
e1_A.z = SIGN_EXTEND(e1_A.z, 6);
e1_B.x = SIGN_EXTEND(e1_B.x, 6);
e1_B.y = SIGN_EXTEND(e1_B.y, 6);
e1_B.z = SIGN_EXTEND(e1_B.z, 6);
}
wprintf(L"\tMode 2 - [7 6 6 6] shape %llu\n", m->d);
wprintf(L"\t E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
wprintf(L"\t E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->indices, 1, m->d);
wprintf(L"\n");
}
break;
default:
switch (*sptr & 0x1F)
{
case 0x02:
// Mode 3 (5 bits, 00010)
{
struct bc6h_mode3
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 10; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
uint64_t gw : 10; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
uint64_t bw : 10; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
uint64_t rx : 5; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}
uint64_t rw10 : 1; // {RW,10}
uint64_t gy : 4; // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
uint64_t gx : 4; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}
uint64_t gw10 : 1; // {GW,10}
uint64_t bz0 : 1; // {BZ, 0}
uint64_t gz : 4; // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
uint64_t bx : 4; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}
uint64_t bw10 : 1; // {BW,10}
uint64_t bz1 : 1; // {BZ, 1}
uint64_t by : 3; // {BY, 0}, {BY, 1}, {BY, 2}
uint64_t by3 : 1; // {BY, 3}
uint64_t ry : 5; // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}
uint64_t bz2 : 1; // {BZ, 2}
uint64_t rz : 5; // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}
uint64_t bz3 : 1; // {BZ, 3}
uint64_t d : 5; // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
uint64_t indices : 46;
};
static_assert(sizeof(bc6h_mode3) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode3*>(sptr);
XMINT3 e0_A(int(m->rw | (m->rw10 << 10)),
int(m->gw | (m->gw10 << 10)),
int(m->bw | (m->bw10 << 10)));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
XMINT3 e1_A(int(m->ry), int(m->gy),
int(m->by | (m->by3 << 3)));
XMINT3 e1_B(int(m->rz),
int(m->gz),
int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 11);
e0_A.y = SIGN_EXTEND(e0_A.y, 11);
e0_A.z = SIGN_EXTEND(e0_A.z, 11);
e0_B.x = SIGN_EXTEND(e0_B.x, 5);
e0_B.y = SIGN_EXTEND(e0_B.y, 4);
e0_B.z = SIGN_EXTEND(e0_B.z, 4);
e1_A.x = SIGN_EXTEND(e1_A.x, 5);
e1_A.y = SIGN_EXTEND(e1_A.y, 4);
e1_A.z = SIGN_EXTEND(e1_A.z, 4);
e1_B.x = SIGN_EXTEND(e1_B.x, 5);
e1_B.y = SIGN_EXTEND(e1_B.y, 4);
e1_B.z = SIGN_EXTEND(e1_B.z, 4);
}
wprintf(L"\tMode 3 - [11 5 4 4] shape %llu\n", m->d);
wprintf(L"\t E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
wprintf(L"\t E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->indices, 1, m->d);
wprintf(L"\n");
}
break;
case 0x06:
// Mode 4 (5 bits, 00110)
{
struct bc6h_mode4
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 10; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
uint64_t gw : 10; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
uint64_t bw : 10; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
uint64_t rx : 4; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}
uint64_t rw10 : 1; // {RW,10}
uint64_t gz4 : 1; // {GZ, 4}
uint64_t gy : 4; // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
uint64_t gx : 5; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}
uint64_t gw10 : 1; // {GW,10}
uint64_t gz : 4; // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
uint64_t bx : 4; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}
uint64_t bw10 : 1; // {BW,10}
uint64_t bz1 : 1; // {BZ, 1}
uint64_t by : 3; // {BY, 0}, {BY, 1}, {BY, 2}
uint64_t by3 : 1; // {BY, 3}
uint64_t ry : 4; // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}
uint64_t bz0 : 1; // {BZ, 0}
uint64_t bz2 : 1; // {BZ, 2}
uint64_t rz : 4; // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}
uint64_t gy4 : 1; // {GY, 4}
uint64_t bz3 : 1; // {BZ, 3}
uint64_t d : 5; // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
uint64_t indices : 46;
};
static_assert(sizeof(bc6h_mode4) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode4*>(sptr);
XMINT3 e0_A(int(m->rw | (m->rw10 << 10)),
int(m->gw | (m->gw10 << 10)),
int(m->bw | (m->bw10 << 10)));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
XMINT3 e1_A(int(m->ry),
int(m->gy | (m->gy4 << 4)),
int(m->by | (m->by3 << 3)));
XMINT3 e1_B(int(m->rz),
int(m->gz | (m->gz4 << 4)),
int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 11);
e0_A.y = SIGN_EXTEND(e0_A.y, 11);
e0_A.z = SIGN_EXTEND(e0_A.z, 11);
e0_B.x = SIGN_EXTEND(e0_B.x, 4);
e0_B.y = SIGN_EXTEND(e0_B.y, 5);
e0_B.z = SIGN_EXTEND(e0_B.z, 4);
e1_A.x = SIGN_EXTEND(e1_A.x, 4);
e1_A.y = SIGN_EXTEND(e1_A.y, 5);
e1_A.z = SIGN_EXTEND(e1_A.z, 4);
e1_B.x = SIGN_EXTEND(e1_B.x, 4);
e1_B.y = SIGN_EXTEND(e1_B.y, 5);
e1_B.z = SIGN_EXTEND(e1_B.z, 4);
}
wprintf(L"\tMode 4 - [11 4 5 4] shape %llu\n", m->d);
wprintf(L"\t E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
wprintf(L"\t E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->indices, 1, m->d);
wprintf(L"\n");
}
break;
case 0x0A:
// Mode 5 (5 bits, 01010)
{
struct bc6h_mode5
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 10; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
uint64_t gw : 10; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
uint64_t bw : 10; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
uint64_t rx : 4; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}
uint64_t rw10 : 1; // {RW,10}
uint64_t by4 : 1; // {BY, 4}
uint64_t gy : 4; // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
uint64_t gx : 4; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}
uint64_t gw10 : 1; // {GW,10}
uint64_t bz0 : 1; // {BZ, 0}
uint64_t gz : 4; // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
uint64_t bx : 5; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}
uint64_t bw10 : 1; // {BW,10}
uint64_t by : 3; // {BY, 0}, {BY, 1}, {BY, 2}
uint64_t by3 : 1; // {BY, 3}
uint64_t ry : 4; // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}
uint64_t bz12 : 2; // {BZ, 1}, {BZ, 2}
uint64_t rz : 5; // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {BZ, 4}
uint64_t bz3 : 1; // {BZ, 3}
uint64_t d : 5; // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
uint64_t indices : 46;
};
static_assert(sizeof(bc6h_mode5) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode5*>(sptr);
XMINT3 e0_A(int(m->rw | (m->rw10 << 10)),
int(m->gw | (m->gw10 << 10)),
int(m->bw | (m->bw10 << 10)));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
XMINT3 e1_A(int(m->ry), int(m->gy),
int(m->by | (m->by3 << 3) | (m->by4 << 4)));
XMINT3 e1_B(int(m->rz), int(m->gz),
int(m->bz0 | (m->bz12 << 1) | (m->bz3 << 3)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 11);
e0_A.y = SIGN_EXTEND(e0_A.y, 11);
e0_A.z = SIGN_EXTEND(e0_A.z, 11);
e0_B.x = SIGN_EXTEND(e0_B.x, 4);
e0_B.y = SIGN_EXTEND(e0_B.y, 4);
e0_B.z = SIGN_EXTEND(e0_B.z, 5);
e1_A.x = SIGN_EXTEND(e1_A.x, 4);
e1_A.y = SIGN_EXTEND(e1_A.y, 4);
e1_A.z = SIGN_EXTEND(e1_A.z, 5);
e1_B.x = SIGN_EXTEND(e1_B.x, 4);
e1_B.y = SIGN_EXTEND(e1_B.y, 4);
e1_B.z = SIGN_EXTEND(e1_B.z, 5);
}
wprintf(L"\tMode 5 - [11 4 4 5] shape %llu\n", m->d);
wprintf(L"\t E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
wprintf(L"\t E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->indices, 1, m->d);
wprintf(L"\n");
}
break;
case 0x0E:
// Mode 6 (5 bits, 01110)
{
struct bc6h_mode6
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 9; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}
uint64_t by4 : 1; // {BY, 4}
uint64_t gw : 9; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}
uint64_t gy4 : 1; // {GY, 4}
uint64_t bw : 9; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}
uint64_t bz4 : 1; // {BZ, 4}
uint64_t rx : 5; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}
uint64_t gz4 : 1; // {GZ, 4}
uint64_t gy : 4; // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
uint64_t gx : 5; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}
uint64_t bz0 : 1; // {BZ, 0}
uint64_t gz : 4; // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
uint64_t bx : 5; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}
uint64_t bz1 : 1; // {BZ, 1}
uint64_t by : 3; // {BY, 0}, {BY, 1}, {BY, 2}
uint64_t by3 : 1; // {BY, 3}
uint64_t ry : 5; // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4},
uint64_t bz2 : 1; // {BZ, 2}
uint64_t rz : 5; // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {BZ, 4}
uint64_t bz3 : 1; // {BZ, 3}
uint64_t d : 5; // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
uint64_t indices : 46;
};
static_assert(sizeof(bc6h_mode6) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode6*>(sptr);
XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
XMINT3 e1_A(int(m->ry),
int(m->gy | (m->gy4 << 4)),
int(m->by | (m->by3 << 3) | (m->by4 << 4)));
XMINT3 e1_B(int(m->rz),
int(m->gz | (m->gz4 << 4)),
int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 9);
e0_A.y = SIGN_EXTEND(e0_A.y, 9);
e0_A.z = SIGN_EXTEND(e0_A.z, 9);
e0_B.x = SIGN_EXTEND(e0_B.x, 5);
e0_B.y = SIGN_EXTEND(e0_B.y, 5);
e0_B.z = SIGN_EXTEND(e0_B.z, 5);
e1_A.x = SIGN_EXTEND(e1_A.x, 5);
e1_A.y = SIGN_EXTEND(e1_A.y, 5);
e1_A.z = SIGN_EXTEND(e1_A.z, 5);
e1_B.x = SIGN_EXTEND(e1_B.x, 5);
e1_B.y = SIGN_EXTEND(e1_B.y, 5);
e1_B.z = SIGN_EXTEND(e1_B.z, 5);
}
wprintf(L"\tMode 6 - [9 5 5 5] shape %llu\n", m->d);
wprintf(L"\t E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
wprintf(L"\t E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->indices, 1, m->d);
wprintf(L"\n");
}
break;
case 0x12:
// Mode 7 (5 bits, 10010)
{
struct bc6h_mode7
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 8; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}
uint64_t gz4 : 1; // {GZ, 4}
uint64_t by4 : 1; // {BY, 4}
uint64_t gw : 8; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}
uint64_t bz2 : 1; // {BZ, 2}
uint64_t gy4 : 1; // {GY, 4}
uint64_t bw : 8; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}
uint64_t bz3 : 1; // {BZ, 3}
uint64_t bz4 : 1; // {BZ, 4}
uint64_t rx : 6; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}
uint64_t gy : 4; // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
uint64_t gx : 5; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}
uint64_t bz0 : 1; // {BZ, 0}
uint64_t gz : 4; // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
uint64_t bx : 5; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}
uint64_t bz1 : 1; // {BZ, 1}
uint64_t by : 3; // {BY, 0}, {BY, 1}, {BY, 2}
uint64_t by3 : 1; // {BY, 3}
uint64_t ry : 6; // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {RY, 5}
uint64_t rz : 6; // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {RZ, 5}
uint64_t d : 5; // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
uint64_t indices : 46;
};
static_assert(sizeof(bc6h_mode7) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode7*>(sptr);
XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
XMINT3 e1_A(int(m->ry),
int(m->gy | (m->gy4 << 4)),
int(m->by | (m->by3 << 3) | (m->by4 << 4)));
XMINT3 e1_B(int(m->rz),
int(m->gz | (m->gz4 << 4)),
int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 8);
e0_A.y = SIGN_EXTEND(e0_A.y, 8);
e0_A.z = SIGN_EXTEND(e0_A.z, 8);
e0_B.x = SIGN_EXTEND(e0_B.x, 6);
e0_B.y = SIGN_EXTEND(e0_B.y, 5);
e0_B.z = SIGN_EXTEND(e0_B.z, 5);
e1_A.x = SIGN_EXTEND(e1_A.x, 6);
e1_A.y = SIGN_EXTEND(e1_A.y, 5);
e1_A.z = SIGN_EXTEND(e1_A.z, 5);
e1_B.x = SIGN_EXTEND(e1_B.x, 6);
e1_B.y = SIGN_EXTEND(e1_B.y, 5);
e1_B.z = SIGN_EXTEND(e1_B.z, 5);
}
wprintf(L"\tMode 7 - [8 6 5 5] shape %llu\n", m->d);
wprintf(L"\t E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
wprintf(L"\t E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->indices, 1, m->d);
wprintf(L"\n");
}
break;
case 0x16:
// Mode 8 (5 bits, 10110)
{
struct bc6h_mode8
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 8; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}
uint64_t bz0 : 1; // {BZ, 0}
uint64_t by4 : 1; // {BY, 4}
uint64_t gw : 8; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}
uint64_t gy5 : 1; // {GY, 5}
uint64_t gy4 : 1; // {GY, 4}
uint64_t bw : 8; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}
uint64_t gz5 : 1; // {GZ, 5}
uint64_t bz4 : 1; // {BZ, 4}
uint64_t rx : 5; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}
uint64_t gz4 : 1; // {GZ, 4}
uint64_t gy : 4; // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
uint64_t gx : 6; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}
uint64_t gz : 4; // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
uint64_t bx : 5; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}
uint64_t bz1 : 1; // {BZ, 1}
uint64_t by : 3; // {BY, 0}, {BY, 1}, {BY, 2}
uint64_t by3 : 1; // {BY, 3}
uint64_t ry : 5; // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}
uint64_t bz2 : 1; // {BZ, 2}
uint64_t rz : 5; // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}
uint64_t bz3 : 1; // {BZ, 3}
uint64_t d : 5; // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
uint64_t indices : 46;
};
static_assert(sizeof(bc6h_mode8) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode8*>(sptr);
XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
XMINT3 e1_A(int(m->ry),
int(m->gy | (m->gy4 << 4) | (m->gy5 << 5)),
int(m->by | (m->by3 << 3) | (m->by4 << 4)));
XMINT3 e1_B(int(m->rz),
int(m->gz | (m->gz4 << 4) | (m->gz5 << 5)),
int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 8);
e0_A.y = SIGN_EXTEND(e0_A.y, 8);
e0_A.z = SIGN_EXTEND(e0_A.z, 8);
e0_B.x = SIGN_EXTEND(e0_B.x, 5);
e0_B.y = SIGN_EXTEND(e0_B.y, 6);
e0_B.z = SIGN_EXTEND(e0_B.z, 5);
e1_A.x = SIGN_EXTEND(e1_A.x, 5);
e1_A.y = SIGN_EXTEND(e1_A.y, 6);
e1_A.z = SIGN_EXTEND(e1_A.z, 5);
e1_B.x = SIGN_EXTEND(e1_B.x, 5);
e1_B.y = SIGN_EXTEND(e1_B.y, 6);
e1_B.z = SIGN_EXTEND(e1_B.z, 5);
}
wprintf(L"\tMode 8 - [8 5 6 5] shape %llu\n", m->d);
wprintf(L"\t E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
wprintf(L"\t E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->indices, 1, m->d);
wprintf(L"\n");
}
break;
case 0x1A:
// Mode 9 (5 bits, 11010)
{
struct bc6h_mode9
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 8; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}
uint64_t bz1 : 1; // {BZ, 1}
uint64_t by4 : 1; // {BY, 4}
uint64_t gw : 8; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}
uint64_t by5 : 1; // {BY, 5}
uint64_t gy4 : 1; // {GY, 4}
uint64_t bw : 8; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}
uint64_t bz5 : 1; // {BZ, 5}
uint64_t bz4 : 1; // {BZ, 4}
uint64_t rx : 5; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}
uint64_t gz4 : 1; // {GZ, 4}
uint64_t gy : 4; // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
uint64_t gx : 5; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}
uint64_t bz0 : 1; // {BZ, 0}
uint64_t gz : 4; // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
uint64_t bx : 6; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}
uint64_t by : 3; // {BY, 0}, {BY, 1}, {BY, 2}
uint64_t by3 : 1; // {BY, 3}
uint64_t ry : 5; // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}
uint64_t bz2 : 1; // {BZ, 2}
uint64_t rz : 5; // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}
uint64_t bz3 : 1; // {BZ, 3}
uint64_t d : 5; // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
uint64_t indices : 46;
};
static_assert(sizeof(bc6h_mode9) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode9*>(sptr);
XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
XMINT3 e1_A(int(m->ry),
int(m->gy | (m->gy4 << 4)),
int(m->by | (m->by3 << 3) | (m->by4 << 4) | (m->by5 << 5)));
XMINT3 e1_B(int(m->rz),
int(m->gz | (m->gz4 << 4)),
int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4) | (m->bz5 << 5)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 8);
e0_A.y = SIGN_EXTEND(e0_A.y, 8);
e0_A.z = SIGN_EXTEND(e0_A.z, 8);
e0_B.x = SIGN_EXTEND(e0_B.x, 5);
e0_B.y = SIGN_EXTEND(e0_B.y, 5);
e0_B.z = SIGN_EXTEND(e0_B.z, 6);
e1_A.x = SIGN_EXTEND(e1_A.x, 5);
e1_A.y = SIGN_EXTEND(e1_A.y, 5);
e1_A.z = SIGN_EXTEND(e1_A.z, 6);
e1_B.x = SIGN_EXTEND(e1_B.x, 5);
e1_B.y = SIGN_EXTEND(e1_B.y, 5);
e1_B.z = SIGN_EXTEND(e1_B.z, 6);
}
wprintf(L"\tMode 9 - [8 5 5 6] shape %llu\n", m->d);
wprintf(L"\t E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
wprintf(L"\t E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->indices, 1, m->d);
wprintf(L"\n");
}
break;
case 0x1E:
// Mode 10 (5 bits, 11110)
{
struct bc6h_mode10
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 6; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}
uint64_t gz4 : 1; // {GZ, 4}
uint64_t bz : 2; // {BZ, 0}, {BZ, 1}
uint64_t by4 : 1; // {BY, 4}
uint64_t gw : 6; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}
uint64_t gy5 : 1; // {GY, 5}
uint64_t by5 : 1; // {BY, 5}
uint64_t bz2 : 1; // {BZ, 2}
uint64_t gy4 : 1; // {GY, 4}
uint64_t bw : 6; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {GZ, 5}
uint64_t bz3 : 1; // {BZ, 3}
uint64_t bz5 : 1; // {BZ, 5}
uint64_t bz4 : 1; // {BZ, 4}
uint64_t rx : 6; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}
uint64_t gy : 4; // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
uint64_t gx : 6; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}
uint64_t gz : 4; // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
uint64_t bx : 6; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}
uint64_t by : 3; // {BY, 0}, {BY, 1}, {BY, 2}
uint64_t by3 : 1; // {BY, 3}
uint64_t ry : 6; // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {RY, 5}
uint64_t rz : 6; // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {RZ, 5}
uint64_t d : 5; // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
uint64_t indices : 46;
};
static_assert(sizeof(bc6h_mode10) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode10*>(sptr);
XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
XMINT3 e1_A(int(m->ry),
int(m->gy | (m->gy4 << 4) | (m->gy5 << 5)),
int(m->by | (m->by3 << 3) | (m->by4 << 4) | (m->by5 << 5)));
XMINT3 e1_B(int(m->rz),
int(m->gz | (m->gz4 << 4)),
int(m->bz | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4) | (m->bz5 << 5)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 6);
e0_A.y = SIGN_EXTEND(e0_A.y, 6);
e0_A.z = SIGN_EXTEND(e0_A.z, 6);
e0_B.x = SIGN_EXTEND(e0_B.x, 6);
e0_B.y = SIGN_EXTEND(e0_B.y, 6);
e0_B.z = SIGN_EXTEND(e0_B.z, 6);
e1_A.x = SIGN_EXTEND(e1_A.x, 6);
e1_A.y = SIGN_EXTEND(e1_A.y, 6);
e1_A.z = SIGN_EXTEND(e1_A.z, 6);
e1_B.x = SIGN_EXTEND(e1_B.x, 6);
e1_B.y = SIGN_EXTEND(e1_B.y, 6);
e1_B.z = SIGN_EXTEND(e1_B.z, 6);
}
wprintf(L"\tMode 10 - [6 6 6 6] shape %llu\n", m->d);
wprintf(L"\t E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
wprintf(L"\t E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->indices, 1, m->d);
wprintf(L"\n");
}
break;
case 0x03:
// Mode 11 (5 bits, 00011)
{
struct bc6h_mode11
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 10; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
uint64_t gw : 10; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
uint64_t bw : 10; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
uint64_t rx : 10; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {RX, 6}, {RX, 7}, {RX, 8}, {RX, 9}
uint64_t gx : 10; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GX, 6}, {GX, 7}, {GX, 8}, {GX, 9}
uint64_t bx : 9; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BX, 6}, {BX, 7}, {BX, 8}
uint64_t bx9 : 1; // {BX, 9}
uint64_t indices : 63;
};
static_assert(sizeof(bc6h_mode11) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode11*>(sptr);
XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
XMINT3 e0_B(int(m->rx), int(m->gx),
int(m->bx | (m->bx9 << 9)));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 10);
e0_A.y = SIGN_EXTEND(e0_A.y, 10);
e0_A.z = SIGN_EXTEND(e0_A.z, 10);
e0_B.x = SIGN_EXTEND(e0_B.x, 10);
e0_B.y = SIGN_EXTEND(e0_B.y, 10);
e0_B.z = SIGN_EXTEND(e0_B.z, 10);
}
wprintf(L"\tMode 11 - [10 10]\n");
wprintf(L"\t E(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex4bpp(m->indices, 0, 0);
wprintf(L"\n");
}
break;
case 0x07:
// Mode 12 (5 bits, 00111)
{
struct bc6h_mode12
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 10; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
uint64_t gw : 10; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
uint64_t bw : 10; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
uint64_t rx : 9; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {RX, 6}, {RX, 7}, {RX, 8}
uint64_t rw10 : 1; // {RW,10}
uint64_t gx : 9; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GX, 6}, {GX, 7}, {GX, 8}
uint64_t gw10 : 1; // {GW,10}
uint64_t bx : 9; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BX, 6}, {BX, 7}, {BX, 8}
uint64_t bw10 : 1; // {BW,10}
uint64_t indices : 63;
};
static_assert(sizeof(bc6h_mode12) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode12*>(sptr);
XMINT3 e0_A(int(m->rw | (m->rw10 << 10)),
int(m->gw | (m->gw10 << 10)),
int(m->bw | (m->bw10 << 10)));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 11);
e0_A.y = SIGN_EXTEND(e0_A.y, 11);
e0_A.z = SIGN_EXTEND(e0_A.z, 11);
e0_B.x = SIGN_EXTEND(e0_B.x, 9);
e0_B.y = SIGN_EXTEND(e0_B.y, 9);
e0_B.z = SIGN_EXTEND(e0_B.z, 9);
}
wprintf(L"\tMode 12 - [11 9]\n");
wprintf(L"\t E(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex4bpp(m->indices, 0, 0);
wprintf(L"\n");
}
break;
case 0x0B:
// Mode 13 (5 bits, 01011)
{
struct bc6h_mode13
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 10; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
uint64_t gw : 10; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
uint64_t bw : 10; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
uint64_t rx : 8; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {RX, 6}, {RX, 7}
uint64_t rw11 : 1; // {RW,11}
uint64_t rw10 : 1; // {RW,10}
uint64_t gx : 8; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GX, 6}, {GX, 7}
uint64_t gw11 : 1; // {GW,11}
uint64_t gw10 : 1; // {GW,10}
uint64_t bx : 8; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BX, 6}, {BX, 7}
uint64_t bw11 : 1; // {BW,11}
uint64_t bw10 : 1; // {BW,10}
uint64_t indices : 63;
};
static_assert(sizeof(bc6h_mode13) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode13*>(sptr);
XMINT3 e0_A(int(m->rw | (m->rw10 << 10) | (m->rw11 << 11)),
int(m->gw | (m->gw10 << 10) | (m->gw11 << 11)),
int(m->bw | (m->bw10 << 10) | (m->bw11 << 11)));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 12);
e0_A.y = SIGN_EXTEND(e0_A.y, 12);
e0_A.z = SIGN_EXTEND(e0_A.z, 12);
e0_B.x = SIGN_EXTEND(e0_B.x, 8);
e0_B.y = SIGN_EXTEND(e0_B.y, 8);
e0_B.z = SIGN_EXTEND(e0_B.z, 8);
}
wprintf(L"\tMode 13 - [12 8]\n");
wprintf(L"\t E(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex4bpp(m->indices, 0, 0);
wprintf(L"\n");
}
break;
case 0x0F:
// Mode 14 (5 bits, 01111)
{
struct bc6h_mode14
{
uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
uint64_t rw : 10; // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
uint64_t gw : 10; // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
uint64_t bw : 10; // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
uint64_t rx : 4; // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}
uint64_t rw15 : 1; // {RW,15}
uint64_t rw14 : 1; // {RW,14}
uint64_t rw13 : 1; // {RW,13}
uint64_t rw12 : 1; // {RW,12}
uint64_t rw11 : 1; // {RW,11}
uint64_t rw10 : 1; // {RW,10}
uint64_t gx : 4; // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}
uint64_t gw15 : 1; // {GW,15}
uint64_t gw14 : 1; // {GW,14}
uint64_t gw13 : 1; // {GW,13}
uint64_t gw12 : 1; // {GW,12}
uint64_t gw11 : 1; // {GW,11}
uint64_t gw10 : 1; // {GW,10}
uint64_t bx : 4; // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}
uint64_t bw15 : 1; // {BW,15}
uint64_t bw14 : 1; // {BW,14}
uint64_t bw13 : 1; // {BW,13}
uint64_t bw12 : 1; // {BW,12}
uint64_t bw11 : 1; // {BW,11}
uint64_t bw10 : 1; // {BW,10}
uint64_t indices : 63;
};
static_assert(sizeof(bc6h_mode14) == 16, "Block size must be 16 bytes");
bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;
auto m = reinterpret_cast<const bc6h_mode14*>(sptr);
XMINT3 e0_A(int(m->rw | (m->rw10 << 10) | (m->rw11 << 11) | (m->rw12 << 12) | (m->rw13 << 13) | (m->rw14 << 14) | (m->rw15 << 15)),
int(m->gw | (m->gw10 << 10) | (m->gw11 << 11) | (m->gw12 << 12) | (m->gw13 << 13) | (m->gw14 << 14) | (m->gw15 << 15)),
int(m->bw | (m->bw10 << 10) | (m->bw11 << 11) | (m->bw12 << 12) | (m->bw13 << 13) | (m->bw14 << 14) | (m->bw15 << 15)));
XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
if (bSigned)
{
e0_A.x = SIGN_EXTEND(e0_A.x, 16);
e0_A.y = SIGN_EXTEND(e0_A.y, 16);
e0_A.z = SIGN_EXTEND(e0_A.z, 16);
e0_B.x = SIGN_EXTEND(e0_B.x, 4);
e0_B.y = SIGN_EXTEND(e0_B.y, 4);
e0_B.z = SIGN_EXTEND(e0_B.z, 4);
}
wprintf(L"\tMode 14 - [16 4]\n");
wprintf(L"\t E(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
wprintf(L"\t E(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
wprintf(L"\t Index: ");
PrintIndex4bpp(m->indices, 0, 0);
wprintf(L"\n");
}
break;
case 0x13: // Reserved mode (5 bits, 10011)
wprintf(L"\tERROR - Reserved mode 10011\n");
break;
case 0x17: // Reserved mode (5 bits, 10111)
wprintf(L"\tERROR - Reserved mode 10011\n");
break;
case 0x1B: // Reserved mode (5 bits, 11011)
wprintf(L"\tERROR - Reserved mode 11011\n");
break;
case 0x1F: // Reserved mode (5 bits, 11111)
wprintf(L"\tERROR - Reserved mode 11111\n");
break;
default:
break;
}
break;
}
break;
case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB:
// http://msdn.microsoft.com/en-us/library/windows/desktop/hh308954.aspx
if (*sptr & 0x01)
{
// Mode 0 (1)
struct bc7_mode0
{
uint64_t mode : 1;
uint64_t part : 4;
uint64_t r0 : 4;
uint64_t r1 : 4;
uint64_t r2 : 4;
uint64_t r3 : 4;
uint64_t r4 : 4;
uint64_t r5 : 4;
uint64_t g0 : 4;
uint64_t g1 : 4;
uint64_t g2 : 4;
uint64_t g3 : 4;
uint64_t g4 : 4;
uint64_t g5 : 4;
uint64_t b0 : 4;
uint64_t b1 : 4;
uint64_t b2 : 3;
uint64_t b2n : 1;
uint64_t b3 : 4;
uint64_t b4 : 4;
uint64_t b5 : 4;
uint64_t P0 : 1;
uint64_t P1 : 1;
uint64_t P2 : 1;
uint64_t P3 : 1;
uint64_t P4 : 1;
uint64_t P5 : 1;
uint64_t index : 45;
};
static_assert(sizeof(bc7_mode0) == 16, "Block size must be 16 bytes");
auto m = reinterpret_cast<const bc7_mode0*>(sptr);
wprintf(L"\tMode 0 - [4 4 4] partition %llu\n", m->part);
wprintf(L"\t E0:(%0.3f, %0.3f, %0.3f)\n", float((m->r0 << 1) | m->P0) / 31.f, float((m->g0 << 1) | m->P0) / 31.f, float((m->b0 << 1) | m->P0) / 31.f);
wprintf(L"\t E1:(%0.3f, %0.3f, %0.3f)\n", float((m->r1 << 1) | m->P1) / 31.f, float((m->g1 << 1) | m->P1) / 31.f, float((m->b1 << 1) | m->P1) / 31.f);
wprintf(L"\t E2:(%0.3f, %0.3f, %0.3f)\n", float((m->r2 << 1) | m->P2) / 31.f, float((m->g2 << 1) | m->P2) / 31.f, float(((m->b2 | (m->b2n << 3)) << 1) | m->P2) / 31.f);
wprintf(L"\t E3:(%0.3f, %0.3f, %0.3f)\n", float((m->r3 << 1) | m->P3) / 31.f, float((m->g3 << 1) | m->P3) / 31.f, float((m->b3 << 1) | m->P3) / 31.f);
wprintf(L"\t E4:(%0.3f, %0.3f, %0.3f)\n", float((m->r4 << 1) | m->P4) / 31.f, float((m->g4 << 1) | m->P4) / 31.f, float((m->b4 << 1) | m->P4) / 31.f);
wprintf(L"\t E5:(%0.3f, %0.3f, %0.3f)\n", float((m->r5 << 1) | m->P5) / 31.f, float((m->g5 << 1) | m->P5) / 31.f, float((m->b5 << 1) | m->P5) / 31.f);
wprintf(L"\t Index: ");
PrintIndex2bpp(m->index, 2, m->part);
wprintf(L"\n");
}
else if (*sptr & 0x02)
{
// Mode 1 (01)
struct bc7_mode1
{
uint64_t mode : 2;
uint64_t part : 6;
uint64_t r0 : 6;
uint64_t r1 : 6;
uint64_t r2 : 6;
uint64_t r3 : 6;
uint64_t g0 : 6;
uint64_t g1 : 6;
uint64_t g2 : 6;
uint64_t g3 : 6;
uint64_t b0 : 6;
uint64_t b1 : 2;
uint64_t b1n : 4;
uint64_t b2 : 6;
uint64_t b3 : 6;
uint64_t P0 : 1;
uint64_t P1 : 1;
uint64_t index : 46;
};
static_assert(sizeof(bc7_mode1) == 16, "Block size must be 16 bytes");
auto m = reinterpret_cast<const bc7_mode1*>(sptr);
wprintf(L"\tMode 1 - [6 6 6] partition %llu\n", m->part);
wprintf(L"\t E0:(%0.3f, %0.3f, %0.3f)\n", float((m->r0 << 1) | m->P0) / 127.f, float((m->g0 << 1) | m->P0) / 127.f, float((m->b0 << 1) | m->P0) / 127.f);
wprintf(L"\t E1:(%0.3f, %0.3f, %0.3f)\n", float((m->r1 << 1) | m->P0) / 127.f, float((m->g1 << 1) | m->P0) / 127.f, float(((m->b1 | (m->b1n << 2)) << 1) | m->P0) / 127.f);
wprintf(L"\t E2:(%0.3f, %0.3f, %0.3f)\n", float((m->r2 << 1) | m->P1) / 127.f, float((m->g2 << 1) | m->P1) / 127.f, float((m->b2 << 1) | m->P1) / 127.f);
wprintf(L"\t E3:(%0.3f, %0.3f, %0.3f)\n", float((m->r3 << 1) | m->P1) / 127.f, float((m->g3 << 1) | m->P1) / 127.f, float((m->b3 << 1) | m->P1) / 127.f);
wprintf(L"\t Index: ");
PrintIndex3bpp(m->index, 1, m->part);
wprintf(L"\n");
}
else if (*sptr & 0x04)
{
// Mode 2 (001)
struct bc7_mode2
{
uint64_t mode : 3;
uint64_t part : 6;
uint64_t r0 : 5;
uint64_t r1 : 5;
uint64_t r2 : 5;
uint64_t r3 : 5;
uint64_t r4 : 5;
uint64_t r5 : 5;
uint64_t g0 : 5;
uint64_t g1 : 5;
uint64_t g2 : 5;
uint64_t g3 : 5;
uint64_t g4 : 5;
uint64_t g5 : 5;
uint64_t b0 : 5;
uint64_t b1 : 5;
uint64_t b2 : 5;
uint64_t b3 : 5;
uint64_t b4 : 5;
uint64_t b5 : 5;
uint64_t index : 29;
};
static_assert(sizeof(bc7_mode2) == 16, "Block size must be 16 bytes");
auto m = reinterpret_cast<const bc7_mode2*>(sptr);
wprintf(L"\tMode 2 - [5 5 5] partition %llu\n", m->part);
wprintf(L"\t E0:(%0.3f, %0.3f, %0.3f)\n", float(m->r0) / 31.f, float(m->g0) / 31.f, float(m->b0) / 31.f);
wprintf(L"\t E1:(%0.3f, %0.3f, %0.3f)\n", float(m->r1) / 31.f, float(m->g1) / 31.f, float(m->b1) / 31.f);
wprintf(L"\t E2:(%0.3f, %0.3f, %0.3f)\n", float(m->r2) / 31.f, float(m->g2) / 31.f, float(m->b2) / 31.f);
wprintf(L"\t E3:(%0.3f, %0.3f, %0.3f)\n", float(m->r3) / 31.f, float(m->g3) / 31.f, float(m->b3) / 31.f);
wprintf(L"\t E4:(%0.3f, %0.3f, %0.3f)\n", float(m->r4) / 31.f, float(m->g4) / 31.f, float(m->b4) / 31.f);
wprintf(L"\t E5:(%0.3f, %0.3f, %0.3f)\n", float(m->r5) / 31.f, float(m->g5) / 31.f, float(m->b5) / 31.f);
wprintf(L"\t Index: ");
PrintIndex2bpp(m->index, 2, m->part);
wprintf(L"\n");
}
else if (*sptr & 0x08)
{
// Mode 3 (0001)
struct bc7_mode3
{
uint64_t mode : 4;
uint64_t part : 6;
uint64_t r0 : 7;
uint64_t r1 : 7;
uint64_t r2 : 7;
uint64_t r3 : 7;
uint64_t g0 : 7;
uint64_t g1 : 7;
uint64_t g2 : 7;
uint64_t g3 : 5;
uint64_t g3n : 2;
uint64_t b0 : 7;
uint64_t b1 : 7;
uint64_t b2 : 7;
uint64_t b3 : 7;
uint64_t P0 : 1;
uint64_t P1 : 1;
uint64_t P2 : 1;
uint64_t P3 : 1;
uint64_t index : 30;
};
static_assert(sizeof(bc7_mode3) == 16, "Block size must be 16 bytes");
auto m = reinterpret_cast<const bc7_mode3*>(sptr);
wprintf(L"\tMode 3 - [7 7 7] partition %llu\n", m->part);
wprintf(L"\t E0:(%0.3f, %0.3f, %0.3f)\n", float((m->r0 << 1) | m->P0) / 255.f, float((m->g0 << 1) | m->P0) / 255.f, float((m->b0 << 1) | m->P0) / 255.f);
wprintf(L"\t E1:(%0.3f, %0.3f, %0.3f)\n", float((m->r1 << 1) | m->P1) / 255.f, float((m->g1 << 1) | m->P1) / 255.f, float((m->b1 << 1) | m->P1) / 255.f);
wprintf(L"\t E2:(%0.3f, %0.3f, %0.3f)\n", float((m->r2 << 1) | m->P2) / 255.f, float((m->g2 << 1) | m->P2) / 255.f, float((m->b2 << 1) | m->P2) / 255.f);
wprintf(L"\t E3:(%0.3f, %0.3f, %0.3f)\n", float((m->r3 << 1) | m->P3) / 255.f, float(((m->g3 | (m->g3n << 5)) << 1) | m->P3) / 255.f, float((m->b3 << 1) | m->P3) / 255.f);
wprintf(L"\t Index: ");
PrintIndex2bpp(m->index, 1, m->part);
wprintf(L"\n");
}
else if (*sptr & 0x10)
{
// Mode 4 (00001)
struct bc7_mode4
{
uint64_t mode : 5;
uint64_t rot : 2;
uint64_t idx : 1;
uint64_t r0 : 5;
uint64_t r1 : 5;
uint64_t g0 : 5;
uint64_t g1 : 5;
uint64_t b0 : 5;
uint64_t b1 : 5;
uint64_t a0 : 6;
uint64_t a1 : 6;
uint64_t color_index : 14;
uint64_t color_indexn : 17;
uint64_t alpha_index : 47;
};
static_assert(sizeof(bc7_mode4) == 16, "Block size must be 16 bytes");
auto m = reinterpret_cast<const bc7_mode4*>(sptr);
wprintf(L"\tMode 4 - [5 5 5 A6] indx mode %ls, rot-bits %llu%ls\n", m->idx ? L"3-bit" : L"2-bit", m->rot, GetRotBits(m->rot));
wprintf(L"\t C0:(%0.3f, %0.3f, %0.3f)\n", float(m->r0) / 31.f, float(m->g0) / 31.f, float(m->b0) / 31.f);
wprintf(L"\t C1:(%0.3f, %0.3f, %0.3f)\n", float(m->r1) / 31.f, float(m->g1) / 31.f, float(m->b1) / 31.f);
wprintf(L"\t A0:(%0.3f)\n", float(m->a0) / 63.f);
wprintf(L"\t A1:(%0.3f)\n", float(m->a1) / 63.f);
wprintf(L"\t Colors: ");
uint64_t color_index = uint64_t(m->color_index) | uint64_t(m->color_indexn << 14);
if (m->idx)
PrintIndex3bpp(color_index, 0, 0);
else
PrintIndex2bpp(color_index, 0, 0);
wprintf(L"\n");
wprintf(L"\t Alpha: ");
PrintIndex3bpp(m->alpha_index, 0, 0);
wprintf(L"\n");
}
else if (*sptr & 0x20)
{
// Mode 5 (000001)
struct bc7_mode5
{
uint64_t mode : 6;
uint64_t rot : 2;
uint64_t r0 : 7;
uint64_t r1 : 7;
uint64_t g0 : 7;
uint64_t g1 : 7;
uint64_t b0 : 7;
uint64_t b1 : 7;
uint64_t a0 : 8;
uint64_t a1 : 6;
uint64_t a1n : 2;
uint64_t color_index : 31;
uint64_t alpha_index : 31;
};
static_assert(sizeof(bc7_mode5) == 16, "Block size must be 16 bytes");
auto m = reinterpret_cast<const bc7_mode5*>(sptr);
wprintf(L"\tMode 5 - [7 7 7 A8] rot-bits %llu%ls\n", m->rot, GetRotBits(m->rot));
wprintf(L"\t C0:(%0.3f, %0.3f, %0.3f)\n", float(m->r0) / 127.f, float(m->g0) / 127.f, float(m->b0) / 127.f);
wprintf(L"\t C1:(%0.3f, %0.3f, %0.3f)\n", float(m->r1) / 127.f, float(m->g1) / 127.f, float(m->b1) / 127.f);
wprintf(L"\t A0:(%0.3f)\n", float(m->a0) / 255.f);
wprintf(L"\t A1:(%0.3f)\n", float(m->a1 | (m->a1n << 6)) / 255.f);
wprintf(L"\t Colors: ");
PrintIndex2bpp(m->color_index, 0, 0);
wprintf(L"\n");
wprintf(L"\t Alpha: ");
PrintIndex2bpp(m->alpha_index, 0, 0);
wprintf(L"\n");
}
else if (*sptr & 0x40)
{
// Mode 6 (0000001)
struct bc7_mode6
{
uint64_t mode : 7;
uint64_t r0 : 7;
uint64_t r1 : 7;
uint64_t g0 : 7;
uint64_t g1 : 7;
uint64_t b0 : 7;
uint64_t b1 : 7;
uint64_t a0 : 7;
uint64_t a1 : 7;
uint64_t P0 : 1;
uint64_t P1 : 1;
uint64_t index : 63;
};
static_assert(sizeof(bc7_mode6) == 16, "Block size must be 16 bytes");
auto m = reinterpret_cast<const bc7_mode6*>(sptr);
wprintf(L"\tMode 6 - [7 7 7 A7]\n");
wprintf(L"\t C0:(%0.3f, %0.3f, %0.3f)\n", float((m->r0 << 1) | m->P0) / 255.f, float((m->g0 << 1) | m->P0) / 255.f, float((m->b0 << 1) | m->P0) / 255.f);
wprintf(L"\t C1:(%0.3f, %0.3f, %0.3f)\n", float((m->r1 << 1) | m->P1) / 255.f, float((m->g1 << 1) | m->P1) / 255.f, float((m->b1 << 1) | m->P1) / 255.f);
wprintf(L"\t A0:(%0.3f)\n", float((m->a0 << 1) | m->P0) / 255.f);
wprintf(L"\t A1:(%0.3f)\n", float((m->a1 << 1) | m->P1) / 255.f);
wprintf(L"\t Index: ");
PrintIndex4bpp(m->index, 0, 0);
wprintf(L"\n");
}
else if (*sptr & 0x80)
{
// Mode 7 (00000001)
struct bc7_mode7
{
uint64_t mode : 8;
uint64_t part : 6;
uint64_t r0 : 5;
uint64_t r1 : 5;
uint64_t r2 : 5;
uint64_t r3 : 5;
uint64_t g0 : 5;
uint64_t g1 : 5;
uint64_t g2 : 5;
uint64_t g3 : 5;
uint64_t b0 : 5;
uint64_t b1 : 5;
uint64_t b2 : 5;
uint64_t b3 : 5;
uint64_t a0 : 5;
uint64_t a1 : 5;
uint64_t a2 : 5;
uint64_t a3 : 5;
uint64_t P0 : 1;
uint64_t P1 : 1;
uint64_t P2 : 1;
uint64_t P3 : 1;
uint64_t index : 30;
};
static_assert(sizeof(bc7_mode7) == 16, "Block size must be 16 bytes");
auto m = reinterpret_cast<const bc7_mode7*>(sptr);
wprintf(L"\tMode 7 - [5 5 5 A5] partition %llu\n", m->part);
wprintf(L"\t C0:(%0.3f, %0.3f, %0.3f)\n", float((m->r0 << 1) | m->P0) / 63.f, float((m->g0 << 1) | m->P0) / 63.f, float((m->b0 << 1) | m->P0) / 63.f);
wprintf(L"\t C1:(%0.3f, %0.3f, %0.3f)\n", float((m->r1 << 1) | m->P1) / 63.f, float((m->g1 << 1) | m->P1) / 63.f, float((m->b1 << 1) | m->P1) / 63.f);
wprintf(L"\t C2:(%0.3f, %0.3f, %0.3f)\n", float((m->r2 << 1) | m->P2) / 63.f, float((m->g2 << 1) | m->P2) / 63.f, float((m->b2 << 1) | m->P2) / 63.f);
wprintf(L"\t C3:(%0.3f, %0.3f, %0.3f)\n", float((m->r3 << 1) | m->P3) / 63.f, float((m->g3 << 1) | m->P3) / 63.f, float((m->b3 << 1) | m->P3) / 63.f);
wprintf(L"\t A0:(%0.3f)\n", float((m->a0 << 1) | m->P0) / 63.f);
wprintf(L"\t A1:(%0.3f)\n", float((m->a1 << 1) | m->P1) / 63.f);
wprintf(L"\t A2:(%0.3f)\n", float((m->a2 << 1) | m->P2) / 63.f);
wprintf(L"\t A3:(%0.3f)\n", float((m->a3 << 1) | m->P3) / 63.f);
wprintf(L"\t Index: ");
PrintIndex4bpp(m->index, 1, m->part);
wprintf(L"\n");
}
else
{
// Reserved mode 8 (00000000)
wprintf(L"\tERROR - Reserved mode 8\n");
}
break;
}
}
}
return S_OK;
}