astc.cpp 50 KB

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