summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/textures/astc.cpp86
-rw-r--r--src/video_core/textures/astc.h41
2 files changed, 63 insertions, 64 deletions
diff --git a/src/video_core/textures/astc.cpp b/src/video_core/textures/astc.cpp
index 3ab500760..26c19d75b 100644
--- a/src/video_core/textures/astc.cpp
+++ b/src/video_core/textures/astc.cpp
@@ -521,35 +521,41 @@ static TexelWeightParams DecodeBlockInfo(InputBitStream& strm) {
521 return params; 521 return params;
522} 522}
523 523
524static void FillVoidExtentLDR(InputBitStream& strm, std::span<u32> outBuf, u32 blockWidth, 524// Replicates low num_bits such that [(to_bit - 1):(to_bit - 1 - from_bit)]
525 u32 blockHeight) { 525// is the same as [(num_bits - 1):0] and repeats all the way down.
526 // Don't actually care about the void extent, just read the bits... 526template <typename IntType>
527 for (s32 i = 0; i < 4; ++i) { 527static constexpr IntType Replicate(IntType val, u32 num_bits, u32 to_bit) {
528 strm.ReadBits<13>(); 528 if (num_bits == 0 || to_bit == 0) {
529 return 0;
529 } 530 }
530 531 const IntType v = val & static_cast<IntType>((1 << num_bits) - 1);
531 // Decode the RGBA components and renormalize them to the range [0, 255] 532 IntType res = v;
532 u16 r = static_cast<u16>(strm.ReadBits<16>()); 533 u32 reslen = num_bits;
533 u16 g = static_cast<u16>(strm.ReadBits<16>()); 534 while (reslen < to_bit) {
534 u16 b = static_cast<u16>(strm.ReadBits<16>()); 535 u32 comp = 0;
535 u16 a = static_cast<u16>(strm.ReadBits<16>()); 536 if (num_bits > to_bit - reslen) {
536 537 u32 newshift = to_bit - reslen;
537 u32 rgba = (r >> 8) | (g & 0xFF00) | (static_cast<u32>(b) & 0xFF00) << 8 | 538 comp = num_bits - newshift;
538 (static_cast<u32>(a) & 0xFF00) << 16; 539 num_bits = newshift;
539
540 for (u32 j = 0; j < blockHeight; j++) {
541 for (u32 i = 0; i < blockWidth; i++) {
542 outBuf[j * blockWidth + i] = rgba;
543 } 540 }
541 res = static_cast<IntType>(res << num_bits);
542 res = static_cast<IntType>(res | (v >> comp));
543 reslen += num_bits;
544 } 544 }
545 return res;
545} 546}
546 547
547static void FillError(std::span<u32> outBuf, u32 blockWidth, u32 blockHeight) { 548static constexpr std::size_t NumReplicateEntries(u32 num_bits) {
548 for (u32 j = 0; j < blockHeight; j++) { 549 return std::size_t(1) << num_bits;
549 for (u32 i = 0; i < blockWidth; i++) { 550}
550 outBuf[j * blockWidth + i] = 0xFFFF00FF; 551
551 } 552template <typename IntType, u32 num_bits, u32 to_bit>
553static constexpr auto MakeReplicateTable() {
554 std::array<IntType, NumReplicateEntries(num_bits)> table{};
555 for (IntType value = 0; value < static_cast<IntType>(std::size(table)); ++value) {
556 table[value] = Replicate(value, num_bits, to_bit);
552 } 557 }
558 return table;
553} 559}
554 560
555static constexpr auto REPLICATE_BYTE_TO_16_TABLE = MakeReplicateTable<u32, 8, 16>(); 561static constexpr auto REPLICATE_BYTE_TO_16_TABLE = MakeReplicateTable<u32, 8, 16>();
@@ -572,6 +578,9 @@ static constexpr auto REPLICATE_2_BIT_TO_8_TABLE = MakeReplicateTable<u32, 2, 8>
572static constexpr auto REPLICATE_3_BIT_TO_8_TABLE = MakeReplicateTable<u32, 3, 8>(); 578static constexpr auto REPLICATE_3_BIT_TO_8_TABLE = MakeReplicateTable<u32, 3, 8>();
573static constexpr auto REPLICATE_4_BIT_TO_8_TABLE = MakeReplicateTable<u32, 4, 8>(); 579static constexpr auto REPLICATE_4_BIT_TO_8_TABLE = MakeReplicateTable<u32, 4, 8>();
574static constexpr auto REPLICATE_5_BIT_TO_8_TABLE = MakeReplicateTable<u32, 5, 8>(); 580static constexpr auto REPLICATE_5_BIT_TO_8_TABLE = MakeReplicateTable<u32, 5, 8>();
581static constexpr auto REPLICATE_6_BIT_TO_8_TABLE = MakeReplicateTable<u32, 6, 8>();
582static constexpr auto REPLICATE_7_BIT_TO_8_TABLE = MakeReplicateTable<u32, 7, 8>();
583static constexpr auto REPLICATE_8_BIT_TO_8_TABLE = MakeReplicateTable<u32, 8, 8>();
575/// Use a precompiled table with the most common usages, if it's not in the expected range, fallback 584/// Use a precompiled table with the most common usages, if it's not in the expected range, fallback
576/// to the runtime implementation 585/// to the runtime implementation
577static constexpr u32 FastReplicateTo8(u32 value, u32 num_bits) { 586static constexpr u32 FastReplicateTo8(u32 value, u32 num_bits) {
@@ -1316,6 +1325,37 @@ static void ComputeEndpoints(Pixel& ep1, Pixel& ep2, const u32*& colorValues,
1316#undef READ_INT_VALUES 1325#undef READ_INT_VALUES
1317} 1326}
1318 1327
1328static void FillVoidExtentLDR(InputBitStream& strm, std::span<u32> outBuf, u32 blockWidth,
1329 u32 blockHeight) {
1330 // Don't actually care about the void extent, just read the bits...
1331 for (s32 i = 0; i < 4; ++i) {
1332 strm.ReadBits<13>();
1333 }
1334
1335 // Decode the RGBA components and renormalize them to the range [0, 255]
1336 u16 r = static_cast<u16>(strm.ReadBits<16>());
1337 u16 g = static_cast<u16>(strm.ReadBits<16>());
1338 u16 b = static_cast<u16>(strm.ReadBits<16>());
1339 u16 a = static_cast<u16>(strm.ReadBits<16>());
1340
1341 u32 rgba = (r >> 8) | (g & 0xFF00) | (static_cast<u32>(b) & 0xFF00) << 8 |
1342 (static_cast<u32>(a) & 0xFF00) << 16;
1343
1344 for (u32 j = 0; j < blockHeight; j++) {
1345 for (u32 i = 0; i < blockWidth; i++) {
1346 outBuf[j * blockWidth + i] = rgba;
1347 }
1348 }
1349}
1350
1351static void FillError(std::span<u32> outBuf, u32 blockWidth, u32 blockHeight) {
1352 for (u32 j = 0; j < blockHeight; j++) {
1353 for (u32 i = 0; i < blockWidth; i++) {
1354 outBuf[j * blockWidth + i] = 0xFFFF00FF;
1355 }
1356 }
1357}
1358
1319static void DecompressBlock(std::span<const u8, 16> inBuf, const u32 blockWidth, 1359static void DecompressBlock(std::span<const u8, 16> inBuf, const u32 blockWidth,
1320 const u32 blockHeight, std::span<u32, 12 * 12> outBuf) { 1360 const u32 blockHeight, std::span<u32, 12 * 12> outBuf) {
1321 InputBitStream strm(inBuf); 1361 InputBitStream strm(inBuf);
diff --git a/src/video_core/textures/astc.h b/src/video_core/textures/astc.h
index 0229ae122..9e148afc4 100644
--- a/src/video_core/textures/astc.h
+++ b/src/video_core/textures/astc.h
@@ -79,47 +79,6 @@ constexpr std::array<IntegerEncodedValue, 256> MakeEncodedValues() {
79 79
80constexpr std::array<IntegerEncodedValue, 256> ASTC_ENCODINGS_VALUES = MakeEncodedValues(); 80constexpr std::array<IntegerEncodedValue, 256> ASTC_ENCODINGS_VALUES = MakeEncodedValues();
81 81
82// Replicates low num_bits such that [(to_bit - 1):(to_bit - 1 - from_bit)]
83// is the same as [(num_bits - 1):0] and repeats all the way down.
84template <typename IntType>
85constexpr IntType Replicate(IntType val, u32 num_bits, u32 to_bit) {
86 if (num_bits == 0 || to_bit == 0) {
87 return 0;
88 }
89 const IntType v = val & static_cast<IntType>((1 << num_bits) - 1);
90 IntType res = v;
91 u32 reslen = num_bits;
92 while (reslen < to_bit) {
93 u32 comp = 0;
94 if (num_bits > to_bit - reslen) {
95 u32 newshift = to_bit - reslen;
96 comp = num_bits - newshift;
97 num_bits = newshift;
98 }
99 res = static_cast<IntType>(res << num_bits);
100 res = static_cast<IntType>(res | (v >> comp));
101 reslen += num_bits;
102 }
103 return res;
104}
105
106constexpr std::size_t NumReplicateEntries(u32 num_bits) {
107 return std::size_t(1) << num_bits;
108}
109
110template <typename IntType, u32 num_bits, u32 to_bit>
111constexpr auto MakeReplicateTable() {
112 std::array<IntType, NumReplicateEntries(num_bits)> table{};
113 for (IntType value = 0; value < static_cast<IntType>(std::size(table)); ++value) {
114 table[value] = Replicate(value, num_bits, to_bit);
115 }
116 return table;
117}
118
119constexpr auto REPLICATE_6_BIT_TO_8_TABLE = MakeReplicateTable<u32, 6, 8>();
120constexpr auto REPLICATE_7_BIT_TO_8_TABLE = MakeReplicateTable<u32, 7, 8>();
121constexpr auto REPLICATE_8_BIT_TO_8_TABLE = MakeReplicateTable<u32, 8, 8>();
122
123void Decompress(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth, 82void Decompress(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth,
124 uint32_t block_width, uint32_t block_height, std::span<uint8_t> output); 83 uint32_t block_width, uint32_t block_height, std::span<uint8_t> output);
125 84