astc.cpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689
  1. // Copyright 2016 The University of North Carolina at Chapel Hill
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // Please send all BUG REPORTS to <pavel@cs.unc.edu>.
  16. // <http://gamma.cs.unc.edu/FasTC/>
  17. #include <algorithm>
  18. #include <cassert>
  19. #include <cstring>
  20. #include <span>
  21. #include <vector>
  22. #include <boost/container/static_vector.hpp>
  23. #include "common/common_types.h"
  24. #include "video_core/textures/astc.h"
  25. class InputBitStream {
  26. public:
  27. constexpr explicit InputBitStream(std::span<const u8> data, size_t start_offset = 0)
  28. : cur_byte{data.data()}, total_bits{data.size()}, next_bit{start_offset % 8} {}
  29. constexpr size_t GetBitsRead() const {
  30. return bits_read;
  31. }
  32. constexpr bool ReadBit() {
  33. if (bits_read >= total_bits * 8) {
  34. return 0;
  35. }
  36. const bool bit = ((*cur_byte >> next_bit) & 1) != 0;
  37. ++next_bit;
  38. while (next_bit >= 8) {
  39. next_bit -= 8;
  40. ++cur_byte;
  41. }
  42. ++bits_read;
  43. return bit;
  44. }
  45. constexpr u32 ReadBits(std::size_t nBits) {
  46. u32 ret = 0;
  47. for (std::size_t i = 0; i < nBits; ++i) {
  48. ret |= (ReadBit() & 1) << i;
  49. }
  50. return ret;
  51. }
  52. template <std::size_t nBits>
  53. constexpr u32 ReadBits() {
  54. u32 ret = 0;
  55. for (std::size_t i = 0; i < nBits; ++i) {
  56. ret |= (ReadBit() & 1) << i;
  57. }
  58. return ret;
  59. }
  60. private:
  61. const u8* cur_byte;
  62. size_t total_bits = 0;
  63. size_t next_bit = 0;
  64. size_t bits_read = 0;
  65. };
  66. class OutputBitStream {
  67. public:
  68. constexpr explicit OutputBitStream(u8* ptr, std::size_t bits = 0, std::size_t start_offset = 0)
  69. : cur_byte{ptr}, num_bits{bits}, next_bit{start_offset % 8} {}
  70. constexpr std::size_t GetBitsWritten() const {
  71. return bits_written;
  72. }
  73. constexpr void WriteBitsR(u32 val, u32 nBits) {
  74. for (u32 i = 0; i < nBits; i++) {
  75. WriteBit((val >> (nBits - i - 1)) & 1);
  76. }
  77. }
  78. constexpr void WriteBits(u32 val, u32 nBits) {
  79. for (u32 i = 0; i < nBits; i++) {
  80. WriteBit((val >> i) & 1);
  81. }
  82. }
  83. private:
  84. constexpr void WriteBit(bool b) {
  85. if (bits_written >= num_bits) {
  86. return;
  87. }
  88. const u32 mask = 1 << next_bit++;
  89. // clear the bit
  90. *cur_byte &= static_cast<u8>(~mask);
  91. // Write the bit, if necessary
  92. if (b)
  93. *cur_byte |= static_cast<u8>(mask);
  94. // Next byte?
  95. if (next_bit >= 8) {
  96. cur_byte += 1;
  97. next_bit = 0;
  98. }
  99. }
  100. u8* cur_byte;
  101. std::size_t num_bits;
  102. std::size_t bits_written = 0;
  103. std::size_t next_bit = 0;
  104. };
  105. template <typename IntType>
  106. class Bits {
  107. public:
  108. explicit Bits(const IntType& v) : m_Bits(v) {}
  109. Bits(const Bits&) = delete;
  110. Bits& operator=(const Bits&) = delete;
  111. u8 operator[](u32 bitPos) const {
  112. return static_cast<u8>((m_Bits >> bitPos) & 1);
  113. }
  114. IntType operator()(u32 start, u32 end) const {
  115. if (start == end) {
  116. return (*this)[start];
  117. } else if (start > end) {
  118. u32 t = start;
  119. start = end;
  120. end = t;
  121. }
  122. u64 mask = (1 << (end - start + 1)) - 1;
  123. return (m_Bits >> start) & static_cast<IntType>(mask);
  124. }
  125. private:
  126. const IntType& m_Bits;
  127. };
  128. enum class IntegerEncoding { JustBits, Quint, Trit };
  129. struct IntegerEncodedValue {
  130. constexpr IntegerEncodedValue() = default;
  131. constexpr IntegerEncodedValue(IntegerEncoding encoding_, u32 num_bits_)
  132. : encoding{encoding_}, num_bits{num_bits_} {}
  133. constexpr bool MatchesEncoding(const IntegerEncodedValue& other) const {
  134. return encoding == other.encoding && num_bits == other.num_bits;
  135. }
  136. // Returns the number of bits required to encode num_vals values.
  137. u32 GetBitLength(u32 num_vals) const {
  138. u32 total_bits = num_bits * num_vals;
  139. if (encoding == IntegerEncoding::Trit) {
  140. total_bits += (num_vals * 8 + 4) / 5;
  141. } else if (encoding == IntegerEncoding::Quint) {
  142. total_bits += (num_vals * 7 + 2) / 3;
  143. }
  144. return total_bits;
  145. }
  146. IntegerEncoding encoding{};
  147. u32 num_bits = 0;
  148. u32 bit_value = 0;
  149. union {
  150. u32 quint_value = 0;
  151. u32 trit_value;
  152. };
  153. };
  154. // Returns a new instance of this struct that corresponds to the
  155. // can take no more than mav_value values
  156. static constexpr IntegerEncodedValue CreateEncoding(u32 mav_value) {
  157. while (mav_value > 0) {
  158. u32 check = mav_value + 1;
  159. // Is mav_value a power of two?
  160. if (!(check & (check - 1))) {
  161. return IntegerEncodedValue(IntegerEncoding::JustBits, std::popcount(mav_value));
  162. }
  163. // Is mav_value of the type 3*2^n - 1?
  164. if ((check % 3 == 0) && !((check / 3) & ((check / 3) - 1))) {
  165. return IntegerEncodedValue(IntegerEncoding::Trit, std::popcount(check / 3 - 1));
  166. }
  167. // Is mav_value of the type 5*2^n - 1?
  168. if ((check % 5 == 0) && !((check / 5) & ((check / 5) - 1))) {
  169. return IntegerEncodedValue(IntegerEncoding::Quint, std::popcount(check / 5 - 1));
  170. }
  171. // Apparently it can't be represented with a bounded integer sequence...
  172. // just iterate.
  173. mav_value--;
  174. }
  175. return IntegerEncodedValue(IntegerEncoding::JustBits, 0);
  176. }
  177. static constexpr std::array<IntegerEncodedValue, 256> MakeEncodedValues() {
  178. std::array<IntegerEncodedValue, 256> encodings{};
  179. for (std::size_t i = 0; i < encodings.size(); ++i) {
  180. encodings[i] = CreateEncoding(static_cast<u32>(i));
  181. }
  182. return encodings;
  183. }
  184. static constexpr std::array<IntegerEncodedValue, 256> ASTC_ENCODINGS_VALUES = MakeEncodedValues();
  185. namespace Tegra::Texture::ASTC {
  186. using IntegerEncodedVector = boost::container::static_vector<
  187. IntegerEncodedValue, 256,
  188. boost::container::static_vector_options<
  189. boost::container::inplace_alignment<alignof(IntegerEncodedValue)>,
  190. boost::container::throw_on_overflow<false>>::type>;
  191. static void DecodeTritBlock(InputBitStream& bits, IntegerEncodedVector& result, u32 nBitsPerValue) {
  192. // Implement the algorithm in section C.2.12
  193. std::array<u32, 5> m;
  194. std::array<u32, 5> t;
  195. u32 T;
  196. // Read the trit encoded block according to
  197. // table C.2.14
  198. m[0] = bits.ReadBits(nBitsPerValue);
  199. T = bits.ReadBits<2>();
  200. m[1] = bits.ReadBits(nBitsPerValue);
  201. T |= bits.ReadBits<2>() << 2;
  202. m[2] = bits.ReadBits(nBitsPerValue);
  203. T |= bits.ReadBit() << 4;
  204. m[3] = bits.ReadBits(nBitsPerValue);
  205. T |= bits.ReadBits<2>() << 5;
  206. m[4] = bits.ReadBits(nBitsPerValue);
  207. T |= bits.ReadBit() << 7;
  208. u32 C = 0;
  209. Bits<u32> Tb(T);
  210. if (Tb(2, 4) == 7) {
  211. C = (Tb(5, 7) << 2) | Tb(0, 1);
  212. t[4] = t[3] = 2;
  213. } else {
  214. C = Tb(0, 4);
  215. if (Tb(5, 6) == 3) {
  216. t[4] = 2;
  217. t[3] = Tb[7];
  218. } else {
  219. t[4] = Tb[7];
  220. t[3] = Tb(5, 6);
  221. }
  222. }
  223. Bits<u32> Cb(C);
  224. if (Cb(0, 1) == 3) {
  225. t[2] = 2;
  226. t[1] = Cb[4];
  227. t[0] = (Cb[3] << 1) | (Cb[2] & ~Cb[3]);
  228. } else if (Cb(2, 3) == 3) {
  229. t[2] = 2;
  230. t[1] = 2;
  231. t[0] = Cb(0, 1);
  232. } else {
  233. t[2] = Cb[4];
  234. t[1] = Cb(2, 3);
  235. t[0] = (Cb[1] << 1) | (Cb[0] & ~Cb[1]);
  236. }
  237. for (std::size_t i = 0; i < 5; ++i) {
  238. IntegerEncodedValue& val = result.emplace_back(IntegerEncoding::Trit, nBitsPerValue);
  239. val.bit_value = m[i];
  240. val.trit_value = t[i];
  241. }
  242. }
  243. static void DecodeQuintBlock(InputBitStream& bits, IntegerEncodedVector& result,
  244. u32 nBitsPerValue) {
  245. // Implement the algorithm in section C.2.12
  246. u32 m[3];
  247. u32 q[3];
  248. u32 Q;
  249. // Read the trit encoded block according to
  250. // table C.2.15
  251. m[0] = bits.ReadBits(nBitsPerValue);
  252. Q = bits.ReadBits<3>();
  253. m[1] = bits.ReadBits(nBitsPerValue);
  254. Q |= bits.ReadBits<2>() << 3;
  255. m[2] = bits.ReadBits(nBitsPerValue);
  256. Q |= bits.ReadBits<2>() << 5;
  257. Bits<u32> Qb(Q);
  258. if (Qb(1, 2) == 3 && Qb(5, 6) == 0) {
  259. q[0] = q[1] = 4;
  260. q[2] = (Qb[0] << 2) | ((Qb[4] & ~Qb[0]) << 1) | (Qb[3] & ~Qb[0]);
  261. } else {
  262. u32 C = 0;
  263. if (Qb(1, 2) == 3) {
  264. q[2] = 4;
  265. C = (Qb(3, 4) << 3) | ((~Qb(5, 6) & 3) << 1) | Qb[0];
  266. } else {
  267. q[2] = Qb(5, 6);
  268. C = Qb(0, 4);
  269. }
  270. Bits<u32> Cb(C);
  271. if (Cb(0, 2) == 5) {
  272. q[1] = 4;
  273. q[0] = Cb(3, 4);
  274. } else {
  275. q[1] = Cb(3, 4);
  276. q[0] = Cb(0, 2);
  277. }
  278. }
  279. for (std::size_t i = 0; i < 3; ++i) {
  280. IntegerEncodedValue& val = result.emplace_back(IntegerEncoding::Quint, nBitsPerValue);
  281. val.bit_value = m[i];
  282. val.quint_value = q[i];
  283. }
  284. }
  285. // Fills result with the values that are encoded in the given
  286. // bitstream. We must know beforehand what the maximum possible
  287. // value is, and how many values we're decoding.
  288. static void DecodeIntegerSequence(IntegerEncodedVector& result, InputBitStream& bits, u32 maxRange,
  289. u32 nValues) {
  290. // Determine encoding parameters
  291. IntegerEncodedValue val = ASTC_ENCODINGS_VALUES[maxRange];
  292. // Start decoding
  293. u32 nValsDecoded = 0;
  294. while (nValsDecoded < nValues) {
  295. switch (val.encoding) {
  296. case IntegerEncoding::Quint:
  297. DecodeQuintBlock(bits, result, val.num_bits);
  298. nValsDecoded += 3;
  299. break;
  300. case IntegerEncoding::Trit:
  301. DecodeTritBlock(bits, result, val.num_bits);
  302. nValsDecoded += 5;
  303. break;
  304. case IntegerEncoding::JustBits:
  305. val.bit_value = bits.ReadBits(val.num_bits);
  306. result.push_back(val);
  307. nValsDecoded++;
  308. break;
  309. }
  310. }
  311. }
  312. struct TexelWeightParams {
  313. u32 m_Width = 0;
  314. u32 m_Height = 0;
  315. bool m_bDualPlane = false;
  316. u32 m_MaxWeight = 0;
  317. bool m_bError = false;
  318. bool m_bVoidExtentLDR = false;
  319. bool m_bVoidExtentHDR = false;
  320. u32 GetPackedBitSize() const {
  321. // How many indices do we have?
  322. u32 nIdxs = m_Height * m_Width;
  323. if (m_bDualPlane) {
  324. nIdxs *= 2;
  325. }
  326. return ASTC_ENCODINGS_VALUES[m_MaxWeight].GetBitLength(nIdxs);
  327. }
  328. u32 GetNumWeightValues() const {
  329. u32 ret = m_Width * m_Height;
  330. if (m_bDualPlane) {
  331. ret *= 2;
  332. }
  333. return ret;
  334. }
  335. };
  336. static TexelWeightParams DecodeBlockInfo(InputBitStream& strm) {
  337. TexelWeightParams params;
  338. // Read the entire block mode all at once
  339. u16 modeBits = static_cast<u16>(strm.ReadBits<11>());
  340. // Does this match the void extent block mode?
  341. if ((modeBits & 0x01FF) == 0x1FC) {
  342. if (modeBits & 0x200) {
  343. params.m_bVoidExtentHDR = true;
  344. } else {
  345. params.m_bVoidExtentLDR = true;
  346. }
  347. // Next two bits must be one.
  348. if (!(modeBits & 0x400) || !strm.ReadBit()) {
  349. params.m_bError = true;
  350. }
  351. return params;
  352. }
  353. // First check if the last four bits are zero
  354. if ((modeBits & 0xF) == 0) {
  355. params.m_bError = true;
  356. return params;
  357. }
  358. // If the last two bits are zero, then if bits
  359. // [6-8] are all ones, this is also reserved.
  360. if ((modeBits & 0x3) == 0 && (modeBits & 0x1C0) == 0x1C0) {
  361. params.m_bError = true;
  362. return params;
  363. }
  364. // Otherwise, there is no error... Figure out the layout
  365. // of the block mode. Layout is determined by a number
  366. // between 0 and 9 corresponding to table C.2.8 of the
  367. // ASTC spec.
  368. u32 layout = 0;
  369. if ((modeBits & 0x1) || (modeBits & 0x2)) {
  370. // layout is in [0-4]
  371. if (modeBits & 0x8) {
  372. // layout is in [2-4]
  373. if (modeBits & 0x4) {
  374. // layout is in [3-4]
  375. if (modeBits & 0x100) {
  376. layout = 4;
  377. } else {
  378. layout = 3;
  379. }
  380. } else {
  381. layout = 2;
  382. }
  383. } else {
  384. // layout is in [0-1]
  385. if (modeBits & 0x4) {
  386. layout = 1;
  387. } else {
  388. layout = 0;
  389. }
  390. }
  391. } else {
  392. // layout is in [5-9]
  393. if (modeBits & 0x100) {
  394. // layout is in [7-9]
  395. if (modeBits & 0x80) {
  396. // layout is in [7-8]
  397. assert((modeBits & 0x40) == 0U);
  398. if (modeBits & 0x20) {
  399. layout = 8;
  400. } else {
  401. layout = 7;
  402. }
  403. } else {
  404. layout = 9;
  405. }
  406. } else {
  407. // layout is in [5-6]
  408. if (modeBits & 0x80) {
  409. layout = 6;
  410. } else {
  411. layout = 5;
  412. }
  413. }
  414. }
  415. assert(layout < 10);
  416. // Determine R
  417. u32 R = !!(modeBits & 0x10);
  418. if (layout < 5) {
  419. R |= (modeBits & 0x3) << 1;
  420. } else {
  421. R |= (modeBits & 0xC) >> 1;
  422. }
  423. assert(2 <= R && R <= 7);
  424. // Determine width & height
  425. switch (layout) {
  426. case 0: {
  427. u32 A = (modeBits >> 5) & 0x3;
  428. u32 B = (modeBits >> 7) & 0x3;
  429. params.m_Width = B + 4;
  430. params.m_Height = A + 2;
  431. break;
  432. }
  433. case 1: {
  434. u32 A = (modeBits >> 5) & 0x3;
  435. u32 B = (modeBits >> 7) & 0x3;
  436. params.m_Width = B + 8;
  437. params.m_Height = A + 2;
  438. break;
  439. }
  440. case 2: {
  441. u32 A = (modeBits >> 5) & 0x3;
  442. u32 B = (modeBits >> 7) & 0x3;
  443. params.m_Width = A + 2;
  444. params.m_Height = B + 8;
  445. break;
  446. }
  447. case 3: {
  448. u32 A = (modeBits >> 5) & 0x3;
  449. u32 B = (modeBits >> 7) & 0x1;
  450. params.m_Width = A + 2;
  451. params.m_Height = B + 6;
  452. break;
  453. }
  454. case 4: {
  455. u32 A = (modeBits >> 5) & 0x3;
  456. u32 B = (modeBits >> 7) & 0x1;
  457. params.m_Width = B + 2;
  458. params.m_Height = A + 2;
  459. break;
  460. }
  461. case 5: {
  462. u32 A = (modeBits >> 5) & 0x3;
  463. params.m_Width = 12;
  464. params.m_Height = A + 2;
  465. break;
  466. }
  467. case 6: {
  468. u32 A = (modeBits >> 5) & 0x3;
  469. params.m_Width = A + 2;
  470. params.m_Height = 12;
  471. break;
  472. }
  473. case 7: {
  474. params.m_Width = 6;
  475. params.m_Height = 10;
  476. break;
  477. }
  478. case 8: {
  479. params.m_Width = 10;
  480. params.m_Height = 6;
  481. break;
  482. }
  483. case 9: {
  484. u32 A = (modeBits >> 5) & 0x3;
  485. u32 B = (modeBits >> 9) & 0x3;
  486. params.m_Width = A + 6;
  487. params.m_Height = B + 6;
  488. break;
  489. }
  490. default:
  491. assert(false && "Don't know this layout...");
  492. params.m_bError = true;
  493. break;
  494. }
  495. // Determine whether or not we're using dual planes
  496. // and/or high precision layouts.
  497. bool D = (layout != 9) && (modeBits & 0x400);
  498. bool H = (layout != 9) && (modeBits & 0x200);
  499. if (H) {
  500. const u32 maxWeights[6] = {9, 11, 15, 19, 23, 31};
  501. params.m_MaxWeight = maxWeights[R - 2];
  502. } else {
  503. const u32 maxWeights[6] = {1, 2, 3, 4, 5, 7};
  504. params.m_MaxWeight = maxWeights[R - 2];
  505. }
  506. params.m_bDualPlane = D;
  507. return params;
  508. }
  509. // Replicates low num_bits such that [(to_bit - 1):(to_bit - 1 - from_bit)]
  510. // is the same as [(num_bits - 1):0] and repeats all the way down.
  511. template <typename IntType>
  512. static constexpr IntType Replicate(IntType val, u32 num_bits, u32 to_bit) {
  513. if (num_bits == 0 || to_bit == 0) {
  514. return 0;
  515. }
  516. const IntType v = val & static_cast<IntType>((1 << num_bits) - 1);
  517. IntType res = v;
  518. u32 reslen = num_bits;
  519. while (reslen < to_bit) {
  520. u32 comp = 0;
  521. if (num_bits > to_bit - reslen) {
  522. u32 newshift = to_bit - reslen;
  523. comp = num_bits - newshift;
  524. num_bits = newshift;
  525. }
  526. res = static_cast<IntType>(res << num_bits);
  527. res = static_cast<IntType>(res | (v >> comp));
  528. reslen += num_bits;
  529. }
  530. return res;
  531. }
  532. static constexpr std::size_t NumReplicateEntries(u32 num_bits) {
  533. return std::size_t(1) << num_bits;
  534. }
  535. template <typename IntType, u32 num_bits, u32 to_bit>
  536. static constexpr auto MakeReplicateTable() {
  537. std::array<IntType, NumReplicateEntries(num_bits)> table{};
  538. for (IntType value = 0; value < static_cast<IntType>(std::size(table)); ++value) {
  539. table[value] = Replicate(value, num_bits, to_bit);
  540. }
  541. return table;
  542. }
  543. static constexpr auto REPLICATE_BYTE_TO_16_TABLE = MakeReplicateTable<u32, 8, 16>();
  544. static constexpr u32 ReplicateByteTo16(std::size_t value) {
  545. return REPLICATE_BYTE_TO_16_TABLE[value];
  546. }
  547. static constexpr auto REPLICATE_BIT_TO_7_TABLE = MakeReplicateTable<u32, 1, 7>();
  548. static constexpr u32 ReplicateBitTo7(std::size_t value) {
  549. return REPLICATE_BIT_TO_7_TABLE[value];
  550. }
  551. static constexpr auto REPLICATE_BIT_TO_9_TABLE = MakeReplicateTable<u32, 1, 9>();
  552. static constexpr u32 ReplicateBitTo9(std::size_t value) {
  553. return REPLICATE_BIT_TO_9_TABLE[value];
  554. }
  555. static constexpr auto REPLICATE_1_BIT_TO_8_TABLE = MakeReplicateTable<u32, 1, 8>();
  556. static constexpr auto REPLICATE_2_BIT_TO_8_TABLE = MakeReplicateTable<u32, 2, 8>();
  557. static constexpr auto REPLICATE_3_BIT_TO_8_TABLE = MakeReplicateTable<u32, 3, 8>();
  558. static constexpr auto REPLICATE_4_BIT_TO_8_TABLE = MakeReplicateTable<u32, 4, 8>();
  559. static constexpr auto REPLICATE_5_BIT_TO_8_TABLE = MakeReplicateTable<u32, 5, 8>();
  560. static constexpr auto REPLICATE_6_BIT_TO_8_TABLE = MakeReplicateTable<u32, 6, 8>();
  561. static constexpr auto REPLICATE_7_BIT_TO_8_TABLE = MakeReplicateTable<u32, 7, 8>();
  562. static constexpr auto REPLICATE_8_BIT_TO_8_TABLE = MakeReplicateTable<u32, 8, 8>();
  563. /// Use a precompiled table with the most common usages, if it's not in the expected range, fallback
  564. /// to the runtime implementation
  565. static constexpr u32 FastReplicateTo8(u32 value, u32 num_bits) {
  566. switch (num_bits) {
  567. case 1:
  568. return REPLICATE_1_BIT_TO_8_TABLE[value];
  569. case 2:
  570. return REPLICATE_2_BIT_TO_8_TABLE[value];
  571. case 3:
  572. return REPLICATE_3_BIT_TO_8_TABLE[value];
  573. case 4:
  574. return REPLICATE_4_BIT_TO_8_TABLE[value];
  575. case 5:
  576. return REPLICATE_5_BIT_TO_8_TABLE[value];
  577. case 6:
  578. return REPLICATE_6_BIT_TO_8_TABLE[value];
  579. case 7:
  580. return REPLICATE_7_BIT_TO_8_TABLE[value];
  581. case 8:
  582. return REPLICATE_8_BIT_TO_8_TABLE[value];
  583. default:
  584. return Replicate(value, num_bits, 8);
  585. }
  586. }
  587. static constexpr auto REPLICATE_1_BIT_TO_6_TABLE = MakeReplicateTable<u32, 1, 6>();
  588. static constexpr auto REPLICATE_2_BIT_TO_6_TABLE = MakeReplicateTable<u32, 2, 6>();
  589. static constexpr auto REPLICATE_3_BIT_TO_6_TABLE = MakeReplicateTable<u32, 3, 6>();
  590. static constexpr auto REPLICATE_4_BIT_TO_6_TABLE = MakeReplicateTable<u32, 4, 6>();
  591. static constexpr auto REPLICATE_5_BIT_TO_6_TABLE = MakeReplicateTable<u32, 5, 6>();
  592. static constexpr u32 FastReplicateTo6(u32 value, u32 num_bits) {
  593. switch (num_bits) {
  594. case 1:
  595. return REPLICATE_1_BIT_TO_6_TABLE[value];
  596. case 2:
  597. return REPLICATE_2_BIT_TO_6_TABLE[value];
  598. case 3:
  599. return REPLICATE_3_BIT_TO_6_TABLE[value];
  600. case 4:
  601. return REPLICATE_4_BIT_TO_6_TABLE[value];
  602. case 5:
  603. return REPLICATE_5_BIT_TO_6_TABLE[value];
  604. default:
  605. return Replicate(value, num_bits, 6);
  606. }
  607. }
  608. class Pixel {
  609. protected:
  610. using ChannelType = s16;
  611. u8 m_BitDepth[4] = {8, 8, 8, 8};
  612. s16 color[4] = {};
  613. public:
  614. Pixel() = default;
  615. Pixel(u32 a, u32 r, u32 g, u32 b, u32 bitDepth = 8)
  616. : m_BitDepth{u8(bitDepth), u8(bitDepth), u8(bitDepth), u8(bitDepth)},
  617. color{static_cast<ChannelType>(a), static_cast<ChannelType>(r),
  618. static_cast<ChannelType>(g), static_cast<ChannelType>(b)} {}
  619. // Changes the depth of each pixel. This scales the values to
  620. // the appropriate bit depth by either truncating the least
  621. // significant bits when going from larger to smaller bit depth
  622. // or by repeating the most significant bits when going from
  623. // smaller to larger bit depths.
  624. void ChangeBitDepth() {
  625. for (u32 i = 0; i < 4; i++) {
  626. Component(i) = ChangeBitDepth(Component(i), m_BitDepth[i]);
  627. m_BitDepth[i] = 8;
  628. }
  629. }
  630. template <typename IntType>
  631. static float ConvertChannelToFloat(IntType channel, u8 bitDepth) {
  632. float denominator = static_cast<float>((1 << bitDepth) - 1);
  633. return static_cast<float>(channel) / denominator;
  634. }
  635. // Changes the bit depth of a single component. See the comment
  636. // above for how we do this.
  637. static ChannelType ChangeBitDepth(Pixel::ChannelType val, u8 oldDepth) {
  638. assert(oldDepth <= 8);
  639. if (oldDepth == 8) {
  640. // Do nothing
  641. return val;
  642. } else if (oldDepth == 0) {
  643. return static_cast<ChannelType>((1 << 8) - 1);
  644. } else if (8 > oldDepth) {
  645. return static_cast<ChannelType>(FastReplicateTo8(static_cast<u32>(val), oldDepth));
  646. } else {
  647. // oldDepth > newDepth
  648. const u8 bitsWasted = static_cast<u8>(oldDepth - 8);
  649. u16 v = static_cast<u16>(val);
  650. v = static_cast<u16>((v + (1 << (bitsWasted - 1))) >> bitsWasted);
  651. v = ::std::min<u16>(::std::max<u16>(0, v), static_cast<u16>((1 << 8) - 1));
  652. return static_cast<u8>(v);
  653. }
  654. assert(false && "We shouldn't get here.");
  655. return 0;
  656. }
  657. const ChannelType& A() const {
  658. return color[0];
  659. }
  660. ChannelType& A() {
  661. return color[0];
  662. }
  663. const ChannelType& R() const {
  664. return color[1];
  665. }
  666. ChannelType& R() {
  667. return color[1];
  668. }
  669. const ChannelType& G() const {
  670. return color[2];
  671. }
  672. ChannelType& G() {
  673. return color[2];
  674. }
  675. const ChannelType& B() const {
  676. return color[3];
  677. }
  678. ChannelType& B() {
  679. return color[3];
  680. }
  681. const ChannelType& Component(u32 idx) const {
  682. return color[idx];
  683. }
  684. ChannelType& Component(u32 idx) {
  685. return color[idx];
  686. }
  687. void GetBitDepth(u8 (&outDepth)[4]) const {
  688. for (s32 i = 0; i < 4; i++) {
  689. outDepth[i] = m_BitDepth[i];
  690. }
  691. }
  692. // Take all of the components, transform them to their 8-bit variants,
  693. // and then pack each channel into an R8G8B8A8 32-bit integer. We assume
  694. // that the architecture is little-endian, so the alpha channel will end
  695. // up in the most-significant byte.
  696. u32 Pack() const {
  697. Pixel eightBit(*this);
  698. eightBit.ChangeBitDepth();
  699. u32 r = 0;
  700. r |= eightBit.A();
  701. r <<= 8;
  702. r |= eightBit.B();
  703. r <<= 8;
  704. r |= eightBit.G();
  705. r <<= 8;
  706. r |= eightBit.R();
  707. return r;
  708. }
  709. // Clamps the pixel to the range [0,255]
  710. void ClampByte() {
  711. for (u32 i = 0; i < 4; i++) {
  712. color[i] = (color[i] < 0) ? 0 : ((color[i] > 255) ? 255 : color[i]);
  713. }
  714. }
  715. void MakeOpaque() {
  716. A() = 255;
  717. }
  718. };
  719. static void DecodeColorValues(u32* out, std::span<u8> data, const u32* modes, const u32 nPartitions,
  720. const u32 nBitsForColorData) {
  721. // First figure out how many color values we have
  722. u32 nValues = 0;
  723. for (u32 i = 0; i < nPartitions; i++) {
  724. nValues += ((modes[i] >> 2) + 1) << 1;
  725. }
  726. // Then based on the number of values and the remaining number of bits,
  727. // figure out the max value for each of them...
  728. u32 range = 256;
  729. while (--range > 0) {
  730. IntegerEncodedValue val = ASTC_ENCODINGS_VALUES[range];
  731. u32 bitLength = val.GetBitLength(nValues);
  732. if (bitLength <= nBitsForColorData) {
  733. // Find the smallest possible range that matches the given encoding
  734. while (--range > 0) {
  735. IntegerEncodedValue newval = ASTC_ENCODINGS_VALUES[range];
  736. if (!newval.MatchesEncoding(val)) {
  737. break;
  738. }
  739. }
  740. // Return to last matching range.
  741. range++;
  742. break;
  743. }
  744. }
  745. // We now have enough to decode our integer sequence.
  746. IntegerEncodedVector decodedColorValues;
  747. InputBitStream colorStream(data, 0);
  748. DecodeIntegerSequence(decodedColorValues, colorStream, range, nValues);
  749. // Once we have the decoded values, we need to dequantize them to the 0-255 range
  750. // This procedure is outlined in ASTC spec C.2.13
  751. u32 outIdx = 0;
  752. for (auto itr = decodedColorValues.begin(); itr != decodedColorValues.end(); ++itr) {
  753. // Have we already decoded all that we need?
  754. if (outIdx >= nValues) {
  755. break;
  756. }
  757. const IntegerEncodedValue& val = *itr;
  758. u32 bitlen = val.num_bits;
  759. u32 bitval = val.bit_value;
  760. assert(bitlen >= 1);
  761. u32 A = 0, B = 0, C = 0, D = 0;
  762. // A is just the lsb replicated 9 times.
  763. A = ReplicateBitTo9(bitval & 1);
  764. switch (val.encoding) {
  765. // Replicate bits
  766. case IntegerEncoding::JustBits:
  767. out[outIdx++] = FastReplicateTo8(bitval, bitlen);
  768. break;
  769. // Use algorithm in C.2.13
  770. case IntegerEncoding::Trit: {
  771. D = val.trit_value;
  772. switch (bitlen) {
  773. case 1: {
  774. C = 204;
  775. } break;
  776. case 2: {
  777. C = 93;
  778. // B = b000b0bb0
  779. u32 b = (bitval >> 1) & 1;
  780. B = (b << 8) | (b << 4) | (b << 2) | (b << 1);
  781. } break;
  782. case 3: {
  783. C = 44;
  784. // B = cb000cbcb
  785. u32 cb = (bitval >> 1) & 3;
  786. B = (cb << 7) | (cb << 2) | cb;
  787. } break;
  788. case 4: {
  789. C = 22;
  790. // B = dcb000dcb
  791. u32 dcb = (bitval >> 1) & 7;
  792. B = (dcb << 6) | dcb;
  793. } break;
  794. case 5: {
  795. C = 11;
  796. // B = edcb000ed
  797. u32 edcb = (bitval >> 1) & 0xF;
  798. B = (edcb << 5) | (edcb >> 2);
  799. } break;
  800. case 6: {
  801. C = 5;
  802. // B = fedcb000f
  803. u32 fedcb = (bitval >> 1) & 0x1F;
  804. B = (fedcb << 4) | (fedcb >> 4);
  805. } break;
  806. default:
  807. assert(false && "Unsupported trit encoding for color values!");
  808. break;
  809. } // switch(bitlen)
  810. } // case IntegerEncoding::Trit
  811. break;
  812. case IntegerEncoding::Quint: {
  813. D = val.quint_value;
  814. switch (bitlen) {
  815. case 1: {
  816. C = 113;
  817. } break;
  818. case 2: {
  819. C = 54;
  820. // B = b0000bb00
  821. u32 b = (bitval >> 1) & 1;
  822. B = (b << 8) | (b << 3) | (b << 2);
  823. } break;
  824. case 3: {
  825. C = 26;
  826. // B = cb0000cbc
  827. u32 cb = (bitval >> 1) & 3;
  828. B = (cb << 7) | (cb << 1) | (cb >> 1);
  829. } break;
  830. case 4: {
  831. C = 13;
  832. // B = dcb0000dc
  833. u32 dcb = (bitval >> 1) & 7;
  834. B = (dcb << 6) | (dcb >> 1);
  835. } break;
  836. case 5: {
  837. C = 6;
  838. // B = edcb0000e
  839. u32 edcb = (bitval >> 1) & 0xF;
  840. B = (edcb << 5) | (edcb >> 3);
  841. } break;
  842. default:
  843. assert(false && "Unsupported quint encoding for color values!");
  844. break;
  845. } // switch(bitlen)
  846. } // case IntegerEncoding::Quint
  847. break;
  848. } // switch(val.encoding)
  849. if (val.encoding != IntegerEncoding::JustBits) {
  850. u32 T = D * C + B;
  851. T ^= A;
  852. T = (A & 0x80) | (T >> 2);
  853. out[outIdx++] = T;
  854. }
  855. }
  856. // Make sure that each of our values is in the proper range...
  857. for (u32 i = 0; i < nValues; i++) {
  858. assert(out[i] <= 255);
  859. }
  860. }
  861. static u32 UnquantizeTexelWeight(const IntegerEncodedValue& val) {
  862. u32 bitval = val.bit_value;
  863. u32 bitlen = val.num_bits;
  864. u32 A = ReplicateBitTo7(bitval & 1);
  865. u32 B = 0, C = 0, D = 0;
  866. u32 result = 0;
  867. switch (val.encoding) {
  868. case IntegerEncoding::JustBits:
  869. result = FastReplicateTo6(bitval, bitlen);
  870. break;
  871. case IntegerEncoding::Trit: {
  872. D = val.trit_value;
  873. assert(D < 3);
  874. switch (bitlen) {
  875. case 0: {
  876. u32 results[3] = {0, 32, 63};
  877. result = results[D];
  878. } break;
  879. case 1: {
  880. C = 50;
  881. } break;
  882. case 2: {
  883. C = 23;
  884. u32 b = (bitval >> 1) & 1;
  885. B = (b << 6) | (b << 2) | b;
  886. } break;
  887. case 3: {
  888. C = 11;
  889. u32 cb = (bitval >> 1) & 3;
  890. B = (cb << 5) | cb;
  891. } break;
  892. default:
  893. assert(false && "Invalid trit encoding for texel weight");
  894. break;
  895. }
  896. } break;
  897. case IntegerEncoding::Quint: {
  898. D = val.quint_value;
  899. assert(D < 5);
  900. switch (bitlen) {
  901. case 0: {
  902. u32 results[5] = {0, 16, 32, 47, 63};
  903. result = results[D];
  904. } break;
  905. case 1: {
  906. C = 28;
  907. } break;
  908. case 2: {
  909. C = 13;
  910. u32 b = (bitval >> 1) & 1;
  911. B = (b << 6) | (b << 1);
  912. } break;
  913. default:
  914. assert(false && "Invalid quint encoding for texel weight");
  915. break;
  916. }
  917. } break;
  918. }
  919. if (val.encoding != IntegerEncoding::JustBits && bitlen > 0) {
  920. // Decode the value...
  921. result = D * C + B;
  922. result ^= A;
  923. result = (A & 0x20) | (result >> 2);
  924. }
  925. assert(result < 64);
  926. // Change from [0,63] to [0,64]
  927. if (result > 32) {
  928. result += 1;
  929. }
  930. return result;
  931. }
  932. static void UnquantizeTexelWeights(u32 out[2][144], const IntegerEncodedVector& weights,
  933. const TexelWeightParams& params, const u32 blockWidth,
  934. const u32 blockHeight) {
  935. u32 weightIdx = 0;
  936. u32 unquantized[2][144];
  937. for (auto itr = weights.begin(); itr != weights.end(); ++itr) {
  938. unquantized[0][weightIdx] = UnquantizeTexelWeight(*itr);
  939. if (params.m_bDualPlane) {
  940. ++itr;
  941. unquantized[1][weightIdx] = UnquantizeTexelWeight(*itr);
  942. if (itr == weights.end()) {
  943. break;
  944. }
  945. }
  946. if (++weightIdx >= (params.m_Width * params.m_Height))
  947. break;
  948. }
  949. // Do infill if necessary (Section C.2.18) ...
  950. u32 Ds = (1024 + (blockWidth / 2)) / (blockWidth - 1);
  951. u32 Dt = (1024 + (blockHeight / 2)) / (blockHeight - 1);
  952. const u32 kPlaneScale = params.m_bDualPlane ? 2U : 1U;
  953. for (u32 plane = 0; plane < kPlaneScale; plane++)
  954. for (u32 t = 0; t < blockHeight; t++)
  955. for (u32 s = 0; s < blockWidth; s++) {
  956. u32 cs = Ds * s;
  957. u32 ct = Dt * t;
  958. u32 gs = (cs * (params.m_Width - 1) + 32) >> 6;
  959. u32 gt = (ct * (params.m_Height - 1) + 32) >> 6;
  960. u32 js = gs >> 4;
  961. u32 fs = gs & 0xF;
  962. u32 jt = gt >> 4;
  963. u32 ft = gt & 0x0F;
  964. u32 w11 = (fs * ft + 8) >> 4;
  965. u32 w10 = ft - w11;
  966. u32 w01 = fs - w11;
  967. u32 w00 = 16 - fs - ft + w11;
  968. u32 v0 = js + jt * params.m_Width;
  969. #define FIND_TEXEL(tidx, bidx) \
  970. u32 p##bidx = 0; \
  971. do { \
  972. if ((tidx) < (params.m_Width * params.m_Height)) { \
  973. p##bidx = unquantized[plane][(tidx)]; \
  974. } \
  975. } while (0)
  976. FIND_TEXEL(v0, 00);
  977. FIND_TEXEL(v0 + 1, 01);
  978. FIND_TEXEL(v0 + params.m_Width, 10);
  979. FIND_TEXEL(v0 + params.m_Width + 1, 11);
  980. #undef FIND_TEXEL
  981. out[plane][t * blockWidth + s] =
  982. (p00 * w00 + p01 * w01 + p10 * w10 + p11 * w11 + 8) >> 4;
  983. }
  984. }
  985. // Transfers a bit as described in C.2.14
  986. static inline void BitTransferSigned(int& a, int& b) {
  987. b >>= 1;
  988. b |= a & 0x80;
  989. a >>= 1;
  990. a &= 0x3F;
  991. if (a & 0x20)
  992. a -= 0x40;
  993. }
  994. // Adds more precision to the blue channel as described
  995. // in C.2.14
  996. static inline Pixel BlueContract(s32 a, s32 r, s32 g, s32 b) {
  997. return Pixel(static_cast<s16>(a), static_cast<s16>((r + b) >> 1),
  998. static_cast<s16>((g + b) >> 1), static_cast<s16>(b));
  999. }
  1000. // Partition selection functions as specified in
  1001. // C.2.21
  1002. static inline u32 hash52(u32 p) {
  1003. p ^= p >> 15;
  1004. p -= p << 17;
  1005. p += p << 7;
  1006. p += p << 4;
  1007. p ^= p >> 5;
  1008. p += p << 16;
  1009. p ^= p >> 7;
  1010. p ^= p >> 3;
  1011. p ^= p << 6;
  1012. p ^= p >> 17;
  1013. return p;
  1014. }
  1015. static u32 SelectPartition(s32 seed, s32 x, s32 y, s32 z, s32 partitionCount, s32 smallBlock) {
  1016. if (1 == partitionCount)
  1017. return 0;
  1018. if (smallBlock) {
  1019. x <<= 1;
  1020. y <<= 1;
  1021. z <<= 1;
  1022. }
  1023. seed += (partitionCount - 1) * 1024;
  1024. u32 rnum = hash52(static_cast<u32>(seed));
  1025. u8 seed1 = static_cast<u8>(rnum & 0xF);
  1026. u8 seed2 = static_cast<u8>((rnum >> 4) & 0xF);
  1027. u8 seed3 = static_cast<u8>((rnum >> 8) & 0xF);
  1028. u8 seed4 = static_cast<u8>((rnum >> 12) & 0xF);
  1029. u8 seed5 = static_cast<u8>((rnum >> 16) & 0xF);
  1030. u8 seed6 = static_cast<u8>((rnum >> 20) & 0xF);
  1031. u8 seed7 = static_cast<u8>((rnum >> 24) & 0xF);
  1032. u8 seed8 = static_cast<u8>((rnum >> 28) & 0xF);
  1033. u8 seed9 = static_cast<u8>((rnum >> 18) & 0xF);
  1034. u8 seed10 = static_cast<u8>((rnum >> 22) & 0xF);
  1035. u8 seed11 = static_cast<u8>((rnum >> 26) & 0xF);
  1036. u8 seed12 = static_cast<u8>(((rnum >> 30) | (rnum << 2)) & 0xF);
  1037. seed1 = static_cast<u8>(seed1 * seed1);
  1038. seed2 = static_cast<u8>(seed2 * seed2);
  1039. seed3 = static_cast<u8>(seed3 * seed3);
  1040. seed4 = static_cast<u8>(seed4 * seed4);
  1041. seed5 = static_cast<u8>(seed5 * seed5);
  1042. seed6 = static_cast<u8>(seed6 * seed6);
  1043. seed7 = static_cast<u8>(seed7 * seed7);
  1044. seed8 = static_cast<u8>(seed8 * seed8);
  1045. seed9 = static_cast<u8>(seed9 * seed9);
  1046. seed10 = static_cast<u8>(seed10 * seed10);
  1047. seed11 = static_cast<u8>(seed11 * seed11);
  1048. seed12 = static_cast<u8>(seed12 * seed12);
  1049. s32 sh1, sh2, sh3;
  1050. if (seed & 1) {
  1051. sh1 = (seed & 2) ? 4 : 5;
  1052. sh2 = (partitionCount == 3) ? 6 : 5;
  1053. } else {
  1054. sh1 = (partitionCount == 3) ? 6 : 5;
  1055. sh2 = (seed & 2) ? 4 : 5;
  1056. }
  1057. sh3 = (seed & 0x10) ? sh1 : sh2;
  1058. seed1 = static_cast<u8>(seed1 >> sh1);
  1059. seed2 = static_cast<u8>(seed2 >> sh2);
  1060. seed3 = static_cast<u8>(seed3 >> sh1);
  1061. seed4 = static_cast<u8>(seed4 >> sh2);
  1062. seed5 = static_cast<u8>(seed5 >> sh1);
  1063. seed6 = static_cast<u8>(seed6 >> sh2);
  1064. seed7 = static_cast<u8>(seed7 >> sh1);
  1065. seed8 = static_cast<u8>(seed8 >> sh2);
  1066. seed9 = static_cast<u8>(seed9 >> sh3);
  1067. seed10 = static_cast<u8>(seed10 >> sh3);
  1068. seed11 = static_cast<u8>(seed11 >> sh3);
  1069. seed12 = static_cast<u8>(seed12 >> sh3);
  1070. s32 a = seed1 * x + seed2 * y + seed11 * z + (rnum >> 14);
  1071. s32 b = seed3 * x + seed4 * y + seed12 * z + (rnum >> 10);
  1072. s32 c = seed5 * x + seed6 * y + seed9 * z + (rnum >> 6);
  1073. s32 d = seed7 * x + seed8 * y + seed10 * z + (rnum >> 2);
  1074. a &= 0x3F;
  1075. b &= 0x3F;
  1076. c &= 0x3F;
  1077. d &= 0x3F;
  1078. if (partitionCount < 4)
  1079. d = 0;
  1080. if (partitionCount < 3)
  1081. c = 0;
  1082. if (a >= b && a >= c && a >= d)
  1083. return 0;
  1084. else if (b >= c && b >= d)
  1085. return 1;
  1086. else if (c >= d)
  1087. return 2;
  1088. return 3;
  1089. }
  1090. static inline u32 Select2DPartition(s32 seed, s32 x, s32 y, s32 partitionCount, s32 smallBlock) {
  1091. return SelectPartition(seed, x, y, 0, partitionCount, smallBlock);
  1092. }
  1093. // Section C.2.14
  1094. static void ComputeEndpoints(Pixel& ep1, Pixel& ep2, const u32*& colorValues,
  1095. u32 colorEndpointMode) {
  1096. #define READ_UINT_VALUES(N) \
  1097. u32 v[N]; \
  1098. for (u32 i = 0; i < N; i++) { \
  1099. v[i] = *(colorValues++); \
  1100. }
  1101. #define READ_INT_VALUES(N) \
  1102. s32 v[N]; \
  1103. for (u32 i = 0; i < N; i++) { \
  1104. v[i] = static_cast<int>(*(colorValues++)); \
  1105. }
  1106. switch (colorEndpointMode) {
  1107. case 0: {
  1108. READ_UINT_VALUES(2)
  1109. ep1 = Pixel(0xFF, v[0], v[0], v[0]);
  1110. ep2 = Pixel(0xFF, v[1], v[1], v[1]);
  1111. } break;
  1112. case 1: {
  1113. READ_UINT_VALUES(2)
  1114. u32 L0 = (v[0] >> 2) | (v[1] & 0xC0);
  1115. u32 L1 = std::min(L0 + (v[1] & 0x3F), 0xFFU);
  1116. ep1 = Pixel(0xFF, L0, L0, L0);
  1117. ep2 = Pixel(0xFF, L1, L1, L1);
  1118. } break;
  1119. case 4: {
  1120. READ_UINT_VALUES(4)
  1121. ep1 = Pixel(v[2], v[0], v[0], v[0]);
  1122. ep2 = Pixel(v[3], v[1], v[1], v[1]);
  1123. } break;
  1124. case 5: {
  1125. READ_INT_VALUES(4)
  1126. BitTransferSigned(v[1], v[0]);
  1127. BitTransferSigned(v[3], v[2]);
  1128. ep1 = Pixel(v[2], v[0], v[0], v[0]);
  1129. ep2 = Pixel(v[2] + v[3], v[0] + v[1], v[0] + v[1], v[0] + v[1]);
  1130. ep1.ClampByte();
  1131. ep2.ClampByte();
  1132. } break;
  1133. case 6: {
  1134. READ_UINT_VALUES(4)
  1135. ep1 = Pixel(0xFF, v[0] * v[3] >> 8, v[1] * v[3] >> 8, v[2] * v[3] >> 8);
  1136. ep2 = Pixel(0xFF, v[0], v[1], v[2]);
  1137. } break;
  1138. case 8: {
  1139. READ_UINT_VALUES(6)
  1140. if (v[1] + v[3] + v[5] >= v[0] + v[2] + v[4]) {
  1141. ep1 = Pixel(0xFF, v[0], v[2], v[4]);
  1142. ep2 = Pixel(0xFF, v[1], v[3], v[5]);
  1143. } else {
  1144. ep1 = BlueContract(0xFF, v[1], v[3], v[5]);
  1145. ep2 = BlueContract(0xFF, v[0], v[2], v[4]);
  1146. }
  1147. } break;
  1148. case 9: {
  1149. READ_INT_VALUES(6)
  1150. BitTransferSigned(v[1], v[0]);
  1151. BitTransferSigned(v[3], v[2]);
  1152. BitTransferSigned(v[5], v[4]);
  1153. if (v[1] + v[3] + v[5] >= 0) {
  1154. ep1 = Pixel(0xFF, v[0], v[2], v[4]);
  1155. ep2 = Pixel(0xFF, v[0] + v[1], v[2] + v[3], v[4] + v[5]);
  1156. } else {
  1157. ep1 = BlueContract(0xFF, v[0] + v[1], v[2] + v[3], v[4] + v[5]);
  1158. ep2 = BlueContract(0xFF, v[0], v[2], v[4]);
  1159. }
  1160. ep1.ClampByte();
  1161. ep2.ClampByte();
  1162. } break;
  1163. case 10: {
  1164. READ_UINT_VALUES(6)
  1165. ep1 = Pixel(v[4], v[0] * v[3] >> 8, v[1] * v[3] >> 8, v[2] * v[3] >> 8);
  1166. ep2 = Pixel(v[5], v[0], v[1], v[2]);
  1167. } break;
  1168. case 12: {
  1169. READ_UINT_VALUES(8)
  1170. if (v[1] + v[3] + v[5] >= v[0] + v[2] + v[4]) {
  1171. ep1 = Pixel(v[6], v[0], v[2], v[4]);
  1172. ep2 = Pixel(v[7], v[1], v[3], v[5]);
  1173. } else {
  1174. ep1 = BlueContract(v[7], v[1], v[3], v[5]);
  1175. ep2 = BlueContract(v[6], v[0], v[2], v[4]);
  1176. }
  1177. } break;
  1178. case 13: {
  1179. READ_INT_VALUES(8)
  1180. BitTransferSigned(v[1], v[0]);
  1181. BitTransferSigned(v[3], v[2]);
  1182. BitTransferSigned(v[5], v[4]);
  1183. BitTransferSigned(v[7], v[6]);
  1184. if (v[1] + v[3] + v[5] >= 0) {
  1185. ep1 = Pixel(v[6], v[0], v[2], v[4]);
  1186. ep2 = Pixel(v[7] + v[6], v[0] + v[1], v[2] + v[3], v[4] + v[5]);
  1187. } else {
  1188. ep1 = BlueContract(v[6] + v[7], v[0] + v[1], v[2] + v[3], v[4] + v[5]);
  1189. ep2 = BlueContract(v[6], v[0], v[2], v[4]);
  1190. }
  1191. ep1.ClampByte();
  1192. ep2.ClampByte();
  1193. } break;
  1194. default:
  1195. assert(false && "Unsupported color endpoint mode (is it HDR?)");
  1196. break;
  1197. }
  1198. #undef READ_UINT_VALUES
  1199. #undef READ_INT_VALUES
  1200. }
  1201. static void FillVoidExtentLDR(InputBitStream& strm, std::span<u32> outBuf, u32 blockWidth,
  1202. u32 blockHeight) {
  1203. // Don't actually care about the void extent, just read the bits...
  1204. for (s32 i = 0; i < 4; ++i) {
  1205. strm.ReadBits<13>();
  1206. }
  1207. // Decode the RGBA components and renormalize them to the range [0, 255]
  1208. u16 r = static_cast<u16>(strm.ReadBits<16>());
  1209. u16 g = static_cast<u16>(strm.ReadBits<16>());
  1210. u16 b = static_cast<u16>(strm.ReadBits<16>());
  1211. u16 a = static_cast<u16>(strm.ReadBits<16>());
  1212. u32 rgba = (r >> 8) | (g & 0xFF00) | (static_cast<u32>(b) & 0xFF00) << 8 |
  1213. (static_cast<u32>(a) & 0xFF00) << 16;
  1214. for (u32 j = 0; j < blockHeight; j++) {
  1215. for (u32 i = 0; i < blockWidth; i++) {
  1216. outBuf[j * blockWidth + i] = rgba;
  1217. }
  1218. }
  1219. }
  1220. static void FillError(std::span<u32> outBuf, u32 blockWidth, u32 blockHeight) {
  1221. for (u32 j = 0; j < blockHeight; j++) {
  1222. for (u32 i = 0; i < blockWidth; i++) {
  1223. outBuf[j * blockWidth + i] = 0xFFFF00FF;
  1224. }
  1225. }
  1226. }
  1227. static void DecompressBlock(std::span<const u8, 16> inBuf, const u32 blockWidth,
  1228. const u32 blockHeight, std::span<u32, 12 * 12> outBuf) {
  1229. InputBitStream strm(inBuf);
  1230. TexelWeightParams weightParams = DecodeBlockInfo(strm);
  1231. // Was there an error?
  1232. if (weightParams.m_bError) {
  1233. assert(false && "Invalid block mode");
  1234. FillError(outBuf, blockWidth, blockHeight);
  1235. return;
  1236. }
  1237. if (weightParams.m_bVoidExtentLDR) {
  1238. FillVoidExtentLDR(strm, outBuf, blockWidth, blockHeight);
  1239. return;
  1240. }
  1241. if (weightParams.m_bVoidExtentHDR) {
  1242. assert(false && "HDR void extent blocks are unsupported!");
  1243. FillError(outBuf, blockWidth, blockHeight);
  1244. return;
  1245. }
  1246. if (weightParams.m_Width > blockWidth) {
  1247. assert(false && "Texel weight grid width should be smaller than block width");
  1248. FillError(outBuf, blockWidth, blockHeight);
  1249. return;
  1250. }
  1251. if (weightParams.m_Height > blockHeight) {
  1252. assert(false && "Texel weight grid height should be smaller than block height");
  1253. FillError(outBuf, blockWidth, blockHeight);
  1254. return;
  1255. }
  1256. // Read num partitions
  1257. u32 nPartitions = strm.ReadBits<2>() + 1;
  1258. assert(nPartitions <= 4);
  1259. if (nPartitions == 4 && weightParams.m_bDualPlane) {
  1260. assert(false && "Dual plane mode is incompatible with four partition blocks");
  1261. FillError(outBuf, blockWidth, blockHeight);
  1262. return;
  1263. }
  1264. // Based on the number of partitions, read the color endpoint mode for
  1265. // each partition.
  1266. // Determine partitions, partition index, and color endpoint modes
  1267. u32 planeIdx{UINT32_MAX};
  1268. u32 partitionIndex{};
  1269. u32 colorEndpointMode[4] = {0, 0, 0, 0};
  1270. // Define color data.
  1271. u8 colorEndpointData[16];
  1272. memset(colorEndpointData, 0, sizeof(colorEndpointData));
  1273. OutputBitStream colorEndpointStream(colorEndpointData, 16 * 8, 0);
  1274. // Read extra config data...
  1275. u32 baseCEM = 0;
  1276. if (nPartitions == 1) {
  1277. colorEndpointMode[0] = strm.ReadBits<4>();
  1278. partitionIndex = 0;
  1279. } else {
  1280. partitionIndex = strm.ReadBits<10>();
  1281. baseCEM = strm.ReadBits<6>();
  1282. }
  1283. u32 baseMode = (baseCEM & 3);
  1284. // Remaining bits are color endpoint data...
  1285. u32 nWeightBits = weightParams.GetPackedBitSize();
  1286. s32 remainingBits = 128 - nWeightBits - static_cast<int>(strm.GetBitsRead());
  1287. // Consider extra bits prior to texel data...
  1288. u32 extraCEMbits = 0;
  1289. if (baseMode) {
  1290. switch (nPartitions) {
  1291. case 2:
  1292. extraCEMbits += 2;
  1293. break;
  1294. case 3:
  1295. extraCEMbits += 5;
  1296. break;
  1297. case 4:
  1298. extraCEMbits += 8;
  1299. break;
  1300. default:
  1301. assert(false);
  1302. break;
  1303. }
  1304. }
  1305. remainingBits -= extraCEMbits;
  1306. // Do we have a dual plane situation?
  1307. u32 planeSelectorBits = 0;
  1308. if (weightParams.m_bDualPlane) {
  1309. planeSelectorBits = 2;
  1310. }
  1311. remainingBits -= planeSelectorBits;
  1312. // Read color data...
  1313. u32 colorDataBits = remainingBits;
  1314. while (remainingBits > 0) {
  1315. u32 nb = std::min(remainingBits, 8);
  1316. u32 b = strm.ReadBits(nb);
  1317. colorEndpointStream.WriteBits(b, nb);
  1318. remainingBits -= 8;
  1319. }
  1320. // Read the plane selection bits
  1321. planeIdx = strm.ReadBits(planeSelectorBits);
  1322. // Read the rest of the CEM
  1323. if (baseMode) {
  1324. u32 extraCEM = strm.ReadBits(extraCEMbits);
  1325. u32 CEM = (extraCEM << 6) | baseCEM;
  1326. CEM >>= 2;
  1327. bool C[4] = {0};
  1328. for (u32 i = 0; i < nPartitions; i++) {
  1329. C[i] = CEM & 1;
  1330. CEM >>= 1;
  1331. }
  1332. u8 M[4] = {0};
  1333. for (u32 i = 0; i < nPartitions; i++) {
  1334. M[i] = CEM & 3;
  1335. CEM >>= 2;
  1336. assert(M[i] <= 3);
  1337. }
  1338. for (u32 i = 0; i < nPartitions; i++) {
  1339. colorEndpointMode[i] = baseMode;
  1340. if (!(C[i]))
  1341. colorEndpointMode[i] -= 1;
  1342. colorEndpointMode[i] <<= 2;
  1343. colorEndpointMode[i] |= M[i];
  1344. }
  1345. } else if (nPartitions > 1) {
  1346. u32 CEM = baseCEM >> 2;
  1347. for (u32 i = 0; i < nPartitions; i++) {
  1348. colorEndpointMode[i] = CEM;
  1349. }
  1350. }
  1351. // Make sure everything up till here is sane.
  1352. for (u32 i = 0; i < nPartitions; i++) {
  1353. assert(colorEndpointMode[i] < 16);
  1354. }
  1355. assert(strm.GetBitsRead() + weightParams.GetPackedBitSize() == 128);
  1356. // Decode both color data and texel weight data
  1357. u32 colorValues[32]; // Four values, two endpoints, four maximum paritions
  1358. DecodeColorValues(colorValues, colorEndpointData, colorEndpointMode, nPartitions,
  1359. colorDataBits);
  1360. Pixel endpoints[4][2];
  1361. const u32* colorValuesPtr = colorValues;
  1362. for (u32 i = 0; i < nPartitions; i++) {
  1363. ComputeEndpoints(endpoints[i][0], endpoints[i][1], colorValuesPtr, colorEndpointMode[i]);
  1364. }
  1365. // Read the texel weight data..
  1366. std::array<u8, 16> texelWeightData;
  1367. std::ranges::copy(inBuf, texelWeightData.begin());
  1368. // Reverse everything
  1369. for (u32 i = 0; i < 8; i++) {
  1370. // Taken from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits
  1371. #define REVERSE_BYTE(b) (((b)*0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32
  1372. u8 a = static_cast<u8>(REVERSE_BYTE(texelWeightData[i]));
  1373. u8 b = static_cast<u8>(REVERSE_BYTE(texelWeightData[15 - i]));
  1374. #undef REVERSE_BYTE
  1375. texelWeightData[i] = b;
  1376. texelWeightData[15 - i] = a;
  1377. }
  1378. // Make sure that higher non-texel bits are set to zero
  1379. const u32 clearByteStart = (weightParams.GetPackedBitSize() >> 3) + 1;
  1380. if (clearByteStart > 0 && clearByteStart <= texelWeightData.size()) {
  1381. texelWeightData[clearByteStart - 1] &=
  1382. static_cast<u8>((1 << (weightParams.GetPackedBitSize() % 8)) - 1);
  1383. std::memset(texelWeightData.data() + clearByteStart, 0,
  1384. std::min(16U - clearByteStart, 16U));
  1385. }
  1386. IntegerEncodedVector texelWeightValues;
  1387. InputBitStream weightStream(texelWeightData);
  1388. DecodeIntegerSequence(texelWeightValues, weightStream, weightParams.m_MaxWeight,
  1389. weightParams.GetNumWeightValues());
  1390. // Blocks can be at most 12x12, so we can have as many as 144 weights
  1391. u32 weights[2][144];
  1392. UnquantizeTexelWeights(weights, texelWeightValues, weightParams, blockWidth, blockHeight);
  1393. // Now that we have endpoints and weights, we can interpolate and generate
  1394. // the proper decoding...
  1395. for (u32 j = 0; j < blockHeight; j++)
  1396. for (u32 i = 0; i < blockWidth; i++) {
  1397. u32 partition = Select2DPartition(partitionIndex, i, j, nPartitions,
  1398. (blockHeight * blockWidth) < 32);
  1399. assert(partition < nPartitions);
  1400. Pixel p;
  1401. for (u32 c = 0; c < 4; c++) {
  1402. u32 C0 = endpoints[partition][0].Component(c);
  1403. C0 = ReplicateByteTo16(C0);
  1404. u32 C1 = endpoints[partition][1].Component(c);
  1405. C1 = ReplicateByteTo16(C1);
  1406. u32 plane = 0;
  1407. if (weightParams.m_bDualPlane && (((planeIdx + 1) & 3) == c)) {
  1408. plane = 1;
  1409. }
  1410. u32 weight = weights[plane][j * blockWidth + i];
  1411. u32 C = (C0 * (64 - weight) + C1 * weight + 32) / 64;
  1412. if (C == 65535) {
  1413. p.Component(c) = 255;
  1414. } else {
  1415. double Cf = static_cast<double>(C);
  1416. p.Component(c) = static_cast<u16>(255.0 * (Cf / 65536.0) + 0.5);
  1417. }
  1418. }
  1419. outBuf[j * blockWidth + i] = p.Pack();
  1420. }
  1421. }
  1422. void Decompress(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth,
  1423. uint32_t block_width, uint32_t block_height, std::span<uint8_t> output) {
  1424. u32 block_index = 0;
  1425. std::size_t depth_offset = 0;
  1426. for (u32 z = 0; z < depth; z++) {
  1427. for (u32 y = 0; y < height; y += block_height) {
  1428. for (u32 x = 0; x < width; x += block_width) {
  1429. const std::span<const u8, 16> blockPtr{data.subspan(block_index * 16, 16)};
  1430. // Blocks can be at most 12x12
  1431. std::array<u32, 12 * 12> uncompData;
  1432. DecompressBlock(blockPtr, block_width, block_height, uncompData);
  1433. u32 decompWidth = std::min(block_width, width - x);
  1434. u32 decompHeight = std::min(block_height, height - y);
  1435. const std::span<u8> outRow = output.subspan(depth_offset + (y * width + x) * 4);
  1436. for (u32 jj = 0; jj < decompHeight; jj++) {
  1437. std::memcpy(outRow.data() + jj * width * 4,
  1438. uncompData.data() + jj * block_width, decompWidth * 4);
  1439. }
  1440. ++block_index;
  1441. }
  1442. }
  1443. depth_offset += height * width * 4;
  1444. }
  1445. }
  1446. } // namespace Tegra::Texture::ASTC