From 2f83d9a61bca42d9ef24074beb2b11b19bd4cecd Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 25 Mar 2021 16:53:51 -0400 Subject: astc_decoder: Refactor for style and more efficient memory use --- src/video_core/textures/astc.h | 174 ++++++++++++----------------------------- 1 file changed, 51 insertions(+), 123 deletions(-) (limited to 'src/video_core/textures/astc.h') diff --git a/src/video_core/textures/astc.h b/src/video_core/textures/astc.h index bc8bddaec..c1c73fda5 100644 --- a/src/video_core/textures/astc.h +++ b/src/video_core/textures/astc.h @@ -4,20 +4,12 @@ #pragma once -#include +#include +#include "common/common_types.h" namespace Tegra::Texture::ASTC { -/// Count the number of bits set in a number. -constexpr u32 Popcnt(u32 n) { - u32 c = 0; - for (; n; c++) { - n &= n - 1; - } - return c; -} - -enum class IntegerEncoding { JustBits, Qus32, Trit }; +enum class IntegerEncoding { JustBits, Quint, Trit }; struct IntegerEncodedValue { constexpr IntegerEncodedValue() = default; @@ -29,55 +21,55 @@ struct IntegerEncodedValue { return encoding == other.encoding && num_bits == other.num_bits; } - // Returns the number of bits required to encode nVals values. - u32 GetBitLength(u32 nVals) const { - u32 totalBits = num_bits * nVals; + // Returns the number of bits required to encode num_vals values. + u32 GetBitLength(u32 num_vals) const { + u32 total_bits = num_bits * num_vals; if (encoding == IntegerEncoding::Trit) { - totalBits += (nVals * 8 + 4) / 5; - } else if (encoding == IntegerEncoding::Qus32) { - totalBits += (nVals * 7 + 2) / 3; + total_bits += (num_vals * 8 + 4) / 5; + } else if (encoding == IntegerEncoding::Quint) { + total_bits += (num_vals * 7 + 2) / 3; } - return totalBits; + return total_bits; } IntegerEncoding encoding{}; u32 num_bits = 0; u32 bit_value = 0; union { - u32 qus32_value = 0; + u32 quint_value = 0; u32 trit_value; }; }; // Returns a new instance of this struct that corresponds to the -// can take no more than maxval values -static constexpr IntegerEncodedValue CreateEncoding(u32 maxVal) { - while (maxVal > 0) { - u32 check = maxVal + 1; +// can take no more than mav_value values +constexpr IntegerEncodedValue CreateEncoding(u32 mav_value) { + while (mav_value > 0) { + u32 check = mav_value + 1; - // Is maxVal a power of two? + // Is mav_value a power of two? if (!(check & (check - 1))) { - return IntegerEncodedValue(IntegerEncoding::JustBits, Popcnt(maxVal)); + return IntegerEncodedValue(IntegerEncoding::JustBits, std::popcount(mav_value)); } - // Is maxVal of the type 3*2^n - 1? + // Is mav_value of the type 3*2^n - 1? if ((check % 3 == 0) && !((check / 3) & ((check / 3) - 1))) { - return IntegerEncodedValue(IntegerEncoding::Trit, Popcnt(check / 3 - 1)); + return IntegerEncodedValue(IntegerEncoding::Trit, std::popcount(check / 3 - 1)); } - // Is maxVal of the type 5*2^n - 1? + // Is mav_value of the type 5*2^n - 1? if ((check % 5 == 0) && !((check / 5) & ((check / 5) - 1))) { - return IntegerEncodedValue(IntegerEncoding::Qus32, Popcnt(check / 5 - 1)); + return IntegerEncodedValue(IntegerEncoding::Quint, std::popcount(check / 5 - 1)); } // Apparently it can't be represented with a bounded integer sequence... // just iterate. - maxVal--; + mav_value--; } return IntegerEncodedValue(IntegerEncoding::JustBits, 0); } -static constexpr std::array MakeEncodedValues() { +constexpr std::array MakeEncodedValues() { std::array encodings{}; for (std::size_t i = 0; i < encodings.size(); ++i) { encodings[i] = CreateEncoding(static_cast(i)); @@ -85,41 +77,38 @@ static constexpr std::array MakeEncodedValues() { return encodings; } -static constexpr std::array EncodingsValues = MakeEncodedValues(); +constexpr std::array EncodingsValues = MakeEncodedValues(); -// Replicates low numBits such that [(toBit - 1):(toBit - 1 - fromBit)] -// is the same as [(numBits - 1):0] and repeats all the way down. +// Replicates low num_bits such that [(to_bit - 1):(to_bit - 1 - from_bit)] +// is the same as [(num_bits - 1):0] and repeats all the way down. template -static constexpr IntType Replicate(IntType val, u32 numBits, u32 toBit) { - if (numBits == 0) { - return 0; - } - if (toBit == 0) { +constexpr IntType Replicate(IntType val, u32 num_bits, u32 to_bit) { + if (num_bits == 0 || to_bit == 0) { return 0; } - const IntType v = val & static_cast((1 << numBits) - 1); + const IntType v = val & static_cast((1 << num_bits) - 1); IntType res = v; - u32 reslen = numBits; - while (reslen < toBit) { + u32 reslen = num_bits; + while (reslen < to_bit) { u32 comp = 0; - if (numBits > toBit - reslen) { - u32 newshift = toBit - reslen; - comp = numBits - newshift; - numBits = newshift; + if (num_bits > to_bit - reslen) { + u32 newshift = to_bit - reslen; + comp = num_bits - newshift; + num_bits = newshift; } - res = static_cast(res << numBits); + res = static_cast(res << num_bits); res = static_cast(res | (v >> comp)); - reslen += numBits; + reslen += num_bits; } return res; } -static constexpr std::size_t NumReplicateEntries(u32 num_bits) { +constexpr std::size_t NumReplicateEntries(u32 num_bits) { return std::size_t(1) << num_bits; } template -static constexpr auto MakeReplicateTable() { +constexpr auto MakeReplicateTable() { std::array table{}; for (IntType value = 0; value < static_cast(std::size(table)); ++value) { table[value] = Replicate(value, num_bits, to_bit); @@ -127,78 +116,17 @@ static constexpr auto MakeReplicateTable() { return table; } -static constexpr auto REPLICATE_BYTE_TO_16_TABLE = MakeReplicateTable(); -static constexpr u32 ReplicateByteTo16(std::size_t value) { - return REPLICATE_BYTE_TO_16_TABLE[value]; -} - -static constexpr auto REPLICATE_BIT_TO_7_TABLE = MakeReplicateTable(); -static constexpr u32 ReplicateBitTo7(std::size_t value) { - return REPLICATE_BIT_TO_7_TABLE[value]; -} - -static constexpr auto REPLICATE_BIT_TO_9_TABLE = MakeReplicateTable(); -static constexpr u32 ReplicateBitTo9(std::size_t value) { - return REPLICATE_BIT_TO_9_TABLE[value]; -} - -static constexpr auto REPLICATE_1_BIT_TO_8_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_2_BIT_TO_8_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_3_BIT_TO_8_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_4_BIT_TO_8_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_5_BIT_TO_8_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_6_BIT_TO_8_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_7_BIT_TO_8_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_8_BIT_TO_8_TABLE = MakeReplicateTable(); -/// Use a precompiled table with the most common usages, if it's not in the expected range, fallback -/// to the runtime implementation -static constexpr u32 FastReplicateTo8(u32 value, u32 num_bits) { - switch (num_bits) { - case 1: - return REPLICATE_1_BIT_TO_8_TABLE[value]; - case 2: - return REPLICATE_2_BIT_TO_8_TABLE[value]; - case 3: - return REPLICATE_3_BIT_TO_8_TABLE[value]; - case 4: - return REPLICATE_4_BIT_TO_8_TABLE[value]; - case 5: - return REPLICATE_5_BIT_TO_8_TABLE[value]; - case 6: - return REPLICATE_6_BIT_TO_8_TABLE[value]; - case 7: - return REPLICATE_7_BIT_TO_8_TABLE[value]; - case 8: - return REPLICATE_8_BIT_TO_8_TABLE[value]; - default: - return Replicate(value, num_bits, 8); - } -} - -static constexpr auto REPLICATE_1_BIT_TO_6_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_2_BIT_TO_6_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_3_BIT_TO_6_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_4_BIT_TO_6_TABLE = MakeReplicateTable(); -static constexpr auto REPLICATE_5_BIT_TO_6_TABLE = MakeReplicateTable(); - -static constexpr u32 FastReplicateTo6(u32 value, u32 num_bits) { - switch (num_bits) { - case 1: - return REPLICATE_1_BIT_TO_6_TABLE[value]; - case 2: - return REPLICATE_2_BIT_TO_6_TABLE[value]; - case 3: - return REPLICATE_3_BIT_TO_6_TABLE[value]; - case 4: - return REPLICATE_4_BIT_TO_6_TABLE[value]; - case 5: - return REPLICATE_5_BIT_TO_6_TABLE[value]; - default: - return Replicate(value, num_bits, 6); - } -} - -void Decompress(std::span data, uint32_t width, uint32_t height, uint32_t depth, - uint32_t block_width, uint32_t block_height, std::span output); +constexpr auto REPLICATE_BYTE_TO_16_TABLE = MakeReplicateTable(); +constexpr auto REPLICATE_6_BIT_TO_8_TABLE = MakeReplicateTable(); +constexpr auto REPLICATE_7_BIT_TO_8_TABLE = MakeReplicateTable(); +constexpr auto REPLICATE_8_BIT_TO_8_TABLE = MakeReplicateTable(); + +struct AstcBufferData { + decltype(EncodingsValues) encoding_values = EncodingsValues; + decltype(REPLICATE_6_BIT_TO_8_TABLE) replicate_6_to_8 = REPLICATE_6_BIT_TO_8_TABLE; + decltype(REPLICATE_7_BIT_TO_8_TABLE) replicate_7_to_8 = REPLICATE_7_BIT_TO_8_TABLE; + decltype(REPLICATE_8_BIT_TO_8_TABLE) replicate_8_to_8 = REPLICATE_8_BIT_TO_8_TABLE; + decltype(REPLICATE_BYTE_TO_16_TABLE) replicate_byte_to_16 = REPLICATE_BYTE_TO_16_TABLE; +} constexpr ASTC_BUFFER_DATA; } // namespace Tegra::Texture::ASTC -- cgit v1.2.3