hglm/detex

serious BC7 decoder bugs

Opened this issue · 1 comments

The BC7 encoder has a couple easily fixed bugs that cause it to fail on some blocks:

detexGetBits64() fails when bit1 is 63 (when built with VS2015 x64). I believe the original implementation relied on undefined behavior (shift left of 1 by 64 bits != 0 on some platforms). Here's the fix:

static DETEX_INLINE_ONLY uint32_t detexGetBits64(uint64_t data, int bit0, int bit1) 
{
    uint64_t mask;
    if (bit1 == 63)
	mask = UINT64_MAX;
    else
	mask = ((uint64_t)1 << (bit1 + 1)) - 1;

    return (data & mask) >> bit0;
}   

The other bug is in FullyDecodeEndpoints() - sometimes the endpoints do across between the two 64-bit values in a block:

static void FullyDecodeEndpoints(uint8_t * DETEX_RESTRICT endpoint_array, int nu_subsets,
int mode, detexBlock128 * DETEX_RESTRICT block) {
if (mode_has_p_bits[mode]) {
// Mode 1 (shared P-bits) handled elsewhere.
// Extract end-point P-bits.
uint32_t bits;
if (block->index < 64)
{
bits = block->data0 >> block->index;
// Bugfix!
if ((block->index + nu_subsets * 2) > 64)
{
bits |= (block->data1 << (64 - block->index));
}
}

Once these 2 fixes are made this decoder outputs the same pixels as DirectXTex's.

Confirm, i even made a pull request for it
#19