astc.cpp 47 KB

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