Created
July 7, 2023 03:09
-
-
Save rygorous/897185a1e8cee7c1b252ac50e5a92b31 to your computer and use it in GitHub Desktop.
BC7 encoding for single-color blocks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void bc7_encode_single_color_block(U8 * output_bc7, const U8 rgba[4]) | |
{ | |
U64 r = rgba[0]; | |
U64 g = rgba[1]; | |
U64 b = rgba[2]; | |
U64 a = rgba[3]; | |
const U64 bit6_mask = (0x40 << 8) | (0x40 << 22) | (0x40ull << 36); | |
const U64 lo7_mask = (0x7f << 8) | (0x7f << 22) | (0x7full << 36); | |
U64 color_bits; | |
// Color channels (see bc7solid/main.cpp) | |
// this is the bit-hack version written to process 3 color chans at once | |
color_bits = (r << 8) | (g << 22) | (b << 36); | |
// The basic idea here is this: for every color channel, we get the right | |
// results with | |
// e0 = val >> 1 | |
// e1 = (val + (val < 128 ? 1 : -1)) >> 1 | |
// the bias in the e1 computation | |
// (val < 128 ? 1 : -1) | |
// can be written as | |
// 1 - ((val >> 6) & 2) | |
// and the rest is just bit fiddling and accounting for the layout of mode 5. | |
U64 t = color_bits << 6; | |
color_bits = ((color_bits >> 1) & lo7_mask) - (color_bits & ~lo7_mask); | |
color_bits += t + (t & bit6_mask); | |
// alpha: just set endpoint 0 to target value then use all-0 inds | |
color_bits |= a << 50; | |
// insert mode bits | |
color_bits |= 0x20; // mode 5, rotation=0 | |
RR_PUT64_LE_UNALIGNED(output_bc7 + 0, color_bits); // this covers 64 out of the 66 mode/color bits | |
RR_PUT64_LE_UNALIGNED(output_bc7 + 8, 0xaaaaaaac); // last 2 color bits, color index bits, alpha index bits | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment