oops bcn format

This commit is contained in:
lizzie 2025-12-29 19:16:12 +00:00
parent c7adeb6a7f
commit 477665f61f
2 changed files with 71 additions and 104 deletions

View File

@ -168,88 +168,6 @@ namespace {
namespace BC6H {
static constexpr int32_t MaxPartitions = 64;
// @fmt:off
static constexpr uint8_t PartitionTable2[MaxPartitions][16] = {
{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 },
{ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 },
{ 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1 },
{ 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1 },
{ 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1 },
{ 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1 },
{ 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 },
{ 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1 },
{ 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 },
{ 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 },
{ 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0 },
{ 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0 },
{ 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0 },
{ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 },
{ 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0 },
{ 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0 },
{ 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0 },
{ 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1 },
{ 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 },
{ 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0 },
{ 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0 },
{ 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0 },
{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 },
{ 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1 },
{ 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0 },
{ 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1 },
{ 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1 },
{ 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0 },
{ 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0 },
{ 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 },
{ 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1 },
{ 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1 },
{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 },
{ 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0 },
{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1 },
};
static constexpr uint8_t AnchorTable2[MaxPartitions] = {
0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0xf, 0x2, 0x8, 0x2, 0x2, 0x8, 0x8, 0xf,
0x2, 0x8, 0x2, 0x2, 0x8, 0x8, 0x2, 0x2,
0xf, 0xf, 0x6, 0x8, 0x2, 0x8, 0xf, 0xf,
0x2, 0x8, 0x2, 0x2, 0x2, 0xf, 0xf, 0x6,
0x6, 0x2, 0x6, 0x8, 0xf, 0xf, 0x2, 0x2,
0xf, 0xf, 0xf, 0xf, 0xf, 0x2, 0x2, 0xf,
};
// @fmt:on
// 1.0f in half-precision floating point format
static constexpr uint16_t halfFloat1 = 0x3C00;
union Color {
@ -793,15 +711,56 @@ namespace {
uint64_t high64;
void decode(uint8_t *dst, size_t dstX, size_t dstY, size_t dstWidth, size_t dstHeight, size_t dstPitch, size_t dstBpp, bool isSigned) const {
uint8_t mode = 0;
// @fmt:off
static const uint32_t p_table[MaxPartitions] = {
0b01010000010100000101000001010000, 0b01000000010000000100000001000000,
0b01010100010101000101010001010100, 0b01010100010100000101000001000000,
0b01010000010000000100000000000000, 0b01010101010101000101010001010000,
0b01010101010101000101000001000000, 0b01010100010100000100000000000000,
0b01010000010000000000000000000000, 0b01010101010101010101010001010000,
0b01010101010101000100000000000000, 0b01010100010000000000000000000000,
0b01010101010101010101010001000000, 0b01010101010101010000000000000000,
0b01010101010101010101010100000000, 0b01010101000000000000000000000000,
0b01010101000101010000000100000000, 0b00000000000000000100000001010100,
0b00010101000000010000000000000000, 0b00000000010000000101000001010100,
0b00000000000000000100000001010000, 0b00010101000001010000000100000000,
0b00000101000000010000000000000000, 0b01000000010100000101000001010100,
0b00000000010000000100000001010000, 0b00000101000000010000000100000000,
0b00010100000101000001010000010100, 0b00000101000101000001010001010000,
0b00000001000101010101010001000000, 0b00000000010101010101010100000000,
0b00010101000000010100000001010100, 0b00000101010000010100000101010000,
0b01000100010001000100010001000100, 0b01010101000000000101010100000000,
0b00010001010001000001000101000100, 0b00000101000001010101000001010000,
0b00000101010100000000010101010000, 0b00010001000100010100010001000100,
0b01000001000101000100000100010100, 0b01000100000100010001000101000100,
0b00010101000001010101000001010100, 0b00000001000001010101000001000000,
0b00000101000001000001000001010000, 0b00000101010001010101000101010000,
0b00010100010000010100000100010100, 0b01010000000001010000010101010000,
0b01000001010000010001010000010100, 0b00000000000101000001010000000000,
0b00000000000001000001010100000100, 0b00000000000100000101010000010000,
0b00010000010101000001000000000000, 0b00000100000101010000010000000000,
0b01010000010000010000010100010100, 0b01000001000001010001010001010000,
0b00000101010000010101000000010100, 0b00010100000001010100000101010000,
0b01000001000001010000010100010100, 0b01000001010100000101000000010100,
0b01000000000000010001010101010100, 0b01010100000101010000000101000000,
0b01010000010100000101010100000000, 0b00000000010101010101000001010000,
0b00010101000101010001000000010000, 0b01010100010101000000010000000100,
};
static const uint8_t AnchorTable2[MaxPartitions] = {
0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0xf, 0x2, 0x8, 0x2, 0x2, 0x8, 0x8, 0xf,
0x2, 0x8, 0x2, 0x2, 0x8, 0x8, 0x2, 0x2,
0xf, 0xf, 0x6, 0x8, 0x2, 0x8, 0xf, 0xf,
0x2, 0x8, 0x2, 0x2, 0x2, 0xf, 0xf, 0x6,
0x6, 0x2, 0x6, 0x8, 0xf, 0xf, 0x2, 0x2,
0xf, 0xf, 0xf, 0xf, 0xf, 0x2, 0x2, 0xf,
};
// @fmt:on
Data data(low64, high64);
assert(dstBpp == sizeof(Color));
if ((data.low64 & 0x2) == 0) {
mode = data.consumeBits(1, 0);
} else {
mode = data.consumeBits(4, 0);
}
uint8_t mode = data.consumeBits((data.low64 & 0x2) == 0 ? 1 : 4, 0);
int32_t blockIndex = modeToIndex(mode);
// Handle illegal or reserved mode
@ -894,7 +853,7 @@ namespace {
idx.num_bits = 3;
// There are 2 indices with implicit leading 0-bits.
isAnchor = ((pixelNum == 0) || (pixelNum == AnchorTable2[partition]));
firstEndpoint = PartitionTable2[partition][pixelNum] * 2;
firstEndpoint = ((p_table[partition] >> pixelNum) & 0x03) * 2;
}
idx.value = data.consumeBits(idx.num_bits - isAnchor - 1, 0);
@ -931,7 +890,7 @@ namespace {
};
struct Mode {
const uint32_t IDX; // Mode index
const int32_t IDX; // Mode index
const uint32_t NS; // Number of subsets in each partition
const uint32_t PB; // Partition bits
const uint32_t RB; // Rotation bits
@ -946,7 +905,7 @@ namespace {
constexpr uint32_t NumColors() const { return NS * 2; }
constexpr Bitfield Partition() const { return {IDX + 1, PB}; }
constexpr Bitfield Partition() const { return {uint32_t(IDX) + 1, PB}; }
constexpr Bitfield Rotation() const { return Partition().Then(RB); }
@ -1028,7 +987,7 @@ namespace {
}
Mode const& mode() const {
static const Mode m_table[8] = {
static const Mode m_table[8 + 1] = {
// IDX NS PB RB ISB CB AB EPB SPB IB IBC, IB2
/**/ {0x0, 0x3, 0x4, 0x0, 0x0, 0x4, 0x0, 0x1, 0x0, 0x3, 0x2d, 0x0},
/**/ {0x1, 0x2, 0x6, 0x0, 0x0, 0x6, 0x0, 0x0, 0x1, 0x3, 0x2e, 0x0},
@ -1038,6 +997,7 @@ namespace {
/**/ {0x5, 0x1, 0x0, 0x2, 0x0, 0x7, 0x8, 0x0, 0x0, 0x2, 0x1f, 0x2},
/**/ {0x6, 0x1, 0x0, 0x0, 0x0, 0x7, 0x7, 0x1, 0x0, 0x4, 0x3f, 0x0},
/**/ {0x7, 0x2, 0x6, 0x0, 0x0, 0x5, 0x5, 0x1, 0x0, 0x2, 0x1e, 0x0},
/**/ {-1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x00, 0x0},
};
// Fun historical fact: this is basically ffs(), however, windows does NOT have ffs()
// This is because ffs() comes from VAX which had an instruction for ffs(), but
@ -1053,21 +1013,20 @@ namespace {
else if ((low & 0b00100000) != 0) return m_table[5];
else if ((low & 0b01000000) != 0) return m_table[6];
else if ((low & 0b10000000) != 0) return m_table[7];
return m_table[0]; //invalid but pretend it's fine
return m_table[8]; //invalid but pretend it's fine
}
struct IndexInfo {
uint64_t value;
int64_t num_bits;
uint32_t num_bits;
};
uint8_t interpolate(uint8_t e0, uint8_t e1, const IndexInfo &index) const {
static const uint16_t weightsN[5][16] = {
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{0, 21, 43, 64}, // {0, 21, 43, 64} = (21 * n) + 1
{0, 9, 18, 27, 37, 46, 55, 64},
{0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64}
static constexpr uint16_t weights2[] = {0, 21, 43, 64};
static constexpr uint16_t weights3[] = {0, 9, 18, 27, 37, 46, 55, 64};
static constexpr uint16_t weights4[] = {0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64};
static constexpr uint16_t const *weightsN[] = {
nullptr, nullptr, weights2, weights3, weights4
};
auto weights = weightsN[index.num_bits];
assert(weights != nullptr);
@ -1077,6 +1036,17 @@ namespace {
void decode(uint8_t *dst, size_t dstX, size_t dstY, size_t dstWidth, size_t dstHeight, size_t dstPitch) const {
assert(low <= 0b11111111);
auto const& mode = this->mode();
if (mode.IDX < 0) {
for (size_t y = 0; y < 4 && y + dstY < dstHeight; y++) {
for (size_t x = 0; x < 4 && x + dstX < dstWidth; x++) {
auto out = reinterpret_cast<Color *>(dst + sizeof(Color) * x + dstPitch * y);
out->rgb = {0, 0, 0};
out->a = 0;
}
}
return;
}
std::array<std::array<Color, 2>, 3> subsets;
for (size_t i = 0; i < mode.NS; i++) {
auto& subset = subsets[i];

View File

@ -23,11 +23,8 @@ using VideoCore::Surface::PixelFormat;
constexpr bool IsSigned(PixelFormat pixel_format) {
switch (pixel_format) {
case PixelFormat::BC4_SNORM:
case PixelFormat::BC4_UNORM:
case PixelFormat::BC5_SNORM:
case PixelFormat::BC5_UNORM:
case PixelFormat::BC6H_SFLOAT:
case PixelFormat::BC6H_UFLOAT:
return true;
default:
return false;