astc.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright 2018 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <bit>
  6. #include "common/common_types.h"
  7. namespace Tegra::Texture::ASTC {
  8. enum class IntegerEncoding { JustBits, Quint, Trit };
  9. struct IntegerEncodedValue {
  10. constexpr IntegerEncodedValue() = default;
  11. constexpr IntegerEncodedValue(IntegerEncoding encoding_, u32 num_bits_)
  12. : encoding{encoding_}, num_bits{num_bits_} {}
  13. constexpr bool MatchesEncoding(const IntegerEncodedValue& other) const {
  14. return encoding == other.encoding && num_bits == other.num_bits;
  15. }
  16. // Returns the number of bits required to encode num_vals values.
  17. u32 GetBitLength(u32 num_vals) const {
  18. u32 total_bits = num_bits * num_vals;
  19. if (encoding == IntegerEncoding::Trit) {
  20. total_bits += (num_vals * 8 + 4) / 5;
  21. } else if (encoding == IntegerEncoding::Quint) {
  22. total_bits += (num_vals * 7 + 2) / 3;
  23. }
  24. return total_bits;
  25. }
  26. IntegerEncoding encoding{};
  27. u32 num_bits = 0;
  28. u32 bit_value = 0;
  29. union {
  30. u32 quint_value = 0;
  31. u32 trit_value;
  32. };
  33. };
  34. // Returns a new instance of this struct that corresponds to the
  35. // can take no more than mav_value values
  36. constexpr IntegerEncodedValue CreateEncoding(u32 mav_value) {
  37. while (mav_value > 0) {
  38. u32 check = mav_value + 1;
  39. // Is mav_value a power of two?
  40. if (!(check & (check - 1))) {
  41. return IntegerEncodedValue(IntegerEncoding::JustBits, std::popcount(mav_value));
  42. }
  43. // Is mav_value of the type 3*2^n - 1?
  44. if ((check % 3 == 0) && !((check / 3) & ((check / 3) - 1))) {
  45. return IntegerEncodedValue(IntegerEncoding::Trit, std::popcount(check / 3 - 1));
  46. }
  47. // Is mav_value of the type 5*2^n - 1?
  48. if ((check % 5 == 0) && !((check / 5) & ((check / 5) - 1))) {
  49. return IntegerEncodedValue(IntegerEncoding::Quint, std::popcount(check / 5 - 1));
  50. }
  51. // Apparently it can't be represented with a bounded integer sequence...
  52. // just iterate.
  53. mav_value--;
  54. }
  55. return IntegerEncodedValue(IntegerEncoding::JustBits, 0);
  56. }
  57. constexpr std::array<IntegerEncodedValue, 256> MakeEncodedValues() {
  58. std::array<IntegerEncodedValue, 256> encodings{};
  59. for (std::size_t i = 0; i < encodings.size(); ++i) {
  60. encodings[i] = CreateEncoding(static_cast<u32>(i));
  61. }
  62. return encodings;
  63. }
  64. constexpr std::array<IntegerEncodedValue, 256> EncodingsValues = MakeEncodedValues();
  65. // Replicates low num_bits such that [(to_bit - 1):(to_bit - 1 - from_bit)]
  66. // is the same as [(num_bits - 1):0] and repeats all the way down.
  67. template <typename IntType>
  68. constexpr IntType Replicate(IntType val, u32 num_bits, u32 to_bit) {
  69. if (num_bits == 0 || to_bit == 0) {
  70. return 0;
  71. }
  72. const IntType v = val & static_cast<IntType>((1 << num_bits) - 1);
  73. IntType res = v;
  74. u32 reslen = num_bits;
  75. while (reslen < to_bit) {
  76. u32 comp = 0;
  77. if (num_bits > to_bit - reslen) {
  78. u32 newshift = to_bit - reslen;
  79. comp = num_bits - newshift;
  80. num_bits = newshift;
  81. }
  82. res = static_cast<IntType>(res << num_bits);
  83. res = static_cast<IntType>(res | (v >> comp));
  84. reslen += num_bits;
  85. }
  86. return res;
  87. }
  88. constexpr std::size_t NumReplicateEntries(u32 num_bits) {
  89. return std::size_t(1) << num_bits;
  90. }
  91. template <typename IntType, u32 num_bits, u32 to_bit>
  92. constexpr auto MakeReplicateTable() {
  93. std::array<IntType, NumReplicateEntries(num_bits)> table{};
  94. for (IntType value = 0; value < static_cast<IntType>(std::size(table)); ++value) {
  95. table[value] = Replicate(value, num_bits, to_bit);
  96. }
  97. return table;
  98. }
  99. constexpr auto REPLICATE_6_BIT_TO_8_TABLE = MakeReplicateTable<u32, 6, 8>();
  100. constexpr auto REPLICATE_7_BIT_TO_8_TABLE = MakeReplicateTable<u32, 7, 8>();
  101. constexpr auto REPLICATE_8_BIT_TO_8_TABLE = MakeReplicateTable<u32, 8, 8>();
  102. struct AstcBufferData {
  103. decltype(EncodingsValues) encoding_values = EncodingsValues;
  104. decltype(REPLICATE_6_BIT_TO_8_TABLE) replicate_6_to_8 = REPLICATE_6_BIT_TO_8_TABLE;
  105. decltype(REPLICATE_7_BIT_TO_8_TABLE) replicate_7_to_8 = REPLICATE_7_BIT_TO_8_TABLE;
  106. decltype(REPLICATE_8_BIT_TO_8_TABLE) replicate_8_to_8 = REPLICATE_8_BIT_TO_8_TABLE;
  107. } constexpr ASTC_BUFFER_DATA;
  108. void Decompress(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth,
  109. uint32_t block_width, uint32_t block_height, std::span<uint8_t> output);
  110. } // namespace Tegra::Texture::ASTC