basisu_astc_helpers.h 108 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715
  1. // basisu_astc_helpers.h
  2. // Be sure to define ASTC_HELPERS_IMPLEMENTATION somewhere to get the implementation, otherwise you only get the header.
  3. #pragma once
  4. #ifndef BASISU_ASTC_HELPERS_HEADER
  5. #define BASISU_ASTC_HELPERS_HEADER
  6. #include <stdlib.h>
  7. #include <stdint.h>
  8. #include <math.h>
  9. #include <fenv.h>
  10. namespace astc_helpers
  11. {
  12. const uint32_t MAX_WEIGHT_VALUE = 64; // grid texel weights must range from [0,64]
  13. const uint32_t MIN_GRID_DIM = 2; // the minimum dimension of a block's weight grid
  14. const uint32_t MIN_BLOCK_DIM = 4, MAX_BLOCK_DIM = 12; // the valid block dimensions in texels
  15. const uint32_t MAX_GRID_WEIGHTS = 64; // a block may have a maximum of 64 weight grid values
  16. const uint32_t NUM_MODE11_ENDPOINTS = 6, NUM_MODE7_ENDPOINTS = 4;
  17. static const uint32_t NUM_ASTC_BLOCK_SIZES = 14;
  18. extern const uint8_t g_astc_block_sizes[NUM_ASTC_BLOCK_SIZES][2];
  19. // The Color Endpoint Modes (CEM's)
  20. enum cems
  21. {
  22. CEM_LDR_LUM_DIRECT = 0,
  23. CEM_LDR_LUM_BASE_PLUS_OFS = 1,
  24. CEM_HDR_LUM_LARGE_RANGE = 2,
  25. CEM_HDR_LUM_SMALL_RANGE = 3,
  26. CEM_LDR_LUM_ALPHA_DIRECT = 4,
  27. CEM_LDR_LUM_ALPHA_BASE_PLUS_OFS = 5,
  28. CEM_LDR_RGB_BASE_SCALE = 6,
  29. CEM_HDR_RGB_BASE_SCALE = 7,
  30. CEM_LDR_RGB_DIRECT = 8,
  31. CEM_LDR_RGB_BASE_PLUS_OFFSET = 9,
  32. CEM_LDR_RGB_BASE_SCALE_PLUS_TWO_A = 10,
  33. CEM_HDR_RGB = 11,
  34. CEM_LDR_RGBA_DIRECT = 12,
  35. CEM_LDR_RGBA_BASE_PLUS_OFFSET = 13,
  36. CEM_HDR_RGB_LDR_ALPHA = 14,
  37. CEM_HDR_RGB_HDR_ALPHA = 15
  38. };
  39. // All Bounded Integer Sequence Coding (BISE or ISE) ranges.
  40. // Weights: Ranges [0,11] are valid.
  41. // Endpoints: Ranges [4,20] are valid.
  42. enum bise_levels
  43. {
  44. BISE_2_LEVELS = 0,
  45. BISE_3_LEVELS = 1,
  46. BISE_4_LEVELS = 2,
  47. BISE_5_LEVELS = 3,
  48. BISE_6_LEVELS = 4,
  49. BISE_8_LEVELS = 5,
  50. BISE_10_LEVELS = 6,
  51. BISE_12_LEVELS = 7,
  52. BISE_16_LEVELS = 8,
  53. BISE_20_LEVELS = 9,
  54. BISE_24_LEVELS = 10,
  55. BISE_32_LEVELS = 11,
  56. BISE_40_LEVELS = 12,
  57. BISE_48_LEVELS = 13,
  58. BISE_64_LEVELS = 14,
  59. BISE_80_LEVELS = 15,
  60. BISE_96_LEVELS = 16,
  61. BISE_128_LEVELS = 17,
  62. BISE_160_LEVELS = 18,
  63. BISE_192_LEVELS = 19,
  64. BISE_256_LEVELS = 20
  65. };
  66. const uint32_t TOTAL_ISE_RANGES = 21;
  67. // Valid endpoint ISE ranges
  68. const uint32_t FIRST_VALID_ENDPOINT_ISE_RANGE = BISE_6_LEVELS; // 4
  69. const uint32_t LAST_VALID_ENDPOINT_ISE_RANGE = BISE_256_LEVELS; // 20
  70. const uint32_t TOTAL_ENDPOINT_ISE_RANGES = LAST_VALID_ENDPOINT_ISE_RANGE - FIRST_VALID_ENDPOINT_ISE_RANGE + 1;
  71. // Valid weight ISE ranges
  72. const uint32_t FIRST_VALID_WEIGHT_ISE_RANGE = BISE_2_LEVELS; // 0
  73. const uint32_t LAST_VALID_WEIGHT_ISE_RANGE = BISE_32_LEVELS; // 11
  74. const uint32_t TOTAL_WEIGHT_ISE_RANGES = LAST_VALID_WEIGHT_ISE_RANGE - FIRST_VALID_WEIGHT_ISE_RANGE + 1;
  75. // The ISE range table.
  76. extern const int8_t g_ise_range_table[TOTAL_ISE_RANGES][3]; // 0=bits (0 to 8), 1=trits (0 or 1), 2=quints (0 or 1)
  77. // Possible Color Component Select values, used in dual plane mode.
  78. // The CCS component will be interpolated using the 2nd weight plane.
  79. enum ccs
  80. {
  81. CCS_GBA_R = 0,
  82. CCS_RBA_G = 1,
  83. CCS_RGA_B = 2,
  84. CCS_RGB_A = 3
  85. };
  86. struct astc_block
  87. {
  88. uint32_t m_vals[4];
  89. };
  90. const uint32_t MAX_PARTITIONS = 4; // Max # of partitions or subsets for single plane mode
  91. const uint32_t MAX_DUAL_PLANE_PARTITIONS = 3; // Max # of partitions or subsets for dual plane mode
  92. const uint32_t NUM_PARTITION_PATTERNS = 1024; // Total # of partition pattern seeds (10-bits)
  93. const uint32_t MAX_ENDPOINTS = 18; // Maximum # of endpoint values in a block
  94. struct log_astc_block
  95. {
  96. bool m_error_flag;
  97. bool m_solid_color_flag_ldr, m_solid_color_flag_hdr;
  98. uint8_t m_user_mode; // user defined value, not used in this module
  99. // Rest is only valid if !m_solid_color_flag_ldr && !m_solid_color_flag_hdr
  100. uint8_t m_grid_width, m_grid_height; // weight grid dimensions, not the dimension of the block
  101. bool m_dual_plane;
  102. uint8_t m_weight_ise_range; // 0-11
  103. uint8_t m_endpoint_ise_range; // 4-20, this is actually inferred from the size of the other config bits+weights, but this is here for checking
  104. uint8_t m_color_component_selector; // 0-3, controls which channel uses the 2nd (odd) weights, only used in dual plane mode
  105. uint8_t m_num_partitions; // or the # of subsets, 1-4 (1-3 if dual plane mode)
  106. uint16_t m_partition_id; // 10-bits, must be 0 if m_num_partitions==1
  107. uint8_t m_color_endpoint_modes[MAX_PARTITIONS]; // each subset's CEM's
  108. union
  109. {
  110. // ISE weight grid values. In dual plane mode, the order is p0,p1, p0,p1, etc.
  111. uint8_t m_weights[MAX_GRID_WEIGHTS];
  112. uint16_t m_solid_color[4];
  113. };
  114. // ISE endpoint values
  115. // Endpoint order examples:
  116. // 1 subset LA : LL0 LH0 AL0 AH0
  117. // 1 subset RGB : RL0 RH0 GL0 GH0 BL0 BH0
  118. // 1 subset RGBA : RL0 RH0 GL0 GH0 BL0 BH0 AL0 AH0
  119. // 2 subset LA : LL0 LH0 AL0 AH0 LL1 LH1 AL1 AH1
  120. // 2 subset RGB : RL0 RH0 GL0 GH0 BL0 BH0 RL1 RH1 GL1 GH1 BL1 BH1
  121. // 2 subset RGBA : RL0 RH0 GL0 GH0 BL0 BH0 AL0 AH0 RL1 RH1 GL1 GH1 BL1 BH1 AL1 AH1
  122. uint8_t m_endpoints[MAX_ENDPOINTS];
  123. void clear()
  124. {
  125. memset(this, 0, sizeof(*this));
  126. }
  127. };
  128. // Open interval
  129. inline int bounds_check(int v, int l, int h) { (void)v; (void)l; (void)h; assert(v >= l && v < h); return v; }
  130. inline uint32_t bounds_check(uint32_t v, uint32_t l, uint32_t h) { (void)v; (void)l; (void)h; assert(v >= l && v < h); return v; }
  131. inline uint32_t get_bits(uint32_t val, int low, int high)
  132. {
  133. const int num_bits = (high - low) + 1;
  134. assert((num_bits >= 1) && (num_bits <= 32));
  135. val >>= low;
  136. if (num_bits != 32)
  137. val &= ((1u << num_bits) - 1);
  138. return val;
  139. }
  140. // Returns the number of levels in the given ISE range.
  141. inline uint32_t get_ise_levels(uint32_t ise_range)
  142. {
  143. assert(ise_range < TOTAL_ISE_RANGES);
  144. return (1 + 2 * g_ise_range_table[ise_range][1] + 4 * g_ise_range_table[ise_range][2]) << g_ise_range_table[ise_range][0];
  145. }
  146. inline int get_ise_sequence_bits(int count, int range)
  147. {
  148. // See 18.22 Data Size Determination - note this will be <= the # of bits actually written by encode_bise(). (It's magic.)
  149. int total_bits = g_ise_range_table[range][0] * count;
  150. total_bits += (g_ise_range_table[range][1] * 8 * count + 4) / 5;
  151. total_bits += (g_ise_range_table[range][2] * 7 * count + 2) / 3;
  152. return total_bits;
  153. }
  154. inline uint32_t weight_interpolate(uint32_t l, uint32_t h, uint32_t w)
  155. {
  156. assert(w <= MAX_WEIGHT_VALUE);
  157. return (l * (64 - w) + h * w + 32) >> 6;
  158. }
  159. void encode_bise(uint32_t* pDst, const uint8_t* pSrc_vals, uint32_t bit_pos, int num_vals, int range, uint32_t *pStats = nullptr);
  160. struct pack_stats
  161. {
  162. uint32_t m_header_bits;
  163. uint32_t m_endpoint_bits;
  164. uint32_t m_weight_bits;
  165. inline pack_stats() { clear(); }
  166. inline void clear() { memset(this, 0, sizeof(*this)); }
  167. };
  168. // Packs a logical to physical ASTC block. Note this does not validate the block's dimensions (use is_valid_block_size()), just the grid dimensions.
  169. bool pack_astc_block(astc_block &phys_block, const log_astc_block& log_block, int* pExpected_endpoint_range = nullptr, pack_stats *pStats = nullptr);
  170. // Pack LDR void extent (really solid color) blocks. For LDR, pass in (val | (val << 8)) for each component.
  171. void pack_void_extent_ldr(astc_block& blk, uint16_t r, uint16_t g, uint16_t b, uint16_t a, pack_stats *pStats = nullptr);
  172. // Pack HDR void extent (16-bit values are FP16/half floats - no NaN/Inf's)
  173. void pack_void_extent_hdr(astc_block& blk, uint16_t rh, uint16_t gh, uint16_t bh, uint16_t ah, pack_stats* pStats = nullptr);
  174. // These helpers are all quite slow, but are useful for table preparation.
  175. // Dequantizes ISE encoded endpoint val to [0,255]
  176. uint32_t dequant_bise_endpoint(uint32_t val, uint32_t ise_range); // ISE ranges 4-11
  177. // Dequantizes ISE encoded weight val to [0,64]
  178. uint32_t dequant_bise_weight(uint32_t val, uint32_t ise_range); // ISE ranges 0-10
  179. uint32_t find_nearest_bise_endpoint(int v, uint32_t ise_range);
  180. uint32_t find_nearest_bise_weight(int v, uint32_t ise_range);
  181. void create_quant_tables(
  182. uint8_t* pVal_to_ise, // [0-255] or [0-64] value to nearest ISE symbol, array size is [256] or [65]
  183. uint8_t* pISE_to_val, // ASTC encoded ISE symbol to [0,255] or [0,64] value, [levels]
  184. uint8_t* pISE_to_rank, // returns the level rank index given an ISE symbol, [levels]
  185. uint8_t* pRank_to_ISE, // returns the ISE symbol given a level rank, inverse of pISE_to_rank, [levels]
  186. uint32_t ise_range, // ise range, [4,20] for endpoints, [0,11] for weights
  187. bool weight_flag); // false if block endpoints, true if weights
  188. // True if the CEM is LDR.
  189. bool is_cem_ldr(uint32_t mode);
  190. inline bool is_cem_hdr(uint32_t mode) { return !is_cem_ldr(mode); }
  191. // True if the passed in dimensions are a valid ASTC block size. There are 14 supported configs, from 4x4 (8bpp) to 12x12 (.89bpp).
  192. bool is_valid_block_size(uint32_t w, uint32_t h);
  193. bool block_has_any_hdr_cems(const log_astc_block& log_blk);
  194. bool block_has_any_ldr_cems(const log_astc_block& log_blk);
  195. // Returns the # of endpoint values for the given CEM.
  196. inline uint32_t get_num_cem_values(uint32_t cem) { assert(cem <= 15); return 2 + 2 * (cem >> 2); }
  197. struct dequant_table
  198. {
  199. basisu::vector<uint8_t> m_val_to_ise; // [0-255] or [0-64] value to nearest ISE symbol, array size is [256] or [65]
  200. basisu::vector<uint8_t> m_ISE_to_val; // ASTC encoded ISE symbol to [0,255] or [0,64] value, [levels]
  201. basisu::vector<uint8_t> m_ISE_to_rank; // returns the level rank index given an ISE symbol, [levels]
  202. basisu::vector<uint8_t> m_rank_to_ISE; // returns the ISE symbol given a level rank, inverse of pISE_to_rank, [levels]
  203. void init(bool weight_flag, uint32_t num_levels, bool init_rank_tabs)
  204. {
  205. m_val_to_ise.resize(weight_flag ? (MAX_WEIGHT_VALUE + 1) : 256);
  206. m_ISE_to_val.resize(num_levels);
  207. if (init_rank_tabs)
  208. {
  209. m_ISE_to_rank.resize(num_levels);
  210. m_rank_to_ISE.resize(num_levels);
  211. }
  212. }
  213. };
  214. struct dequant_tables
  215. {
  216. dequant_table m_weights[TOTAL_WEIGHT_ISE_RANGES];
  217. dequant_table m_endpoints[TOTAL_ENDPOINT_ISE_RANGES];
  218. const dequant_table& get_weight_tab(uint32_t range) const
  219. {
  220. assert((range >= FIRST_VALID_WEIGHT_ISE_RANGE) && (range <= LAST_VALID_WEIGHT_ISE_RANGE));
  221. return m_weights[range - FIRST_VALID_WEIGHT_ISE_RANGE];
  222. }
  223. dequant_table& get_weight_tab(uint32_t range)
  224. {
  225. assert((range >= FIRST_VALID_WEIGHT_ISE_RANGE) && (range <= LAST_VALID_WEIGHT_ISE_RANGE));
  226. return m_weights[range - FIRST_VALID_WEIGHT_ISE_RANGE];
  227. }
  228. const dequant_table& get_endpoint_tab(uint32_t range) const
  229. {
  230. assert((range >= FIRST_VALID_ENDPOINT_ISE_RANGE) && (range <= LAST_VALID_ENDPOINT_ISE_RANGE));
  231. return m_endpoints[range - FIRST_VALID_ENDPOINT_ISE_RANGE];
  232. }
  233. dequant_table& get_endpoint_tab(uint32_t range)
  234. {
  235. assert((range >= FIRST_VALID_ENDPOINT_ISE_RANGE) && (range <= LAST_VALID_ENDPOINT_ISE_RANGE));
  236. return m_endpoints[range - FIRST_VALID_ENDPOINT_ISE_RANGE];
  237. }
  238. void init(bool init_rank_tabs)
  239. {
  240. for (uint32_t range = FIRST_VALID_WEIGHT_ISE_RANGE; range <= LAST_VALID_WEIGHT_ISE_RANGE; range++)
  241. {
  242. const uint32_t num_levels = get_ise_levels(range);
  243. dequant_table& tab = get_weight_tab(range);
  244. tab.init(true, num_levels, init_rank_tabs);
  245. create_quant_tables(tab.m_val_to_ise.data(), tab.m_ISE_to_val.data(), init_rank_tabs ? tab.m_ISE_to_rank.data() : nullptr, init_rank_tabs ? tab.m_rank_to_ISE.data() : nullptr, range, true);
  246. }
  247. for (uint32_t range = FIRST_VALID_ENDPOINT_ISE_RANGE; range <= LAST_VALID_ENDPOINT_ISE_RANGE; range++)
  248. {
  249. const uint32_t num_levels = get_ise_levels(range);
  250. dequant_table& tab = get_endpoint_tab(range);
  251. tab.init(false, num_levels, init_rank_tabs);
  252. create_quant_tables(tab.m_val_to_ise.data(), tab.m_ISE_to_val.data(), init_rank_tabs ? tab.m_ISE_to_rank.data() : nullptr, init_rank_tabs ? tab.m_rank_to_ISE.data() : nullptr, range, false);
  253. }
  254. }
  255. };
  256. extern dequant_tables g_dequant_tables;
  257. void init_tables(bool init_rank_tabs);
  258. struct weighted_sample
  259. {
  260. uint8_t m_src_x;
  261. uint8_t m_src_y;
  262. uint8_t m_weights[2][2]; // [y][x], scaled by 16, round by adding 8
  263. };
  264. void compute_upsample_weights(
  265. int block_width, int block_height,
  266. int weight_grid_width, int weight_grid_height,
  267. weighted_sample* pWeights); // there will be block_width * block_height bilinear samples
  268. void upsample_weight_grid(
  269. uint32_t bx, uint32_t by, // destination/to dimension
  270. uint32_t wx, uint32_t wy, // source/from dimension
  271. const uint8_t* pSrc_weights, // these are dequantized [0,64] weights, NOT ISE symbols, [wy][wx]
  272. uint8_t* pDst_weights); // [by][bx]
  273. // Procedurally returns the texel partition/subset index given the block coordinate and config.
  274. int compute_texel_partition(uint32_t seedIn, uint32_t xIn, uint32_t yIn, uint32_t zIn, int num_partitions, bool small_block);
  275. void blue_contract(
  276. int r, int g, int b, int a,
  277. int& dr, int& dg, int& db, int& da);
  278. void bit_transfer_signed(int& a, int& b);
  279. void decode_endpoint(uint32_t cem_index, int (*pEndpoints)[2], const uint8_t* pE);
  280. typedef uint16_t half_float;
  281. half_float float_to_half(float val, bool toward_zero);
  282. float half_to_float(half_float hval);
  283. // Notes:
  284. // qlog16_to_half(half_to_qlog16(half_val_as_int)) == half_val_as_int (is lossless)
  285. // However, this is not lossless in the general sense.
  286. inline half_float qlog16_to_half(int k)
  287. {
  288. assert((k >= 0) && (k <= 0xFFFF));
  289. int E = (k & 0xF800) >> 11;
  290. int M = k & 0x7FF;
  291. int Mt;
  292. if (M < 512)
  293. Mt = 3 * M;
  294. else if (M >= 1536)
  295. Mt = 5 * M - 2048;
  296. else
  297. Mt = 4 * M - 512;
  298. return (half_float)((E << 10) + (Mt >> 3));
  299. }
  300. const int MAX_RGB9E5 = 0xff80;
  301. void unpack_rgb9e5(uint32_t packed, float& r, float& g, float& b);
  302. uint32_t pack_rgb9e5(float r, float g, float b);
  303. enum decode_mode
  304. {
  305. cDecodeModeSRGB8 = 0, // returns uint8_t's, not valid on HDR blocks
  306. cDecodeModeLDR8 = 1, // returns uint8_t's, not valid on HDR blocks
  307. cDecodeModeHDR16 = 2, // returns uint16_t's (half floats), valid on all LDR/HDR blocks
  308. cDecodeModeRGB9E5 = 3 // returns uint32_t's, packed as RGB 9E5 (shared exponent), see https://registry.khronos.org/OpenGL/extensions/EXT/EXT_texture_shared_exponent.txt
  309. };
  310. // Decodes logical block to output pixels.
  311. // pPixels must point to either 32-bit pixel values (SRGB8/LDR8/9E5) or 64-bit pixel values (HDR16)
  312. bool decode_block(const log_astc_block& log_blk, void* pPixels, uint32_t blk_width, uint32_t blk_height, decode_mode dec_mode);
  313. void decode_bise(uint32_t ise_range, uint8_t* pVals, uint32_t num_vals, const uint8_t *pBits128, uint32_t bit_ofs);
  314. // Unpack a physical ASTC encoded GPU texture block to a logical block description.
  315. bool unpack_block(const void* pASTC_block, log_astc_block& log_blk, uint32_t blk_width, uint32_t blk_height);
  316. } // namespace astc_helpers
  317. #endif // BASISU_ASTC_HELPERS_HEADER
  318. //------------------------------------------------------------------
  319. #ifdef BASISU_ASTC_HELPERS_IMPLEMENTATION
  320. namespace astc_helpers
  321. {
  322. template<typename T> inline T my_min(T a, T b) { return (a < b) ? a : b; }
  323. template<typename T> inline T my_max(T a, T b) { return (a > b) ? a : b; }
  324. const uint8_t g_astc_block_sizes[NUM_ASTC_BLOCK_SIZES][2] = {
  325. { 4, 4 }, { 5, 4 }, { 5, 5 }, { 6, 5 },
  326. { 6, 6 }, { 8, 5 }, { 8, 6 }, { 10, 5 },
  327. { 10, 6 }, { 8, 8 }, { 10, 8 }, { 10, 10 },
  328. { 12, 10 }, { 12, 12 }
  329. };
  330. const int8_t g_ise_range_table[TOTAL_ISE_RANGES][3] =
  331. {
  332. //b t q
  333. //2 3 5 // rng ise_index notes
  334. { 1, 0, 0 }, // 0..1 0
  335. { 0, 1, 0 }, // 0..2 1
  336. { 2, 0, 0 }, // 0..3 2
  337. { 0, 0, 1 }, // 0..4 3
  338. { 1, 1, 0 }, // 0..5 4 min endpoint ISE index
  339. { 3, 0, 0 }, // 0..7 5
  340. { 1, 0, 1 }, // 0..9 6
  341. { 2, 1, 0 }, // 0..11 7
  342. { 4, 0, 0 }, // 0..15 8
  343. { 2, 0, 1 }, // 0..19 9
  344. { 3, 1, 0 }, // 0..23 10
  345. { 5, 0, 0 }, // 0..31 11 max weight ISE index
  346. { 3, 0, 1 }, // 0..39 12
  347. { 4, 1, 0 }, // 0..47 13
  348. { 6, 0, 0 }, // 0..63 14
  349. { 4, 0, 1 }, // 0..79 15
  350. { 5, 1, 0 }, // 0..95 16
  351. { 7, 0, 0 }, // 0..127 17
  352. { 5, 0, 1 }, // 0..159 18
  353. { 6, 1, 0 }, // 0..191 19
  354. { 8, 0, 0 }, // 0..255 20
  355. };
  356. static inline void astc_set_bits_1_to_9(uint32_t* pDst, uint32_t& bit_offset, uint32_t code, uint32_t codesize)
  357. {
  358. uint8_t* pBuf = reinterpret_cast<uint8_t*>(pDst);
  359. assert(codesize <= 9);
  360. if (codesize)
  361. {
  362. uint32_t byte_bit_offset = bit_offset & 7;
  363. uint32_t val = code << byte_bit_offset;
  364. uint32_t index = bit_offset >> 3;
  365. pBuf[index] |= (uint8_t)val;
  366. if (codesize > (8 - byte_bit_offset))
  367. pBuf[index + 1] |= (uint8_t)(val >> 8);
  368. bit_offset += codesize;
  369. }
  370. }
  371. static inline uint32_t astc_extract_bits(uint32_t bits, int low, int high)
  372. {
  373. return (bits >> low) & ((1 << (high - low + 1)) - 1);
  374. }
  375. // Writes bits to output in an endian safe way
  376. static inline void astc_set_bits(uint32_t* pOutput, uint32_t& bit_pos, uint32_t value, uint32_t total_bits)
  377. {
  378. assert(total_bits <= 31);
  379. assert(value < (1u << total_bits));
  380. uint8_t* pBytes = reinterpret_cast<uint8_t*>(pOutput);
  381. while (total_bits)
  382. {
  383. const uint32_t bits_to_write = my_min<int>(total_bits, 8 - (bit_pos & 7));
  384. pBytes[bit_pos >> 3] |= static_cast<uint8_t>(value << (bit_pos & 7));
  385. bit_pos += bits_to_write;
  386. total_bits -= bits_to_write;
  387. value >>= bits_to_write;
  388. }
  389. }
  390. static const uint8_t g_astc_quint_encode[125] =
  391. {
  392. 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 16, 17, 18, 19, 20, 24, 25, 26, 27, 28, 5, 13, 21, 29, 6, 32, 33, 34, 35, 36, 40, 41, 42, 43, 44, 48, 49, 50, 51, 52, 56, 57,
  393. 58, 59, 60, 37, 45, 53, 61, 14, 64, 65, 66, 67, 68, 72, 73, 74, 75, 76, 80, 81, 82, 83, 84, 88, 89, 90, 91, 92, 69, 77, 85, 93, 22, 96, 97, 98, 99, 100, 104,
  394. 105, 106, 107, 108, 112, 113, 114, 115, 116, 120, 121, 122, 123, 124, 101, 109, 117, 125, 30, 102, 103, 70, 71, 38, 110, 111, 78, 79, 46, 118, 119, 86, 87, 54,
  395. 126, 127, 94, 95, 62, 39, 47, 55, 63, 7 /*31 - results in the same decode as 7*/
  396. };
  397. // Encodes 3 values to output, usable for any range that uses quints and bits
  398. static inline void astc_encode_quints(uint32_t* pOutput, const uint8_t* pValues, uint32_t& bit_pos, int n, uint32_t* pStats)
  399. {
  400. // First extract the quints and the bits from the 3 input values
  401. int quints = 0, bits[3];
  402. const uint32_t bit_mask = (1 << n) - 1;
  403. for (int i = 0; i < 3; i++)
  404. {
  405. static const int s_muls[3] = { 1, 5, 25 };
  406. const int t = pValues[i] >> n;
  407. quints += t * s_muls[i];
  408. bits[i] = pValues[i] & bit_mask;
  409. }
  410. // Encode the quints, by inverting the bit manipulations done by the decoder, converting 3 quints into 7-bits.
  411. // See https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#astc-integer-sequence-encoding
  412. assert(quints < 125);
  413. const int T = g_astc_quint_encode[quints];
  414. // Now interleave the 7 encoded quint bits with the bits to form the encoded output. See table 95-96.
  415. astc_set_bits(pOutput, bit_pos, bits[0] | (astc_extract_bits(T, 0, 2) << n) | (bits[1] << (3 + n)) | (astc_extract_bits(T, 3, 4) << (3 + n * 2)) |
  416. (bits[2] << (5 + n * 2)) | (astc_extract_bits(T, 5, 6) << (5 + n * 3)), 7 + n * 3);
  417. if (pStats)
  418. *pStats += n * 3 + 7;
  419. }
  420. static const uint8_t g_astc_trit_encode[243] = { 0, 1, 2, 4, 5, 6, 8, 9, 10, 16, 17, 18, 20, 21, 22, 24, 25, 26, 3, 7, 11, 19, 23, 27, 12, 13, 14, 32, 33, 34, 36, 37, 38, 40, 41, 42, 48, 49, 50, 52, 53, 54, 56, 57, 58, 35, 39,
  421. 43, 51, 55, 59, 44, 45, 46, 64, 65, 66, 68, 69, 70, 72, 73, 74, 80, 81, 82, 84, 85, 86, 88, 89, 90, 67, 71, 75, 83, 87, 91, 76, 77, 78, 128, 129, 130, 132, 133, 134, 136, 137, 138, 144, 145, 146, 148, 149, 150, 152, 153, 154,
  422. 131, 135, 139, 147, 151, 155, 140, 141, 142, 160, 161, 162, 164, 165, 166, 168, 169, 170, 176, 177, 178, 180, 181, 182, 184, 185, 186, 163, 167, 171, 179, 183, 187, 172, 173, 174, 192, 193, 194, 196, 197, 198, 200, 201, 202,
  423. 208, 209, 210, 212, 213, 214, 216, 217, 218, 195, 199, 203, 211, 215, 219, 204, 205, 206, 96, 97, 98, 100, 101, 102, 104, 105, 106, 112, 113, 114, 116, 117, 118, 120, 121, 122, 99, 103, 107, 115, 119, 123, 108, 109, 110, 224,
  424. 225, 226, 228, 229, 230, 232, 233, 234, 240, 241, 242, 244, 245, 246, 248, 249, 250, 227, 231, 235, 243, 247, 251, 236, 237, 238, 28, 29, 30, 60, 61, 62, 92, 93, 94, 156, 157, 158, 188, 189, 190, 220, 221, 222, 31, 63, 95, 159,
  425. 191, 223, 124, 125, 126 };
  426. // Encodes 5 values to output, usable for any range that uses trits and bits
  427. static void astc_encode_trits(uint32_t* pOutput, const uint8_t* pValues, uint32_t& bit_pos, int n, uint32_t *pStats)
  428. {
  429. // First extract the trits and the bits from the 5 input values
  430. int trits = 0, bits[5];
  431. const uint32_t bit_mask = (1 << n) - 1;
  432. for (int i = 0; i < 5; i++)
  433. {
  434. static const int s_muls[5] = { 1, 3, 9, 27, 81 };
  435. const int t = pValues[i] >> n;
  436. trits += t * s_muls[i];
  437. bits[i] = pValues[i] & bit_mask;
  438. }
  439. // Encode the trits, by inverting the bit manipulations done by the decoder, converting 5 trits into 8-bits.
  440. // See https://www.khronos.org/registry/DataFormat/specs/1.2/dataformat.1.2.html#astc-integer-sequence-encoding
  441. assert(trits < 243);
  442. const int T = g_astc_trit_encode[trits];
  443. // Now interleave the 8 encoded trit bits with the bits to form the encoded output. See table 94.
  444. astc_set_bits(pOutput, bit_pos, bits[0] | (astc_extract_bits(T, 0, 1) << n) | (bits[1] << (2 + n)), n * 2 + 2);
  445. astc_set_bits(pOutput, bit_pos, astc_extract_bits(T, 2, 3) | (bits[2] << 2) | (astc_extract_bits(T, 4, 4) << (2 + n)) | (bits[3] << (3 + n)) | (astc_extract_bits(T, 5, 6) << (3 + n * 2)) |
  446. (bits[4] << (5 + n * 2)) | (astc_extract_bits(T, 7, 7) << (5 + n * 3)), n * 3 + 6);
  447. if (pStats)
  448. *pStats += n * 5 + 8;
  449. }
  450. // Packs values using ASTC's BISE to output buffer.
  451. void encode_bise(uint32_t* pDst, const uint8_t* pSrc_vals, uint32_t bit_pos, int num_vals, int range, uint32_t *pStats)
  452. {
  453. uint32_t temp[5] = { 0 };
  454. const int num_bits = g_ise_range_table[range][0];
  455. int group_size = 0;
  456. if (g_ise_range_table[range][1])
  457. group_size = 5;
  458. else if (g_ise_range_table[range][2])
  459. group_size = 3;
  460. #ifndef NDEBUG
  461. const uint32_t num_levels = get_ise_levels(range);
  462. for (int i = 0; i < num_vals; i++)
  463. {
  464. assert(pSrc_vals[i] < num_levels);
  465. }
  466. #endif
  467. if (group_size)
  468. {
  469. // Range has trits or quints - pack each group of 5 or 3 values
  470. const int total_groups = (group_size == 5) ? ((num_vals + 4) / 5) : ((num_vals + 2) / 3);
  471. for (int group_index = 0; group_index < total_groups; group_index++)
  472. {
  473. uint8_t vals[5] = { 0 };
  474. const int limit = my_min(group_size, num_vals - group_index * group_size);
  475. for (int i = 0; i < limit; i++)
  476. vals[i] = pSrc_vals[group_index * group_size + i];
  477. // Note this always writes a group of 3 or 5 bits values, even for incomplete groups. So it can write more than needed.
  478. // get_ise_sequence_bits() returns the # of bits that must be written for proper decoding.
  479. if (group_size == 5)
  480. astc_encode_trits(temp, vals, bit_pos, num_bits, pStats);
  481. else
  482. astc_encode_quints(temp, vals, bit_pos, num_bits, pStats);
  483. }
  484. }
  485. else
  486. {
  487. for (int i = 0; i < num_vals; i++)
  488. astc_set_bits_1_to_9(temp, bit_pos, pSrc_vals[i], num_bits);
  489. if (pStats)
  490. *pStats += num_vals * num_bits;
  491. }
  492. pDst[0] |= temp[0]; pDst[1] |= temp[1];
  493. pDst[2] |= temp[2]; pDst[3] |= temp[3];
  494. }
  495. inline uint32_t rev_dword(uint32_t bits)
  496. {
  497. uint32_t v = (bits << 16) | (bits >> 16);
  498. v = ((v & 0x00ff00ff) << 8) | ((v & 0xff00ff00) >> 8); v = ((v & 0x0f0f0f0f) << 4) | ((v & 0xf0f0f0f0) >> 4);
  499. v = ((v & 0x33333333) << 2) | ((v & 0xcccccccc) >> 2); v = ((v & 0x55555555) << 1) | ((v & 0xaaaaaaaa) >> 1);
  500. return v;
  501. }
  502. static inline bool is_packable(int value, int num_bits) { assert((num_bits >= 1) && (num_bits < 31)); return (value >= 0) && (value < (1 << num_bits)); }
  503. static bool get_config_bits(const log_astc_block &log_block, uint32_t &config_bits)
  504. {
  505. config_bits = 0;
  506. const int W = log_block.m_grid_width, H = log_block.m_grid_height;
  507. const uint32_t P = log_block.m_weight_ise_range >= 6; // high precision
  508. const uint32_t Dp_P = (log_block.m_dual_plane << 1) | P; // pack dual plane+high precision bits
  509. // See Tables 81-82
  510. // Compute p from weight range
  511. uint32_t p = 2 + log_block.m_weight_ise_range - (P ? 6 : 0);
  512. // Rearrange p's bits to p0 p2 p1
  513. p = (p >> 1) + ((p & 1) << 2);
  514. // Try encoding each row of table 82.
  515. // W+4 H+2
  516. if (is_packable(W - 4, 2) && is_packable(H - 2, 2))
  517. {
  518. config_bits = (Dp_P << 9) | ((W - 4) << 7) | ((H - 2) << 5) | ((p & 4) << 2) | (p & 3);
  519. return true;
  520. }
  521. // W+8 H+2
  522. if (is_packable(W - 8, 2) && is_packable(H - 2, 2))
  523. {
  524. config_bits = (Dp_P << 9) | ((W - 8) << 7) | ((H - 2) << 5) | ((p & 4) << 2) | 4 | (p & 3);
  525. return true;
  526. }
  527. // W+2 H+8
  528. if (is_packable(W - 2, 2) && is_packable(H - 8, 2))
  529. {
  530. config_bits = (Dp_P << 9) | ((H - 8) << 7) | ((W - 2) << 5) | ((p & 4) << 2) | 8 | (p & 3);
  531. return true;
  532. }
  533. // W+2 H+6
  534. if (is_packable(W - 2, 2) && is_packable(H - 6, 1))
  535. {
  536. config_bits = (Dp_P << 9) | ((H - 6) << 7) | ((W - 2) << 5) | ((p & 4) << 2) | 12 | (p & 3);
  537. return true;
  538. }
  539. // W+2 H+2
  540. if (is_packable(W - 2, 1) && is_packable(H - 2, 2))
  541. {
  542. config_bits = (Dp_P << 9) | ((W) << 7) | ((H - 2) << 5) | ((p & 4) << 2) | 12 | (p & 3);
  543. return true;
  544. }
  545. // 12 H+2
  546. if ((W == 12) && is_packable(H - 2, 2))
  547. {
  548. config_bits = (Dp_P << 9) | ((H - 2) << 5) | (p << 2);
  549. return true;
  550. }
  551. // W+2 12
  552. if ((H == 12) && is_packable(W - 2, 2))
  553. {
  554. config_bits = (Dp_P << 9) | (1 << 7) | ((W - 2) << 5) | (p << 2);
  555. return true;
  556. }
  557. // 6 10
  558. if ((W == 6) && (H == 10))
  559. {
  560. config_bits = (Dp_P << 9) | (3 << 7) | (p << 2);
  561. return true;
  562. }
  563. // 10 6
  564. if ((W == 10) && (H == 6))
  565. {
  566. config_bits = (Dp_P << 9) | (0b1101 << 5) | (p << 2);
  567. return true;
  568. }
  569. // W+6 H+6 (no dual plane or high prec)
  570. if ((!Dp_P) && is_packable(W - 6, 2) && is_packable(H - 6, 2))
  571. {
  572. config_bits = ((H - 6) << 9) | 256 | ((W - 6) << 5) | (p << 2);
  573. return true;
  574. }
  575. // Failed: unsupported weight grid dimensions or config.
  576. return false;
  577. }
  578. bool pack_astc_block(astc_block& phys_block, const log_astc_block& log_block, int* pExpected_endpoint_range, pack_stats *pStats)
  579. {
  580. memset(&phys_block, 0, sizeof(phys_block));
  581. if (pExpected_endpoint_range)
  582. *pExpected_endpoint_range = -1;
  583. assert(!log_block.m_error_flag);
  584. if (log_block.m_error_flag)
  585. return false;
  586. if (log_block.m_solid_color_flag_ldr)
  587. {
  588. pack_void_extent_ldr(phys_block, log_block.m_solid_color[0], log_block.m_solid_color[1], log_block.m_solid_color[2], log_block.m_solid_color[3], pStats);
  589. return true;
  590. }
  591. else if (log_block.m_solid_color_flag_hdr)
  592. {
  593. pack_void_extent_hdr(phys_block, log_block.m_solid_color[0], log_block.m_solid_color[1], log_block.m_solid_color[2], log_block.m_solid_color[3], pStats);
  594. return true;
  595. }
  596. if ((log_block.m_num_partitions < 1) || (log_block.m_num_partitions > MAX_PARTITIONS))
  597. return false;
  598. // Max usable weight range is 11
  599. if (log_block.m_weight_ise_range > LAST_VALID_WEIGHT_ISE_RANGE)
  600. return false;
  601. // See 23.24 Illegal Encodings, [0,5] is the minimum ISE encoding for endpoints
  602. if ((log_block.m_endpoint_ise_range < FIRST_VALID_ENDPOINT_ISE_RANGE) || (log_block.m_endpoint_ise_range > LAST_VALID_ENDPOINT_ISE_RANGE))
  603. return false;
  604. if (log_block.m_color_component_selector > 3)
  605. return false;
  606. // TODO: sanity check grid width/height vs. block's physical width/height
  607. uint32_t config_bits = 0;
  608. if (!get_config_bits(log_block, config_bits))
  609. return false;
  610. uint32_t bit_pos = 0;
  611. astc_set_bits(&phys_block.m_vals[0], bit_pos, config_bits, 11);
  612. if (pStats)
  613. pStats->m_header_bits += 11;
  614. const uint32_t total_grid_weights = (log_block.m_dual_plane ? 2 : 1) * (log_block.m_grid_width * log_block.m_grid_height);
  615. const uint32_t total_weight_bits = get_ise_sequence_bits(total_grid_weights, log_block.m_weight_ise_range);
  616. // 18.24 Illegal Encodings
  617. if ((!total_grid_weights) || (total_grid_weights > MAX_GRID_WEIGHTS) || (total_weight_bits < 24) || (total_weight_bits > 96))
  618. return false;
  619. uint32_t total_extra_bits = 0;
  620. astc_set_bits(&phys_block.m_vals[0], bit_pos, log_block.m_num_partitions - 1, 2);
  621. if (pStats)
  622. pStats->m_header_bits += 2;
  623. if (log_block.m_num_partitions > 1)
  624. {
  625. if (log_block.m_partition_id >= NUM_PARTITION_PATTERNS)
  626. return false;
  627. astc_set_bits(&phys_block.m_vals[0], bit_pos, log_block.m_partition_id, 10);
  628. if (pStats)
  629. pStats->m_header_bits += 10;
  630. uint32_t highest_cem = 0, lowest_cem = UINT32_MAX;
  631. for (uint32_t j = 0; j < log_block.m_num_partitions; j++)
  632. {
  633. highest_cem = my_max<uint32_t>(highest_cem, log_block.m_color_endpoint_modes[j]);
  634. lowest_cem = my_min<uint32_t>(lowest_cem, log_block.m_color_endpoint_modes[j]);
  635. }
  636. if (highest_cem > 15)
  637. return false;
  638. // Ensure CEM range is contiguous
  639. if (((highest_cem >> 2) > (1 + (lowest_cem >> 2))))
  640. return false;
  641. // See tables 79/80
  642. uint32_t encoded_cem = log_block.m_color_endpoint_modes[0] << 2;
  643. if (lowest_cem != highest_cem)
  644. {
  645. encoded_cem = my_min<uint32_t>(3, 1 + (lowest_cem >> 2));
  646. // See tables at 23.11 Color Endpoint Mode
  647. for (uint32_t j = 0; j < log_block.m_num_partitions; j++)
  648. {
  649. const int M = log_block.m_color_endpoint_modes[j] & 3;
  650. const int C = (log_block.m_color_endpoint_modes[j] >> 2) - ((encoded_cem & 3) - 1);
  651. if ((C & 1) != C)
  652. return false;
  653. encoded_cem |= (C << (2 + j)) | (M << (2 + log_block.m_num_partitions + 2 * j));
  654. }
  655. total_extra_bits = 3 * log_block.m_num_partitions - 4;
  656. if ((total_weight_bits + total_extra_bits) > 128)
  657. return false;
  658. uint32_t cem_bit_pos = 128 - total_weight_bits - total_extra_bits;
  659. astc_set_bits(&phys_block.m_vals[0], cem_bit_pos, encoded_cem >> 6, total_extra_bits);
  660. if (pStats)
  661. pStats->m_header_bits += total_extra_bits;
  662. }
  663. astc_set_bits(&phys_block.m_vals[0], bit_pos, encoded_cem & 0x3f, 6);
  664. if (pStats)
  665. pStats->m_header_bits += 6;
  666. }
  667. else
  668. {
  669. if (log_block.m_partition_id)
  670. return false;
  671. if (log_block.m_color_endpoint_modes[0] > 15)
  672. return false;
  673. astc_set_bits(&phys_block.m_vals[0], bit_pos, log_block.m_color_endpoint_modes[0], 4);
  674. if (pStats)
  675. pStats->m_header_bits += 4;
  676. }
  677. if (log_block.m_dual_plane)
  678. {
  679. if (log_block.m_num_partitions > 3)
  680. return false;
  681. total_extra_bits += 2;
  682. uint32_t ccs_bit_pos = 128 - (int)total_weight_bits - (int)total_extra_bits;
  683. astc_set_bits(&phys_block.m_vals[0], ccs_bit_pos, log_block.m_color_component_selector, 2);
  684. if (pStats)
  685. pStats->m_header_bits += 2;
  686. }
  687. const uint32_t total_config_bits = bit_pos + total_extra_bits;
  688. const int num_remaining_bits = 128 - (int)total_config_bits - (int)total_weight_bits;
  689. if (num_remaining_bits < 0)
  690. return false;
  691. uint32_t total_cem_vals = 0;
  692. for (uint32_t j = 0; j < log_block.m_num_partitions; j++)
  693. total_cem_vals += 2 + 2 * (log_block.m_color_endpoint_modes[j] >> 2);
  694. if (total_cem_vals > MAX_ENDPOINTS)
  695. return false;
  696. int endpoint_ise_range = -1;
  697. for (int k = 20; k > 0; k--)
  698. {
  699. int bits = get_ise_sequence_bits(total_cem_vals, k);
  700. if (bits <= num_remaining_bits)
  701. {
  702. endpoint_ise_range = k;
  703. break;
  704. }
  705. }
  706. // See 23.24 Illegal Encodings, [0,5] is the minimum ISE encoding for endpoints
  707. if (endpoint_ise_range < (int)FIRST_VALID_ENDPOINT_ISE_RANGE)
  708. return false;
  709. // Ensure the caller utilized the right endpoint ISE range.
  710. if ((int)log_block.m_endpoint_ise_range != endpoint_ise_range)
  711. {
  712. if (pExpected_endpoint_range)
  713. *pExpected_endpoint_range = endpoint_ise_range;
  714. return false;
  715. }
  716. if (pStats)
  717. {
  718. pStats->m_endpoint_bits += get_ise_sequence_bits(total_cem_vals, endpoint_ise_range);
  719. pStats->m_weight_bits += get_ise_sequence_bits(total_grid_weights, log_block.m_weight_ise_range);
  720. }
  721. // Pack endpoints forwards
  722. encode_bise(&phys_block.m_vals[0], log_block.m_endpoints, bit_pos, total_cem_vals, endpoint_ise_range);
  723. // Pack weights backwards
  724. uint32_t weight_data[4] = { 0 };
  725. encode_bise(weight_data, log_block.m_weights, 0, total_grid_weights, log_block.m_weight_ise_range);
  726. for (uint32_t i = 0; i < 4; i++)
  727. phys_block.m_vals[i] |= rev_dword(weight_data[3 - i]);
  728. return true;
  729. }
  730. static inline uint32_t bit_replication_scale(uint32_t src, int num_src_bits, int num_dst_bits)
  731. {
  732. assert(num_src_bits <= num_dst_bits);
  733. assert((src & ((1 << num_src_bits) - 1)) == src);
  734. uint32_t dst = 0;
  735. for (int shift = num_dst_bits - num_src_bits; shift > -num_src_bits; shift -= num_src_bits)
  736. dst |= (shift >= 0) ? (src << shift) : (src >> -shift);
  737. return dst;
  738. }
  739. uint32_t dequant_bise_endpoint(uint32_t val, uint32_t ise_range)
  740. {
  741. assert((ise_range >= FIRST_VALID_ENDPOINT_ISE_RANGE) && (ise_range <= LAST_VALID_ENDPOINT_ISE_RANGE));
  742. assert(val < get_ise_levels(ise_range));
  743. uint32_t u = 0;
  744. switch (ise_range)
  745. {
  746. case 5:
  747. {
  748. u = bit_replication_scale(val, 3, 8);
  749. break;
  750. }
  751. case 8:
  752. {
  753. u = bit_replication_scale(val, 4, 8);
  754. break;
  755. }
  756. case 11:
  757. {
  758. u = bit_replication_scale(val, 5, 8);
  759. break;
  760. }
  761. case 14:
  762. {
  763. u = bit_replication_scale(val, 6, 8);
  764. break;
  765. }
  766. case 17:
  767. {
  768. u = bit_replication_scale(val, 7, 8);
  769. break;
  770. }
  771. case 20:
  772. {
  773. u = val;
  774. break;
  775. }
  776. case 4:
  777. case 6:
  778. case 7:
  779. case 9:
  780. case 10:
  781. case 12:
  782. case 13:
  783. case 15:
  784. case 16:
  785. case 18:
  786. case 19:
  787. {
  788. const uint32_t num_bits = g_ise_range_table[ise_range][0];
  789. const uint32_t num_trits = g_ise_range_table[ise_range][1]; BASISU_NOTE_UNUSED(num_trits);
  790. const uint32_t num_quints = g_ise_range_table[ise_range][2]; BASISU_NOTE_UNUSED(num_quints);
  791. // compute Table 103 row index
  792. const int range_index = (num_bits * 2 + (num_quints ? 1 : 0)) - 2;
  793. assert(range_index >= 0 && range_index <= 10);
  794. uint32_t bits = val & ((1 << num_bits) - 1);
  795. uint32_t tval = val >> num_bits;
  796. assert(tval < (num_trits ? 3U : 5U));
  797. uint32_t a = bits & 1;
  798. uint32_t b = (bits >> 1) & 1;
  799. uint32_t c = (bits >> 2) & 1;
  800. uint32_t d = (bits >> 3) & 1;
  801. uint32_t e = (bits >> 4) & 1;
  802. uint32_t f = (bits >> 5) & 1;
  803. uint32_t A = a ? 511 : 0;
  804. uint32_t B = 0;
  805. switch (range_index)
  806. {
  807. case 2:
  808. {
  809. // 876543210
  810. // b000b0bb0
  811. B = (b << 1) | (b << 2) | (b << 4) | (b << 8);
  812. break;
  813. }
  814. case 3:
  815. {
  816. // 876543210
  817. // b0000bb00
  818. B = (b << 2) | (b << 3) | (b << 8);
  819. break;
  820. }
  821. case 4:
  822. {
  823. // 876543210
  824. // cb000cbcb
  825. B = b | (c << 1) | (b << 2) | (c << 3) | (b << 7) | (c << 8);
  826. break;
  827. }
  828. case 5:
  829. {
  830. // 876543210
  831. // cb0000cbc
  832. B = c | (b << 1) | (c << 2) | (b << 7) | (c << 8);
  833. break;
  834. }
  835. case 6:
  836. {
  837. // 876543210
  838. // dcb000dcb
  839. B = b | (c << 1) | (d << 2) | (b << 6) | (c << 7) | (d << 8);
  840. break;
  841. }
  842. case 7:
  843. {
  844. // 876543210
  845. // dcb0000dc
  846. B = c | (d << 1) | (b << 6) | (c << 7) | (d << 8);
  847. break;
  848. }
  849. case 8:
  850. {
  851. // 876543210
  852. // edcb000ed
  853. B = d | (e << 1) | (b << 5) | (c << 6) | (d << 7) | (e << 8);
  854. break;
  855. }
  856. case 9:
  857. {
  858. // 876543210
  859. // edcb0000e
  860. B = e | (b << 5) | (c << 6) | (d << 7) | (e << 8);
  861. break;
  862. }
  863. case 10:
  864. {
  865. // 876543210
  866. // fedcb000f
  867. B = f | (b << 4) | (c << 5) | (d << 6) | (e << 7) | (f << 8);
  868. break;
  869. }
  870. default:
  871. break;
  872. }
  873. static uint8_t C_vals[11] = { 204, 113, 93, 54, 44, 26, 22, 13, 11, 6, 5 };
  874. uint32_t C = C_vals[range_index];
  875. uint32_t D = tval;
  876. u = D * C + B;
  877. u = u ^ A;
  878. u = (A & 0x80) | (u >> 2);
  879. break;
  880. }
  881. default:
  882. {
  883. assert(0);
  884. break;
  885. }
  886. }
  887. return u;
  888. }
  889. uint32_t dequant_bise_weight(uint32_t val, uint32_t ise_range)
  890. {
  891. assert(val < get_ise_levels(ise_range));
  892. uint32_t u = 0;
  893. switch (ise_range)
  894. {
  895. case 0:
  896. {
  897. u = val ? 63 : 0;
  898. break;
  899. }
  900. case 1: // 0-2
  901. {
  902. const uint8_t s_tab_0_2[3] = { 0, 32, 63 };
  903. u = s_tab_0_2[val];
  904. break;
  905. }
  906. case 2: // 0-3
  907. {
  908. u = bit_replication_scale(val, 2, 6);
  909. break;
  910. }
  911. case 3: // 0-4
  912. {
  913. const uint8_t s_tab_0_4[5] = { 0, 16, 32, 47, 63 };
  914. u = s_tab_0_4[val];
  915. break;
  916. }
  917. case 5: // 0-7
  918. {
  919. u = bit_replication_scale(val, 3, 6);
  920. break;
  921. }
  922. case 8: // 0-15
  923. {
  924. u = bit_replication_scale(val, 4, 6);
  925. break;
  926. }
  927. case 11: // 0-31
  928. {
  929. u = bit_replication_scale(val, 5, 6);
  930. break;
  931. }
  932. case 4: // 0-5
  933. case 6: // 0-9
  934. case 7: // 0-11
  935. case 9: // 0-19
  936. case 10: // 0-23
  937. {
  938. const uint32_t num_bits = g_ise_range_table[ise_range][0];
  939. const uint32_t num_trits = g_ise_range_table[ise_range][1]; BASISU_NOTE_UNUSED(num_trits);
  940. const uint32_t num_quints = g_ise_range_table[ise_range][2]; BASISU_NOTE_UNUSED(num_quints);
  941. // compute Table 103 row index
  942. const int range_index = num_bits * 2 + (num_quints ? 1 : 0);
  943. // Extract bits and tris/quints from value
  944. const uint32_t bits = val & ((1u << num_bits) - 1);
  945. const uint32_t D = val >> num_bits;
  946. assert(D < (num_trits ? 3U : 5U));
  947. // Now dequantize
  948. // See Table 103. ASTC weight unquantization parameters
  949. static const uint32_t C_table[5] = { 50, 28, 23, 13, 11 };
  950. const uint32_t a = bits & 1, b = (bits >> 1) & 1, c = (bits >> 2) & 1;
  951. const uint32_t A = (a == 0) ? 0 : 0x7F;
  952. uint32_t B = 0;
  953. if (range_index == 4)
  954. B = ((b << 6) | (b << 2) | (b << 0));
  955. else if (range_index == 5)
  956. B = ((b << 6) | (b << 1));
  957. else if (range_index == 6)
  958. B = ((c << 6) | (b << 5) | (c << 1) | (b << 0));
  959. const uint32_t C = C_table[range_index - 2];
  960. u = D * C + B;
  961. u = u ^ A;
  962. u = (A & 0x20) | (u >> 2);
  963. break;
  964. }
  965. default:
  966. assert(0);
  967. break;
  968. }
  969. if (u > 32)
  970. u++;
  971. return u;
  972. }
  973. // Returns the nearest ISE symbol given a [0,255] endpoint value.
  974. uint32_t find_nearest_bise_endpoint(int v, uint32_t ise_range)
  975. {
  976. assert(ise_range >= FIRST_VALID_ENDPOINT_ISE_RANGE && ise_range <= LAST_VALID_ENDPOINT_ISE_RANGE);
  977. const uint32_t total_levels = get_ise_levels(ise_range);
  978. int best_e = INT_MAX, best_index = 0;
  979. for (uint32_t i = 0; i < total_levels; i++)
  980. {
  981. const int qv = dequant_bise_endpoint(i, ise_range);
  982. int e = labs(v - qv);
  983. if (e < best_e)
  984. {
  985. best_e = e;
  986. best_index = i;
  987. if (!best_e)
  988. break;
  989. }
  990. }
  991. return best_index;
  992. }
  993. // Returns the nearest ISE weight given a [0,64] endpoint value.
  994. uint32_t find_nearest_bise_weight(int v, uint32_t ise_range)
  995. {
  996. assert(ise_range >= FIRST_VALID_WEIGHT_ISE_RANGE && ise_range <= LAST_VALID_WEIGHT_ISE_RANGE);
  997. assert(v <= (int)MAX_WEIGHT_VALUE);
  998. const uint32_t total_levels = get_ise_levels(ise_range);
  999. int best_e = INT_MAX, best_index = 0;
  1000. for (uint32_t i = 0; i < total_levels; i++)
  1001. {
  1002. const int qv = dequant_bise_weight(i, ise_range);
  1003. int e = labs(v - qv);
  1004. if (e < best_e)
  1005. {
  1006. best_e = e;
  1007. best_index = i;
  1008. if (!best_e)
  1009. break;
  1010. }
  1011. }
  1012. return best_index;
  1013. }
  1014. void create_quant_tables(
  1015. uint8_t* pVal_to_ise, // [0-255] or [0-64] value to nearest ISE symbol, array size is [256] or [65]
  1016. uint8_t* pISE_to_val, // ASTC encoded ISE symbol to [0,255] or [0,64] value, [levels]
  1017. uint8_t* pISE_to_rank, // returns the level rank index given an ISE symbol, [levels]
  1018. uint8_t* pRank_to_ISE, // returns the ISE symbol given a level rank, inverse of pISE_to_rank, [levels]
  1019. uint32_t ise_range, // ise range, [4,20] for endpoints, [0,11] for weights
  1020. bool weight_flag) // false if block endpoints, true if weights
  1021. {
  1022. const uint32_t num_dequant_vals = weight_flag ? (MAX_WEIGHT_VALUE + 1) : 256;
  1023. for (uint32_t i = 0; i < num_dequant_vals; i++)
  1024. {
  1025. uint32_t bise_index = weight_flag ? astc_helpers::find_nearest_bise_weight(i, ise_range) : astc_helpers::find_nearest_bise_endpoint(i, ise_range);
  1026. if (pVal_to_ise)
  1027. pVal_to_ise[i] = (uint8_t)bise_index;
  1028. if (pISE_to_val)
  1029. pISE_to_val[bise_index] = weight_flag ? (uint8_t)astc_helpers::dequant_bise_weight(bise_index, ise_range) : (uint8_t)astc_helpers::dequant_bise_endpoint(bise_index, ise_range);
  1030. }
  1031. if (pISE_to_rank || pRank_to_ISE)
  1032. {
  1033. const uint32_t num_levels = get_ise_levels(ise_range);
  1034. if (!g_ise_range_table[ise_range][1] && !g_ise_range_table[ise_range][2])
  1035. {
  1036. // Only bits
  1037. for (uint32_t i = 0; i < num_levels; i++)
  1038. {
  1039. if (pISE_to_rank)
  1040. pISE_to_rank[i] = (uint8_t)i;
  1041. if (pRank_to_ISE)
  1042. pRank_to_ISE[i] = (uint8_t)i;
  1043. }
  1044. }
  1045. else
  1046. {
  1047. // Range has trits or quints
  1048. uint32_t vals[256];
  1049. for (uint32_t i = 0; i < num_levels; i++)
  1050. {
  1051. uint32_t v = weight_flag ? astc_helpers::dequant_bise_weight(i, ise_range) : astc_helpers::dequant_bise_endpoint(i, ise_range);
  1052. // Low=ISE value
  1053. // High=dequantized value
  1054. vals[i] = (v << 16) | i;
  1055. }
  1056. // Sorts by dequantized value
  1057. std::sort(vals, vals + num_levels);
  1058. for (uint32_t rank = 0; rank < num_levels; rank++)
  1059. {
  1060. uint32_t ise_val = (uint8_t)vals[rank];
  1061. if (pISE_to_rank)
  1062. pISE_to_rank[ise_val] = (uint8_t)rank;
  1063. if (pRank_to_ISE)
  1064. pRank_to_ISE[rank] = (uint8_t)ise_val;
  1065. }
  1066. }
  1067. }
  1068. }
  1069. void pack_void_extent_ldr(astc_block &blk, uint16_t rh, uint16_t gh, uint16_t bh, uint16_t ah, pack_stats* pStats)
  1070. {
  1071. uint8_t* pDst = (uint8_t*)&blk.m_vals[0];
  1072. memset(pDst, 0xFF, 16);
  1073. pDst[0] = 0b11111100;
  1074. pDst[1] = 0b11111101;
  1075. pDst[8] = (uint8_t)rh;
  1076. pDst[9] = (uint8_t)(rh >> 8);
  1077. pDst[10] = (uint8_t)gh;
  1078. pDst[11] = (uint8_t)(gh >> 8);
  1079. pDst[12] = (uint8_t)bh;
  1080. pDst[13] = (uint8_t)(bh >> 8);
  1081. pDst[14] = (uint8_t)ah;
  1082. pDst[15] = (uint8_t)(ah >> 8);
  1083. if (pStats)
  1084. pStats->m_header_bits += 128;
  1085. }
  1086. // rh-ah are half-floats
  1087. void pack_void_extent_hdr(astc_block& blk, uint16_t rh, uint16_t gh, uint16_t bh, uint16_t ah, pack_stats *pStats)
  1088. {
  1089. uint8_t* pDst = (uint8_t*)&blk.m_vals[0];
  1090. memset(pDst, 0xFF, 16);
  1091. pDst[0] = 0b11111100;
  1092. pDst[8] = (uint8_t)rh;
  1093. pDst[9] = (uint8_t)(rh >> 8);
  1094. pDst[10] = (uint8_t)gh;
  1095. pDst[11] = (uint8_t)(gh >> 8);
  1096. pDst[12] = (uint8_t)bh;
  1097. pDst[13] = (uint8_t)(bh >> 8);
  1098. pDst[14] = (uint8_t)ah;
  1099. pDst[15] = (uint8_t)(ah >> 8);
  1100. if (pStats)
  1101. pStats->m_header_bits += 128;
  1102. }
  1103. bool is_cem_ldr(uint32_t mode)
  1104. {
  1105. switch (mode)
  1106. {
  1107. case CEM_LDR_LUM_DIRECT:
  1108. case CEM_LDR_LUM_BASE_PLUS_OFS:
  1109. case CEM_LDR_LUM_ALPHA_DIRECT:
  1110. case CEM_LDR_LUM_ALPHA_BASE_PLUS_OFS:
  1111. case CEM_LDR_RGB_BASE_SCALE:
  1112. case CEM_LDR_RGB_DIRECT:
  1113. case CEM_LDR_RGB_BASE_PLUS_OFFSET:
  1114. case CEM_LDR_RGB_BASE_SCALE_PLUS_TWO_A:
  1115. case CEM_LDR_RGBA_DIRECT:
  1116. case CEM_LDR_RGBA_BASE_PLUS_OFFSET:
  1117. return true;
  1118. default:
  1119. break;
  1120. }
  1121. return false;
  1122. }
  1123. bool is_valid_block_size(uint32_t w, uint32_t h)
  1124. {
  1125. assert((w >= MIN_BLOCK_DIM) && (w <= MAX_BLOCK_DIM));
  1126. assert((h >= MIN_BLOCK_DIM) && (h <= MAX_BLOCK_DIM));
  1127. #define SIZECHK(x, y) if ((w == (x)) && (h == (y))) return true;
  1128. SIZECHK(4, 4);
  1129. SIZECHK(5, 4);
  1130. SIZECHK(5, 5);
  1131. SIZECHK(6, 5);
  1132. SIZECHK(6, 6);
  1133. SIZECHK(8, 5);
  1134. SIZECHK(8, 6);
  1135. SIZECHK(10, 5);
  1136. SIZECHK(10, 6);
  1137. SIZECHK(8, 8);
  1138. SIZECHK(10, 8);
  1139. SIZECHK(10, 10);
  1140. SIZECHK(12, 10);
  1141. SIZECHK(12, 12);
  1142. #undef SIZECHK
  1143. return false;
  1144. }
  1145. bool block_has_any_hdr_cems(const log_astc_block& log_blk)
  1146. {
  1147. assert((log_blk.m_num_partitions >= 1) && (log_blk.m_num_partitions <= MAX_PARTITIONS));
  1148. for (uint32_t i = 0; i < log_blk.m_num_partitions; i++)
  1149. if (is_cem_hdr(log_blk.m_color_endpoint_modes[i]))
  1150. return true;
  1151. return false;
  1152. }
  1153. bool block_has_any_ldr_cems(const log_astc_block& log_blk)
  1154. {
  1155. assert((log_blk.m_num_partitions >= 1) && (log_blk.m_num_partitions <= MAX_PARTITIONS));
  1156. for (uint32_t i = 0; i < log_blk.m_num_partitions; i++)
  1157. if (!is_cem_hdr(log_blk.m_color_endpoint_modes[i]))
  1158. return true;
  1159. return false;
  1160. }
  1161. dequant_tables g_dequant_tables;
  1162. void precompute_texel_partitions_4x4();
  1163. void precompute_texel_partitions_6x6();
  1164. void init_tables(bool init_rank_tabs)
  1165. {
  1166. g_dequant_tables.init(init_rank_tabs);
  1167. precompute_texel_partitions_4x4();
  1168. precompute_texel_partitions_6x6();
  1169. }
  1170. void compute_upsample_weights(
  1171. int block_width, int block_height,
  1172. int weight_grid_width, int weight_grid_height,
  1173. weighted_sample* pWeights) // there will be block_width * block_height bilinear samples
  1174. {
  1175. const uint32_t scaleX = (1024 + block_width / 2) / (block_width - 1);
  1176. const uint32_t scaleY = (1024 + block_height / 2) / (block_height - 1);
  1177. for (int texelY = 0; texelY < block_height; texelY++)
  1178. {
  1179. for (int texelX = 0; texelX < block_width; texelX++)
  1180. {
  1181. const uint32_t gX = (scaleX * texelX * (weight_grid_width - 1) + 32) >> 6;
  1182. const uint32_t gY = (scaleY * texelY * (weight_grid_height - 1) + 32) >> 6;
  1183. const uint32_t jX = gX >> 4;
  1184. const uint32_t jY = gY >> 4;
  1185. const uint32_t fX = gX & 0xf;
  1186. const uint32_t fY = gY & 0xf;
  1187. const uint32_t w11 = (fX * fY + 8) >> 4;
  1188. const uint32_t w10 = fY - w11;
  1189. const uint32_t w01 = fX - w11;
  1190. const uint32_t w00 = 16 - fX - fY + w11;
  1191. weighted_sample& s = pWeights[texelX + texelY * block_width];
  1192. s.m_src_x = (uint8_t)jX;
  1193. s.m_src_y = (uint8_t)jY;
  1194. s.m_weights[0][0] = (uint8_t)w00;
  1195. s.m_weights[0][1] = (uint8_t)w01;
  1196. s.m_weights[1][0] = (uint8_t)w10;
  1197. s.m_weights[1][1] = (uint8_t)w11;
  1198. }
  1199. }
  1200. }
  1201. // Should be dequantized [0,64] weights
  1202. void upsample_weight_grid(
  1203. uint32_t bx, uint32_t by, // destination/to dimension
  1204. uint32_t wx, uint32_t wy, // source/from dimension
  1205. const uint8_t* pSrc_weights, // these are dequantized [0,64] weights, NOT ISE symbols, [wy][wx]
  1206. uint8_t* pDst_weights) // [by][bx]
  1207. {
  1208. assert((bx >= 2) && (by >= 2) && (bx <= 12) && (by <= 12));
  1209. assert((wx >= 2) && (wy >= 2) && (wx <= bx) && (wy <= by));
  1210. const uint32_t total_src_weights = wx * wy;
  1211. const uint32_t total_dst_weights = bx * by;
  1212. if (total_src_weights == total_dst_weights)
  1213. {
  1214. memcpy(pDst_weights, pSrc_weights, total_src_weights);
  1215. return;
  1216. }
  1217. weighted_sample weights[12 * 12];
  1218. compute_upsample_weights(bx, by, wx, wy, weights);
  1219. const weighted_sample* pS = weights;
  1220. for (uint32_t y = 0; y < by; y++)
  1221. {
  1222. for (uint32_t x = 0; x < bx; x++, ++pS)
  1223. {
  1224. const uint32_t w00 = pS->m_weights[0][0];
  1225. const uint32_t w01 = pS->m_weights[0][1];
  1226. const uint32_t w10 = pS->m_weights[1][0];
  1227. const uint32_t w11 = pS->m_weights[1][1];
  1228. assert(w00 || w01 || w10 || w11);
  1229. const uint32_t sx = pS->m_src_x, sy = pS->m_src_y;
  1230. uint32_t total = 8;
  1231. if (w00) total += pSrc_weights[bounds_check(sx + sy * wx, 0U, total_src_weights)] * w00;
  1232. if (w01) total += pSrc_weights[bounds_check(sx + 1 + sy * wx, 0U, total_src_weights)] * w01;
  1233. if (w10) total += pSrc_weights[bounds_check(sx + (sy + 1) * wx, 0U, total_src_weights)] * w10;
  1234. if (w11) total += pSrc_weights[bounds_check(sx + 1 + (sy + 1) * wx, 0U, total_src_weights)] * w11;
  1235. pDst_weights[x + y * bx] = (uint8_t)(total >> 4);
  1236. }
  1237. }
  1238. }
  1239. inline uint32_t hash52(uint32_t v)
  1240. {
  1241. uint32_t p = v;
  1242. p ^= p >> 15; p -= p << 17; p += p << 7; p += p << 4;
  1243. p ^= p >> 5; p += p << 16; p ^= p >> 7; p ^= p >> 3;
  1244. p ^= p << 6; p ^= p >> 17;
  1245. return p;
  1246. }
  1247. // small_block = num_blk_pixels < 31
  1248. int compute_texel_partition(uint32_t seedIn, uint32_t xIn, uint32_t yIn, uint32_t zIn, int num_partitions, bool small_block)
  1249. {
  1250. assert(zIn == 0);
  1251. const uint32_t x = small_block ? xIn << 1 : xIn;
  1252. const uint32_t y = small_block ? yIn << 1 : yIn;
  1253. const uint32_t z = small_block ? zIn << 1 : zIn;
  1254. const uint32_t seed = seedIn + 1024 * (num_partitions - 1);
  1255. const uint32_t rnum = hash52(seed);
  1256. uint8_t seed1 = (uint8_t)(rnum & 0xf);
  1257. uint8_t seed2 = (uint8_t)((rnum >> 4) & 0xf);
  1258. uint8_t seed3 = (uint8_t)((rnum >> 8) & 0xf);
  1259. uint8_t seed4 = (uint8_t)((rnum >> 12) & 0xf);
  1260. uint8_t seed5 = (uint8_t)((rnum >> 16) & 0xf);
  1261. uint8_t seed6 = (uint8_t)((rnum >> 20) & 0xf);
  1262. uint8_t seed7 = (uint8_t)((rnum >> 24) & 0xf);
  1263. uint8_t seed8 = (uint8_t)((rnum >> 28) & 0xf);
  1264. uint8_t seed9 = (uint8_t)((rnum >> 18) & 0xf);
  1265. uint8_t seed10 = (uint8_t)((rnum >> 22) & 0xf);
  1266. uint8_t seed11 = (uint8_t)((rnum >> 26) & 0xf);
  1267. uint8_t seed12 = (uint8_t)(((rnum >> 30) | (rnum << 2)) & 0xf);
  1268. seed1 = (uint8_t)(seed1 * seed1);
  1269. seed2 = (uint8_t)(seed2 * seed2);
  1270. seed3 = (uint8_t)(seed3 * seed3);
  1271. seed4 = (uint8_t)(seed4 * seed4);
  1272. seed5 = (uint8_t)(seed5 * seed5);
  1273. seed6 = (uint8_t)(seed6 * seed6);
  1274. seed7 = (uint8_t)(seed7 * seed7);
  1275. seed8 = (uint8_t)(seed8 * seed8);
  1276. seed9 = (uint8_t)(seed9 * seed9);
  1277. seed10 = (uint8_t)(seed10 * seed10);
  1278. seed11 = (uint8_t)(seed11 * seed11);
  1279. seed12 = (uint8_t)(seed12 * seed12);
  1280. const int shA = (seed & 2) != 0 ? 4 : 5;
  1281. const int shB = (num_partitions == 3) ? 6 : 5;
  1282. const int sh1 = (seed & 1) != 0 ? shA : shB;
  1283. const int sh2 = (seed & 1) != 0 ? shB : shA;
  1284. const int sh3 = (seed & 0x10) != 0 ? sh1 : sh2;
  1285. seed1 = (uint8_t)(seed1 >> sh1);
  1286. seed2 = (uint8_t)(seed2 >> sh2);
  1287. seed3 = (uint8_t)(seed3 >> sh1);
  1288. seed4 = (uint8_t)(seed4 >> sh2);
  1289. seed5 = (uint8_t)(seed5 >> sh1);
  1290. seed6 = (uint8_t)(seed6 >> sh2);
  1291. seed7 = (uint8_t)(seed7 >> sh1);
  1292. seed8 = (uint8_t)(seed8 >> sh2);
  1293. seed9 = (uint8_t)(seed9 >> sh3);
  1294. seed10 = (uint8_t)(seed10 >> sh3);
  1295. seed11 = (uint8_t)(seed11 >> sh3);
  1296. seed12 = (uint8_t)(seed12 >> sh3);
  1297. const int a = 0x3f & (seed1 * x + seed2 * y + seed11 * z + (rnum >> 14));
  1298. const int b = 0x3f & (seed3 * x + seed4 * y + seed12 * z + (rnum >> 10));
  1299. const int c = (num_partitions >= 3) ? 0x3f & (seed5 * x + seed6 * y + seed9 * z + (rnum >> 6)) : 0;
  1300. const int d = (num_partitions >= 4) ? 0x3f & (seed7 * x + seed8 * y + seed10 * z + (rnum >> 2)) : 0;
  1301. return (a >= b && a >= c && a >= d) ? 0
  1302. : (b >= c && b >= d) ? 1
  1303. : (c >= d) ? 2
  1304. : 3;
  1305. }
  1306. // 4x4, 2 and 3 subsets
  1307. static uint32_t g_texel_partitions_4x4[1024][2];
  1308. // 6x6, 2 and 3 subsets (2 subsets low 4 bits, 3 subsets high 4 bits)
  1309. static uint8_t g_texel_partitions_6x6[1024][6 * 6];
  1310. void precompute_texel_partitions_4x4()
  1311. {
  1312. for (uint32_t p = 0; p < 1024; p++)
  1313. {
  1314. uint32_t v2 = 0, v3 = 0;
  1315. for (uint32_t y = 0; y < 4; y++)
  1316. {
  1317. for (uint32_t x = 0; x < 4; x++)
  1318. {
  1319. const uint32_t shift = x * 2 + y * 8;
  1320. v2 |= (compute_texel_partition(p, x, y, 0, 2, true) << shift);
  1321. v3 |= (compute_texel_partition(p, x, y, 0, 3, true) << shift);
  1322. }
  1323. }
  1324. g_texel_partitions_4x4[p][0] = v2;
  1325. g_texel_partitions_4x4[p][1] = v3;
  1326. }
  1327. }
  1328. void precompute_texel_partitions_6x6()
  1329. {
  1330. for (uint32_t p = 0; p < 1024; p++)
  1331. {
  1332. for (uint32_t y = 0; y < 6; y++)
  1333. {
  1334. for (uint32_t x = 0; x < 6; x++)
  1335. {
  1336. const uint32_t p2 = compute_texel_partition(p, x, y, 0, 2, false);
  1337. const uint32_t p3 = compute_texel_partition(p, x, y, 0, 3, false);
  1338. assert((p2 <= 1) && (p3 <= 2));
  1339. g_texel_partitions_6x6[p][x + y * 6] = (uint8_t)((p3 << 4) | p2);
  1340. }
  1341. }
  1342. }
  1343. }
  1344. static inline int get_precompute_texel_partitions_4x4(uint32_t seed, uint32_t x, uint32_t y, uint32_t num_partitions)
  1345. {
  1346. assert(g_texel_partitions_4x4[1][0]);
  1347. assert(seed < 1024);
  1348. assert((x <= 3) && (y <= 3));
  1349. assert((num_partitions >= 2) && (num_partitions <= 3));
  1350. const uint32_t shift = x * 2 + y * 8;
  1351. return (g_texel_partitions_4x4[seed][num_partitions - 2] >> shift) & 3;
  1352. }
  1353. static inline int get_precompute_texel_partitions_6x6(uint32_t seed, uint32_t x, uint32_t y, uint32_t num_partitions)
  1354. {
  1355. assert(g_texel_partitions_6x6[0][0]);
  1356. assert(seed < 1024);
  1357. assert((x <= 5) && (y <= 5));
  1358. assert((num_partitions >= 2) && (num_partitions <= 3));
  1359. const uint32_t shift = (num_partitions == 3) ? 4 : 0;
  1360. return (g_texel_partitions_6x6[seed][x + y * 6] >> shift) & 3;
  1361. }
  1362. void blue_contract(
  1363. int r, int g, int b, int a,
  1364. int &dr, int &dg, int &db, int &da)
  1365. {
  1366. dr = (r + b) >> 1;
  1367. dg = (g + b) >> 1;
  1368. db = b;
  1369. da = a;
  1370. }
  1371. inline void bit_transfer_signed(int& a, int& b)
  1372. {
  1373. b >>= 1;
  1374. b |= (a & 0x80);
  1375. a >>= 1;
  1376. a &= 0x3F;
  1377. if ((a & 0x20) != 0)
  1378. a -= 0x40;
  1379. }
  1380. static inline int clamp(int a, int l, int h)
  1381. {
  1382. if (a < l)
  1383. a = l;
  1384. else if (a > h)
  1385. a = h;
  1386. return a;
  1387. }
  1388. static inline float clampf(float a, float l, float h)
  1389. {
  1390. if (a < l)
  1391. a = l;
  1392. else if (a > h)
  1393. a = h;
  1394. return a;
  1395. }
  1396. inline int sign_extend(int src, int num_src_bits)
  1397. {
  1398. assert((num_src_bits >= 2) && (num_src_bits <= 31));
  1399. const bool negative = (src & (1 << (num_src_bits - 1))) != 0;
  1400. if (negative)
  1401. return src | ~((1 << num_src_bits) - 1);
  1402. else
  1403. return src & ((1 << num_src_bits) - 1);
  1404. }
  1405. // endpoints is [4][2]
  1406. void decode_endpoint(uint32_t cem_index, int (*pEndpoints)[2], const uint8_t *pE)
  1407. {
  1408. assert(cem_index <= CEM_HDR_RGB_HDR_ALPHA);
  1409. int v0 = pE[0], v1 = pE[1];
  1410. int& e0_r = pEndpoints[0][0], &e0_g = pEndpoints[1][0], &e0_b = pEndpoints[2][0], &e0_a = pEndpoints[3][0];
  1411. int& e1_r = pEndpoints[0][1], &e1_g = pEndpoints[1][1], &e1_b = pEndpoints[2][1], &e1_a = pEndpoints[3][1];
  1412. switch (cem_index)
  1413. {
  1414. case CEM_LDR_LUM_DIRECT:
  1415. {
  1416. e0_r = v0; e1_r = v1;
  1417. e0_g = v0; e1_g = v1;
  1418. e0_b = v0; e1_b = v1;
  1419. e0_a = 0xFF; e1_a = 0xFF;
  1420. break;
  1421. }
  1422. case CEM_LDR_LUM_BASE_PLUS_OFS:
  1423. {
  1424. int l0 = (v0 >> 2) | (v1 & 0xc0);
  1425. int l1 = l0 + (v1 & 0x3f);
  1426. if (l1 > 0xFF)
  1427. l1 = 0xFF;
  1428. e0_r = l0; e1_r = l1;
  1429. e0_g = l0; e1_g = l1;
  1430. e0_b = l0; e1_b = l1;
  1431. e0_a = 0xFF; e1_a = 0xFF;
  1432. break;
  1433. }
  1434. case CEM_LDR_LUM_ALPHA_DIRECT:
  1435. {
  1436. int v2 = pE[2], v3 = pE[3];
  1437. e0_r = v0; e1_r = v1;
  1438. e0_g = v0; e1_g = v1;
  1439. e0_b = v0; e1_b = v1;
  1440. e0_a = v2; e1_a = v3;
  1441. break;
  1442. }
  1443. case CEM_LDR_LUM_ALPHA_BASE_PLUS_OFS:
  1444. {
  1445. int v2 = pE[2], v3 = pE[3];
  1446. bit_transfer_signed(v1, v0);
  1447. bit_transfer_signed(v3, v2);
  1448. e0_r = v0; e1_r = v0 + v1;
  1449. e0_g = v0; e1_g = v0 + v1;
  1450. e0_b = v0; e1_b = v0 + v1;
  1451. e0_a = v2; e1_a = v2 + v3;
  1452. for (uint32_t c = 0; c < 4; c++)
  1453. {
  1454. pEndpoints[c][0] = clamp(pEndpoints[c][0], 0, 255);
  1455. pEndpoints[c][1] = clamp(pEndpoints[c][1], 0, 255);
  1456. }
  1457. break;
  1458. }
  1459. case CEM_LDR_RGB_BASE_SCALE:
  1460. {
  1461. int v2 = pE[2], v3 = pE[3];
  1462. e0_r = (v0 * v3) >> 8; e1_r = v0;
  1463. e0_g = (v1 * v3) >> 8; e1_g = v1;
  1464. e0_b = (v2 * v3) >> 8; e1_b = v2;
  1465. e0_a = 0xFF; e1_a = 0xFF;
  1466. break;
  1467. }
  1468. case CEM_LDR_RGB_DIRECT:
  1469. {
  1470. int v2 = pE[2], v3 = pE[3], v4 = pE[4], v5 = pE[5];
  1471. if ((v1 + v3 + v5) >= (v0 + v2 + v4))
  1472. {
  1473. e0_r = v0; e1_r = v1;
  1474. e0_g = v2; e1_g = v3;
  1475. e0_b = v4; e1_b = v5;
  1476. e0_a = 0xFF; e1_a = 0xFF;
  1477. }
  1478. else
  1479. {
  1480. blue_contract(v1, v3, v5, 0xFF, e0_r, e0_g, e0_b, e0_a);
  1481. blue_contract(v0, v2, v4, 0xFF, e1_r, e1_g, e1_b, e1_a);
  1482. }
  1483. break;
  1484. }
  1485. case CEM_LDR_RGB_BASE_PLUS_OFFSET:
  1486. {
  1487. int v2 = pE[2], v3 = pE[3], v4 = pE[4], v5 = pE[5];
  1488. bit_transfer_signed(v1, v0);
  1489. bit_transfer_signed(v3, v2);
  1490. bit_transfer_signed(v5, v4);
  1491. if ((v1 + v3 + v5) >= 0)
  1492. {
  1493. e0_r = v0; e1_r = v0 + v1;
  1494. e0_g = v2; e1_g = v2 + v3;
  1495. e0_b = v4; e1_b = v4 + v5;
  1496. e0_a = 0xFF; e1_a = 0xFF;
  1497. }
  1498. else
  1499. {
  1500. blue_contract(v0 + v1, v2 + v3, v4 + v5, 0xFF, e0_r, e0_g, e0_b, e0_a);
  1501. blue_contract(v0, v2, v4, 0xFF, e1_r, e1_g, e1_b, e1_a);
  1502. }
  1503. for (uint32_t c = 0; c < 4; c++)
  1504. {
  1505. pEndpoints[c][0] = clamp(pEndpoints[c][0], 0, 255);
  1506. pEndpoints[c][1] = clamp(pEndpoints[c][1], 0, 255);
  1507. }
  1508. break;
  1509. }
  1510. case CEM_LDR_RGB_BASE_SCALE_PLUS_TWO_A:
  1511. {
  1512. int v2 = pE[2], v3 = pE[3], v4 = pE[4], v5 = pE[5];
  1513. e0_r = (v0 * v3) >> 8; e1_r = v0;
  1514. e0_g = (v1 * v3) >> 8; e1_g = v1;
  1515. e0_b = (v2 * v3) >> 8; e1_b = v2;
  1516. e0_a = v4; e1_a = v5;
  1517. break;
  1518. }
  1519. case CEM_LDR_RGBA_DIRECT:
  1520. {
  1521. int v2 = pE[2], v3 = pE[3], v4 = pE[4], v5 = pE[5], v6 = pE[6], v7 = pE[7];
  1522. if ((v1 + v3 + v5) >= (v0 + v2 + v4))
  1523. {
  1524. e0_r = v0; e1_r = v1;
  1525. e0_g = v2; e1_g = v3;
  1526. e0_b = v4; e1_b = v5;
  1527. e0_a = v6; e1_a = v7;
  1528. }
  1529. else
  1530. {
  1531. blue_contract(v1, v3, v5, v7, e0_r, e0_g, e0_b, e0_a);
  1532. blue_contract(v0, v2, v4, v6, e1_r, e1_g, e1_b, e1_a);
  1533. }
  1534. break;
  1535. }
  1536. case CEM_LDR_RGBA_BASE_PLUS_OFFSET:
  1537. {
  1538. int v2 = pE[2], v3 = pE[3], v4 = pE[4], v5 = pE[5], v6 = pE[6], v7 = pE[7];
  1539. bit_transfer_signed(v1, v0);
  1540. bit_transfer_signed(v3, v2);
  1541. bit_transfer_signed(v5, v4);
  1542. bit_transfer_signed(v7, v6);
  1543. if ((v1 + v3 + v5) >= 0)
  1544. {
  1545. e0_r = v0; e1_r = v0 + v1;
  1546. e0_g = v2; e1_g = v2 + v3;
  1547. e0_b = v4; e1_b = v4 + v5;
  1548. e0_a = v6; e1_a = v6 + v7;
  1549. }
  1550. else
  1551. {
  1552. blue_contract(v0 + v1, v2 + v3, v4 + v5, v6 + v7, e0_r, e0_g, e0_b, e0_a);
  1553. blue_contract(v0, v2, v4, v6, e1_r, e1_g, e1_b, e1_a);
  1554. }
  1555. for (uint32_t c = 0; c < 4; c++)
  1556. {
  1557. pEndpoints[c][0] = clamp(pEndpoints[c][0], 0, 255);
  1558. pEndpoints[c][1] = clamp(pEndpoints[c][1], 0, 255);
  1559. }
  1560. break;
  1561. }
  1562. case CEM_HDR_LUM_LARGE_RANGE:
  1563. {
  1564. int y0, y1;
  1565. if (v1 >= v0)
  1566. {
  1567. y0 = (v0 << 4);
  1568. y1 = (v1 << 4);
  1569. }
  1570. else
  1571. {
  1572. y0 = (v1 << 4) + 8;
  1573. y1 = (v0 << 4) - 8;
  1574. }
  1575. e0_r = y0; e1_r = y1;
  1576. e0_g = y0; e1_g = y1;
  1577. e0_b = y0; e1_b = y1;
  1578. e0_a = 0x780; e1_a = 0x780;
  1579. break;
  1580. }
  1581. case CEM_HDR_LUM_SMALL_RANGE:
  1582. {
  1583. int y0, y1, d;
  1584. if ((v0 & 0x80) != 0)
  1585. {
  1586. y0 = ((v1 & 0xE0) << 4) | ((v0 & 0x7F) << 2);
  1587. d = (v1 & 0x1F) << 2;
  1588. }
  1589. else
  1590. {
  1591. y0 = ((v1 & 0xF0) << 4) | ((v0 & 0x7F) << 1);
  1592. d = (v1 & 0x0F) << 1;
  1593. }
  1594. y1 = y0 + d;
  1595. if (y1 > 0xFFF)
  1596. y1 = 0xFFF;
  1597. e0_r = y0; e1_r = y1;
  1598. e0_g = y0; e1_g = y1;
  1599. e0_b = y0; e1_b = y1;
  1600. e0_a = 0x780; e1_a = 0x780;
  1601. break;
  1602. }
  1603. case CEM_HDR_RGB_BASE_SCALE:
  1604. {
  1605. int v2 = pE[2], v3 = pE[3];
  1606. int modeval = ((v0 & 0xC0) >> 6) | ((v1 & 0x80) >> 5) | ((v2 & 0x80) >> 4);
  1607. int majcomp, mode;
  1608. if ((modeval & 0xC) != 0xC)
  1609. {
  1610. majcomp = modeval >> 2;
  1611. mode = modeval & 3;
  1612. }
  1613. else if (modeval != 0xF)
  1614. {
  1615. majcomp = modeval & 3;
  1616. mode = 4;
  1617. }
  1618. else
  1619. {
  1620. majcomp = 0;
  1621. mode = 5;
  1622. }
  1623. int red = v0 & 0x3f;
  1624. int green = v1 & 0x1f;
  1625. int blue = v2 & 0x1f;
  1626. int scale = v3 & 0x1f;
  1627. int x0 = (v1 >> 6) & 1;
  1628. int x1 = (v1 >> 5) & 1;
  1629. int x2 = (v2 >> 6) & 1;
  1630. int x3 = (v2 >> 5) & 1;
  1631. int x4 = (v3 >> 7) & 1;
  1632. int x5 = (v3 >> 6) & 1;
  1633. int x6 = (v3 >> 5) & 1;
  1634. int ohm = 1 << mode;
  1635. if (ohm & 0x30) green |= x0 << 6;
  1636. if (ohm & 0x3A) green |= x1 << 5;
  1637. if (ohm & 0x30) blue |= x2 << 6;
  1638. if (ohm & 0x3A) blue |= x3 << 5;
  1639. if (ohm & 0x3D) scale |= x6 << 5;
  1640. if (ohm & 0x2D) scale |= x5 << 6;
  1641. if (ohm & 0x04) scale |= x4 << 7;
  1642. if (ohm & 0x3B) red |= x4 << 6;
  1643. if (ohm & 0x04) red |= x3 << 6;
  1644. if (ohm & 0x10) red |= x5 << 7;
  1645. if (ohm & 0x0F) red |= x2 << 7;
  1646. if (ohm & 0x05) red |= x1 << 8;
  1647. if (ohm & 0x0A) red |= x0 << 8;
  1648. if (ohm & 0x05) red |= x0 << 9;
  1649. if (ohm & 0x02) red |= x6 << 9;
  1650. if (ohm & 0x01) red |= x3 << 10;
  1651. if (ohm & 0x02) red |= x5 << 10;
  1652. static const int s_shamts[6] = { 1,1,2,3,4,5 };
  1653. const int shamt = s_shamts[mode];
  1654. red <<= shamt;
  1655. green <<= shamt;
  1656. blue <<= shamt;
  1657. scale <<= shamt;
  1658. if (mode != 5)
  1659. {
  1660. green = red - green;
  1661. blue = red - blue;
  1662. }
  1663. if (majcomp == 1)
  1664. std::swap(red, green);
  1665. if (majcomp == 2)
  1666. std::swap(red, blue);
  1667. e1_r = clamp(red, 0, 0xFFF);
  1668. e1_g = clamp(green, 0, 0xFFF);
  1669. e1_b = clamp(blue, 0, 0xFFF);
  1670. e1_a = 0x780;
  1671. e0_r = clamp(red - scale, 0, 0xFFF);
  1672. e0_g = clamp(green - scale, 0, 0xFFF);
  1673. e0_b = clamp(blue - scale, 0, 0xFFF);
  1674. e0_a = 0x780;
  1675. break;
  1676. }
  1677. case CEM_HDR_RGB_HDR_ALPHA:
  1678. case CEM_HDR_RGB_LDR_ALPHA:
  1679. case CEM_HDR_RGB:
  1680. {
  1681. int v2 = pE[2], v3 = pE[3], v4 = pE[4], v5 = pE[5];
  1682. int majcomp = ((v4 & 0x80) >> 7) | ((v5 & 0x80) >> 6);
  1683. e0_a = 0x780;
  1684. e1_a = 0x780;
  1685. if (majcomp == 3)
  1686. {
  1687. e0_r = v0 << 4;
  1688. e0_g = v2 << 4;
  1689. e0_b = (v4 & 0x7f) << 5;
  1690. e1_r = v1 << 4;
  1691. e1_g = v3 << 4;
  1692. e1_b = (v5 & 0x7f) << 5;
  1693. }
  1694. else
  1695. {
  1696. int mode = ((v1 & 0x80) >> 7) | ((v2 & 0x80) >> 6) | ((v3 & 0x80) >> 5);
  1697. int va = v0 | ((v1 & 0x40) << 2);
  1698. int vb0 = v2 & 0x3f;
  1699. int vb1 = v3 & 0x3f;
  1700. int vc = v1 & 0x3f;
  1701. int vd0 = v4 & 0x7f;
  1702. int vd1 = v5 & 0x7f;
  1703. static const int s_dbitstab[8] = { 7,6,7,6,5,6,5,6 };
  1704. vd0 = sign_extend(vd0, s_dbitstab[mode]);
  1705. vd1 = sign_extend(vd1, s_dbitstab[mode]);
  1706. int x0 = (v2 >> 6) & 1;
  1707. int x1 = (v3 >> 6) & 1;
  1708. int x2 = (v4 >> 6) & 1;
  1709. int x3 = (v5 >> 6) & 1;
  1710. int x4 = (v4 >> 5) & 1;
  1711. int x5 = (v5 >> 5) & 1;
  1712. int ohm = 1 << mode;
  1713. if (ohm & 0xA4) va |= x0 << 9;
  1714. if (ohm & 0x08) va |= x2 << 9;
  1715. if (ohm & 0x50) va |= x4 << 9;
  1716. if (ohm & 0x50) va |= x5 << 10;
  1717. if (ohm & 0xA0) va |= x1 << 10;
  1718. if (ohm & 0xC0) va |= x2 << 11;
  1719. if (ohm & 0x04) vc |= x1 << 6;
  1720. if (ohm & 0xE8) vc |= x3 << 6;
  1721. if (ohm & 0x20) vc |= x2 << 7;
  1722. if (ohm & 0x5B) vb0 |= x0 << 6;
  1723. if (ohm & 0x5B) vb1 |= x1 << 6;
  1724. if (ohm & 0x12) vb0 |= x2 << 7;
  1725. if (ohm & 0x12) vb1 |= x3 << 7;
  1726. int shamt = (mode >> 1) ^ 3;
  1727. va = (uint32_t)va << shamt;
  1728. vb0 = (uint32_t)vb0 << shamt;
  1729. vb1 = (uint32_t)vb1 << shamt;
  1730. vc = (uint32_t)vc << shamt;
  1731. vd0 = (uint32_t)vd0 << shamt;
  1732. vd1 = (uint32_t)vd1 << shamt;
  1733. e1_r = clamp(va, 0, 0xFFF);
  1734. e1_g = clamp(va - vb0, 0, 0xFFF);
  1735. e1_b = clamp(va - vb1, 0, 0xFFF);
  1736. e0_r = clamp(va - vc, 0, 0xFFF);
  1737. e0_g = clamp(va - vb0 - vc - vd0, 0, 0xFFF);
  1738. e0_b = clamp(va - vb1 - vc - vd1, 0, 0xFFF);
  1739. if (majcomp == 1)
  1740. {
  1741. std::swap(e0_r, e0_g);
  1742. std::swap(e1_r, e1_g);
  1743. }
  1744. else if (majcomp == 2)
  1745. {
  1746. std::swap(e0_r, e0_b);
  1747. std::swap(e1_r, e1_b);
  1748. }
  1749. }
  1750. if (cem_index == CEM_HDR_RGB_LDR_ALPHA)
  1751. {
  1752. int v6 = pE[6], v7 = pE[7];
  1753. e0_a = v6;
  1754. e1_a = v7;
  1755. }
  1756. else if (cem_index == CEM_HDR_RGB_HDR_ALPHA)
  1757. {
  1758. int v6 = pE[6], v7 = pE[7];
  1759. // Extract mode bits
  1760. int mode = ((v6 >> 7) & 1) | ((v7 >> 6) & 2);
  1761. v6 &= 0x7F;
  1762. v7 &= 0x7F;
  1763. if (mode == 3)
  1764. {
  1765. e0_a = v6 << 5;
  1766. e1_a = v7 << 5;
  1767. }
  1768. else
  1769. {
  1770. v6 |= (v7 << (mode + 1)) & 0x780;
  1771. v7 &= (0x3F >> mode);
  1772. v7 ^= (0x20 >> mode);
  1773. v7 -= (0x20 >> mode);
  1774. v6 <<= (4 - mode);
  1775. v7 <<= (4 - mode);
  1776. v7 += v6;
  1777. v7 = clamp(v7, 0, 0xFFF);
  1778. e0_a = v6;
  1779. e1_a = v7;
  1780. }
  1781. }
  1782. break;
  1783. }
  1784. default:
  1785. {
  1786. assert(0);
  1787. for (uint32_t c = 0; c < 4; c++)
  1788. {
  1789. pEndpoints[c][0] = 0;
  1790. pEndpoints[c][1] = 0;
  1791. }
  1792. break;
  1793. }
  1794. }
  1795. }
  1796. static inline bool is_half_inf_or_nan(half_float v)
  1797. {
  1798. return get_bits(v, 10, 14) == 31;
  1799. }
  1800. // This float->half conversion matches how "F32TO16" works on Intel GPU's.
  1801. half_float float_to_half(float val, bool toward_zero)
  1802. {
  1803. union { float f; int32_t i; uint32_t u; } fi = { val };
  1804. const int flt_m = fi.i & 0x7FFFFF, flt_e = (fi.i >> 23) & 0xFF, flt_s = (fi.i >> 31) & 0x1;
  1805. int s = flt_s, e = 0, m = 0;
  1806. // inf/NaN
  1807. if (flt_e == 0xff)
  1808. {
  1809. e = 31;
  1810. if (flt_m != 0) // NaN
  1811. m = 1;
  1812. }
  1813. // not zero or denormal
  1814. else if (flt_e != 0)
  1815. {
  1816. int new_exp = flt_e - 127;
  1817. if (new_exp > 15)
  1818. e = 31;
  1819. else if (new_exp < -14)
  1820. {
  1821. if (toward_zero)
  1822. m = (int)truncf((1 << 24) * fabsf(fi.f));
  1823. else
  1824. m = lrintf((1 << 24) * fabsf(fi.f));
  1825. }
  1826. else
  1827. {
  1828. e = new_exp + 15;
  1829. if (toward_zero)
  1830. m = (int)truncf((float)flt_m * (1.0f / (float)(1 << 13)));
  1831. else
  1832. m = lrintf((float)flt_m * (1.0f / (float)(1 << 13)));
  1833. }
  1834. }
  1835. assert((0 <= m) && (m <= 1024));
  1836. if (m == 1024)
  1837. {
  1838. e++;
  1839. m = 0;
  1840. }
  1841. assert((s >= 0) && (s <= 1));
  1842. assert((e >= 0) && (e <= 31));
  1843. assert((m >= 0) && (m <= 1023));
  1844. half_float result = (half_float)((s << 15) | (e << 10) | m);
  1845. return result;
  1846. }
  1847. float half_to_float(half_float hval)
  1848. {
  1849. union { float f; uint32_t u; } x = { 0 };
  1850. uint32_t s = ((uint32_t)hval >> 15) & 1;
  1851. uint32_t e = ((uint32_t)hval >> 10) & 0x1F;
  1852. uint32_t m = (uint32_t)hval & 0x3FF;
  1853. if (!e)
  1854. {
  1855. if (!m)
  1856. {
  1857. // +- 0
  1858. x.u = s << 31;
  1859. return x.f;
  1860. }
  1861. else
  1862. {
  1863. // denormalized
  1864. while (!(m & 0x00000400))
  1865. {
  1866. m <<= 1;
  1867. --e;
  1868. }
  1869. ++e;
  1870. m &= ~0x00000400;
  1871. }
  1872. }
  1873. else if (e == 31)
  1874. {
  1875. if (m == 0)
  1876. {
  1877. // +/- INF
  1878. x.u = (s << 31) | 0x7f800000;
  1879. return x.f;
  1880. }
  1881. else
  1882. {
  1883. // +/- NaN
  1884. x.u = (s << 31) | 0x7f800000 | (m << 13);
  1885. return x.f;
  1886. }
  1887. }
  1888. e = e + (127 - 15);
  1889. m = m << 13;
  1890. assert(s <= 1);
  1891. assert(m <= 0x7FFFFF);
  1892. assert(e <= 255);
  1893. x.u = m | (e << 23) | (s << 31);
  1894. return x.f;
  1895. }
  1896. // See https://registry.khronos.org/OpenGL/extensions/EXT/EXT_texture_shared_exponent.txt
  1897. const int RGB9E5_EXPONENT_BITS = 5, RGB9E5_MANTISSA_BITS = 9, RGB9E5_EXP_BIAS = 15, RGB9E5_MAX_VALID_BIASED_EXP = 31;
  1898. const int MAX_RGB9E5_EXP = (RGB9E5_MAX_VALID_BIASED_EXP - RGB9E5_EXP_BIAS);
  1899. const int RGB9E5_MANTISSA_VALUES = (1 << RGB9E5_MANTISSA_BITS);
  1900. const int MAX_RGB9E5_MANTISSA = (RGB9E5_MANTISSA_VALUES - 1);
  1901. //const int MAX_RGB9E5 = (int)(((float)MAX_RGB9E5_MANTISSA) / RGB9E5_MANTISSA_VALUES * (1 << MAX_RGB9E5_EXP));
  1902. const int EPSILON_RGB9E5 = (int)((1.0f / (float)RGB9E5_MANTISSA_VALUES) / (float)(1 << RGB9E5_EXP_BIAS));
  1903. void unpack_rgb9e5(uint32_t packed, float& r, float& g, float& b)
  1904. {
  1905. int x = packed & 511;
  1906. int y = (packed >> 9) & 511;
  1907. int z = (packed >> 18) & 511;
  1908. int w = (packed >> 27) & 31;
  1909. const float scale = powf(2.0f, static_cast<float>(w - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS));
  1910. r = x * scale;
  1911. g = y * scale;
  1912. b = z * scale;
  1913. }
  1914. // floor_log2 is not correct for the denorm and zero values, but we are going to do a max of this value with the minimum rgb9e5 exponent that will hide these problem cases.
  1915. static inline int floor_log2(float x)
  1916. {
  1917. union float754
  1918. {
  1919. unsigned int raw;
  1920. float value;
  1921. };
  1922. float754 f;
  1923. f.value = x;
  1924. // Extract float exponent
  1925. return ((f.raw >> 23) & 0xFF) - 127;
  1926. }
  1927. static inline int maximumi(int a, int b) { return (a > b) ? a : b; }
  1928. static inline float maximumf(float a, float b) { return (a > b) ? a : b; }
  1929. uint32_t pack_rgb9e5(float r, float g, float b)
  1930. {
  1931. r = clampf(r, 0.0f, MAX_RGB9E5);
  1932. g = clampf(g, 0.0f, MAX_RGB9E5);
  1933. b = clampf(b, 0.0f, MAX_RGB9E5);
  1934. float maxrgb = maximumf(maximumf(r, g), b);
  1935. int exp_shared = maximumi(-RGB9E5_EXP_BIAS - 1, floor_log2(maxrgb)) + 1 + RGB9E5_EXP_BIAS;
  1936. assert((exp_shared >= 0) && (exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP));
  1937. float denom = powf(2.0f, (float)(exp_shared - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS));
  1938. int maxm = (int)floorf((maxrgb / denom) + 0.5f);
  1939. if (maxm == (MAX_RGB9E5_MANTISSA + 1))
  1940. {
  1941. denom *= 2;
  1942. exp_shared += 1;
  1943. assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP);
  1944. }
  1945. else
  1946. {
  1947. assert(maxm <= MAX_RGB9E5_MANTISSA);
  1948. }
  1949. int rm = (int)floorf((r / denom) + 0.5f);
  1950. int gm = (int)floorf((g / denom) + 0.5f);
  1951. int bm = (int)floorf((b / denom) + 0.5f);
  1952. assert((rm >= 0) && (rm <= MAX_RGB9E5_MANTISSA));
  1953. assert((gm >= 0) && (gm <= MAX_RGB9E5_MANTISSA));
  1954. assert((bm >= 0) && (bm <= MAX_RGB9E5_MANTISSA));
  1955. return rm | (gm << 9) | (bm << 18) | (exp_shared << 27);
  1956. }
  1957. static inline int clz17(uint32_t x)
  1958. {
  1959. assert(x <= 0x1FFFF);
  1960. x &= 0x1FFFF;
  1961. if (!x)
  1962. return 17;
  1963. uint32_t n = 0;
  1964. while ((x & 0x10000) == 0)
  1965. {
  1966. x <<= 1u;
  1967. n++;
  1968. }
  1969. return n;
  1970. }
  1971. static inline uint32_t pack_rgb9e5_ldr_astc(int Cr, int Cg, int Cb)
  1972. {
  1973. int lz = clz17(Cr | Cg | Cb | 1);
  1974. if (Cr == 65535) { Cr = 65536; lz = 0; }
  1975. if (Cg == 65535) { Cg = 65536; lz = 0; }
  1976. if (Cb == 65535) { Cb = 65536; lz = 0; }
  1977. Cr <<= lz; Cg <<= lz; Cb <<= lz;
  1978. Cr = (Cr >> 8) & 0x1FF;
  1979. Cg = (Cg >> 8) & 0x1FF;
  1980. Cb = (Cb >> 8) & 0x1FF;
  1981. uint32_t exponent = 16 - lz;
  1982. uint32_t texel = (exponent << 27) | (Cb << 18) | (Cg << 9) | Cr;
  1983. return texel;
  1984. }
  1985. static inline uint32_t pack_rgb9e5_hdr_astc(int Cr, int Cg, int Cb)
  1986. {
  1987. if (Cr > 0x7c00) Cr = 0; else if (Cr == 0x7c00) Cr = 0x7bff;
  1988. if (Cg > 0x7c00) Cg = 0; else if (Cg == 0x7c00) Cg = 0x7bff;
  1989. if (Cb > 0x7c00) Cb = 0; else if (Cb == 0x7c00) Cb = 0x7bff;
  1990. int Re = (Cr >> 10) & 0x1F;
  1991. int Ge = (Cg >> 10) & 0x1F;
  1992. int Be = (Cb >> 10) & 0x1F;
  1993. int Rex = (Re == 0) ? 1 : Re;
  1994. int Gex = (Ge == 0) ? 1 : Ge;
  1995. int Bex = (Be == 0) ? 1 : Be;
  1996. int Xm = ((Cr | Cg | Cb) & 0x200) >> 9;
  1997. int Xe = Re | Ge | Be;
  1998. uint32_t rshift, gshift, bshift, expo;
  1999. if (Xe == 0)
  2000. {
  2001. expo = rshift = gshift = bshift = Xm;
  2002. }
  2003. else if (Re >= Ge && Re >= Be)
  2004. {
  2005. expo = Rex + 1;
  2006. rshift = 2;
  2007. gshift = Rex - Gex + 2;
  2008. bshift = Rex - Bex + 2;
  2009. }
  2010. else if (Ge >= Be)
  2011. {
  2012. expo = Gex + 1;
  2013. rshift = Gex - Rex + 2;
  2014. gshift = 2;
  2015. bshift = Gex - Bex + 2;
  2016. }
  2017. else
  2018. {
  2019. expo = Bex + 1;
  2020. rshift = Bex - Rex + 2;
  2021. gshift = Bex - Gex + 2;
  2022. bshift = 2;
  2023. }
  2024. int Rm = (Cr & 0x3FF) | (Re == 0 ? 0 : 0x400);
  2025. int Gm = (Cg & 0x3FF) | (Ge == 0 ? 0 : 0x400);
  2026. int Bm = (Cb & 0x3FF) | (Be == 0 ? 0 : 0x400);
  2027. Rm = (Rm >> rshift) & 0x1FF;
  2028. Gm = (Gm >> gshift) & 0x1FF;
  2029. Bm = (Bm >> bshift) & 0x1FF;
  2030. uint32_t texel = (expo << 27) | (Bm << 18) | (Gm << 9) | (Rm << 0);
  2031. return texel;
  2032. }
  2033. // Important: pPixels is either 32-bit/texel or 64-bit/texel.
  2034. bool decode_block(const log_astc_block& log_blk, void* pPixels, uint32_t blk_width, uint32_t blk_height, decode_mode dec_mode)
  2035. {
  2036. assert(is_valid_block_size(blk_width, blk_height));
  2037. assert(g_dequant_tables.m_endpoints[0].m_ISE_to_val.size());
  2038. if (!g_dequant_tables.m_endpoints[0].m_ISE_to_val.size())
  2039. return false;
  2040. const uint32_t num_blk_pixels = blk_width * blk_height;
  2041. // Write block error color
  2042. if (dec_mode == cDecodeModeHDR16)
  2043. {
  2044. // NaN's
  2045. memset(pPixels, 0xFF, num_blk_pixels * sizeof(half_float) * 4);
  2046. }
  2047. else if (dec_mode == cDecodeModeRGB9E5)
  2048. {
  2049. const uint32_t purple_9e5 = pack_rgb9e5(1.0f, 0.0f, 1.0f);
  2050. for (uint32_t i = 0; i < num_blk_pixels; i++)
  2051. ((uint32_t*)pPixels)[i] = purple_9e5;
  2052. }
  2053. else
  2054. {
  2055. for (uint32_t i = 0; i < num_blk_pixels; i++)
  2056. ((uint32_t*)pPixels)[i] = 0xFFFF00FF;
  2057. }
  2058. if (log_blk.m_error_flag)
  2059. {
  2060. // Should this return false? It's not an invalid logical block config, though.
  2061. return false;
  2062. }
  2063. // Handle solid color blocks
  2064. if (log_blk.m_solid_color_flag_ldr)
  2065. {
  2066. // LDR solid block
  2067. if (dec_mode == cDecodeModeHDR16)
  2068. {
  2069. // Convert LDR pixels to half-float
  2070. half_float h[4];
  2071. for (uint32_t c = 0; c < 4; c++)
  2072. h[c] = (log_blk.m_solid_color[c] == 0xFFFF) ? 0x3C00 : float_to_half((float)log_blk.m_solid_color[c] * (1.0f / 65536.0f), true);
  2073. for (uint32_t i = 0; i < num_blk_pixels; i++)
  2074. memcpy((uint16_t*)pPixels + i * 4, h, sizeof(half_float) * 4);
  2075. }
  2076. else if (dec_mode == cDecodeModeRGB9E5)
  2077. {
  2078. float r = (log_blk.m_solid_color[0] == 0xFFFF) ? 1.0f : ((float)log_blk.m_solid_color[0] * (1.0f / 65536.0f));
  2079. float g = (log_blk.m_solid_color[1] == 0xFFFF) ? 1.0f : ((float)log_blk.m_solid_color[1] * (1.0f / 65536.0f));
  2080. float b = (log_blk.m_solid_color[2] == 0xFFFF) ? 1.0f : ((float)log_blk.m_solid_color[2] * (1.0f / 65536.0f));
  2081. const uint32_t packed = pack_rgb9e5(r, g, b);
  2082. for (uint32_t i = 0; i < num_blk_pixels; i++)
  2083. ((uint32_t*)pPixels)[i] = packed;
  2084. }
  2085. else
  2086. {
  2087. // Convert LDR pixels to 8-bits
  2088. for (uint32_t i = 0; i < num_blk_pixels; i++)
  2089. for (uint32_t c = 0; c < 4; c++)
  2090. ((uint8_t*)pPixels)[i * 4 + c] = (log_blk.m_solid_color[c] >> 8);
  2091. }
  2092. return true;
  2093. }
  2094. else if (log_blk.m_solid_color_flag_hdr)
  2095. {
  2096. // HDR solid block, decode mode must be half-float or RGB9E5
  2097. if (dec_mode == cDecodeModeHDR16)
  2098. {
  2099. for (uint32_t i = 0; i < num_blk_pixels; i++)
  2100. memcpy((uint16_t*)pPixels + i * 4, log_blk.m_solid_color, sizeof(half_float) * 4);
  2101. }
  2102. else if (dec_mode == cDecodeModeRGB9E5)
  2103. {
  2104. float r = half_to_float(log_blk.m_solid_color[0]);
  2105. float g = half_to_float(log_blk.m_solid_color[1]);
  2106. float b = half_to_float(log_blk.m_solid_color[2]);
  2107. const uint32_t packed = pack_rgb9e5(r, g, b);
  2108. for (uint32_t i = 0; i < num_blk_pixels; i++)
  2109. ((uint32_t*)pPixels)[i] = packed;
  2110. }
  2111. else
  2112. {
  2113. return false;
  2114. }
  2115. return true;
  2116. }
  2117. // Sanity check block's config
  2118. if ((log_blk.m_grid_width < 2) || (log_blk.m_grid_height < 2))
  2119. return false;
  2120. if ((log_blk.m_grid_width > blk_width) || (log_blk.m_grid_height > blk_height))
  2121. return false;
  2122. if ((log_blk.m_endpoint_ise_range < FIRST_VALID_ENDPOINT_ISE_RANGE) || (log_blk.m_endpoint_ise_range > LAST_VALID_ENDPOINT_ISE_RANGE))
  2123. return false;
  2124. if ((log_blk.m_weight_ise_range < FIRST_VALID_WEIGHT_ISE_RANGE) || (log_blk.m_weight_ise_range > LAST_VALID_WEIGHT_ISE_RANGE))
  2125. return false;
  2126. if ((log_blk.m_num_partitions < 1) || (log_blk.m_num_partitions > MAX_PARTITIONS))
  2127. return false;
  2128. if ((log_blk.m_dual_plane) && (log_blk.m_num_partitions > MAX_DUAL_PLANE_PARTITIONS))
  2129. return false;
  2130. if (log_blk.m_partition_id >= NUM_PARTITION_PATTERNS)
  2131. return false;
  2132. if ((log_blk.m_num_partitions == 1) && (log_blk.m_partition_id > 0))
  2133. return false;
  2134. if (log_blk.m_color_component_selector > 3)
  2135. return false;
  2136. const uint32_t total_endpoint_levels = get_ise_levels(log_blk.m_endpoint_ise_range);
  2137. const uint32_t total_weight_levels = get_ise_levels(log_blk.m_weight_ise_range);
  2138. bool is_ldr_endpoints[MAX_PARTITIONS];
  2139. // Check CEM's
  2140. uint32_t total_cem_vals = 0;
  2141. for (uint32_t i = 0; i < log_blk.m_num_partitions; i++)
  2142. {
  2143. if (log_blk.m_color_endpoint_modes[i] > 15)
  2144. return false;
  2145. total_cem_vals += get_num_cem_values(log_blk.m_color_endpoint_modes[i]);
  2146. is_ldr_endpoints[i] = is_cem_ldr(log_blk.m_color_endpoint_modes[i]);
  2147. }
  2148. if (total_cem_vals > MAX_ENDPOINTS)
  2149. return false;
  2150. const dequant_table& endpoint_dequant_tab = g_dequant_tables.get_endpoint_tab(log_blk.m_endpoint_ise_range);
  2151. const uint8_t* pEndpoint_dequant = endpoint_dequant_tab.m_ISE_to_val.data();
  2152. // Dequantized endpoints to [0,255]
  2153. uint8_t dequantized_endpoints[MAX_ENDPOINTS];
  2154. for (uint32_t i = 0; i < total_cem_vals; i++)
  2155. {
  2156. if (log_blk.m_endpoints[i] >= total_endpoint_levels)
  2157. return false;
  2158. dequantized_endpoints[i] = pEndpoint_dequant[log_blk.m_endpoints[i]];
  2159. }
  2160. // Dequantize weights to [0,64]
  2161. uint8_t dequantized_weights[2][12 * 12];
  2162. const dequant_table& weight_dequant_tab = g_dequant_tables.get_weight_tab(log_blk.m_weight_ise_range);
  2163. const uint8_t* pWeight_dequant = weight_dequant_tab.m_ISE_to_val.data();
  2164. const uint32_t total_weight_vals = (log_blk.m_dual_plane ? 2 : 1) * log_blk.m_grid_width * log_blk.m_grid_height;
  2165. for (uint32_t i = 0; i < total_weight_vals; i++)
  2166. {
  2167. if (log_blk.m_weights[i] >= total_weight_levels)
  2168. return false;
  2169. const uint32_t plane_index = log_blk.m_dual_plane ? (i & 1) : 0;
  2170. const uint32_t grid_index = log_blk.m_dual_plane ? (i >> 1) : i;
  2171. dequantized_weights[plane_index][grid_index] = pWeight_dequant[log_blk.m_weights[i]];
  2172. }
  2173. // Upsample weight grid. [0,64] weights
  2174. uint8_t upsampled_weights[2][12 * 12];
  2175. upsample_weight_grid(blk_width, blk_height, log_blk.m_grid_width, log_blk.m_grid_height, &dequantized_weights[0][0], &upsampled_weights[0][0]);
  2176. if (log_blk.m_dual_plane)
  2177. upsample_weight_grid(blk_width, blk_height, log_blk.m_grid_width, log_blk.m_grid_height, &dequantized_weights[1][0], &upsampled_weights[1][0]);
  2178. // Decode CEM's
  2179. int endpoints[4][4][2]; // [subset][comp][l/h]
  2180. uint32_t endpoint_val_index = 0;
  2181. for (uint32_t subset = 0; subset < log_blk.m_num_partitions; subset++)
  2182. {
  2183. const uint32_t cem_index = log_blk.m_color_endpoint_modes[subset];
  2184. decode_endpoint(cem_index, &endpoints[subset][0], &dequantized_endpoints[endpoint_val_index]);
  2185. endpoint_val_index += get_num_cem_values(cem_index);
  2186. }
  2187. // Decode texels
  2188. const bool small_block = num_blk_pixels < 31;
  2189. const bool use_precomputed_texel_partitions_4x4 = (blk_width == 4) && (blk_height == 4) && (log_blk.m_num_partitions >= 2) && (log_blk.m_num_partitions <= 3);
  2190. const bool use_precomputed_texel_partitions_6x6 = (blk_width == 6) && (blk_height == 6) && (log_blk.m_num_partitions >= 2) && (log_blk.m_num_partitions <= 3);
  2191. const uint32_t ccs = log_blk.m_dual_plane ? log_blk.m_color_component_selector : UINT32_MAX;
  2192. bool success = true;
  2193. if (dec_mode == cDecodeModeRGB9E5)
  2194. {
  2195. // returns uint32_t's
  2196. for (uint32_t y = 0; y < blk_height; y++)
  2197. {
  2198. for (uint32_t x = 0; x < blk_width; x++)
  2199. {
  2200. const uint32_t pixel_index = x + y * blk_width;
  2201. uint32_t subset = 0;
  2202. if (log_blk.m_num_partitions > 1)
  2203. {
  2204. if (use_precomputed_texel_partitions_4x4)
  2205. subset = get_precompute_texel_partitions_4x4(log_blk.m_partition_id, x, y, log_blk.m_num_partitions);
  2206. else if (use_precomputed_texel_partitions_6x6)
  2207. subset = get_precompute_texel_partitions_6x6(log_blk.m_partition_id, x, y, log_blk.m_num_partitions);
  2208. else
  2209. subset = compute_texel_partition(log_blk.m_partition_id, x, y, 0, log_blk.m_num_partitions, small_block);
  2210. }
  2211. int comp[3];
  2212. for (uint32_t c = 0; c < 3; c++)
  2213. {
  2214. const uint32_t w = upsampled_weights[(c == ccs) ? 1 : 0][pixel_index];
  2215. if (is_ldr_endpoints[subset])
  2216. {
  2217. assert((endpoints[subset][c][0] >= 0) && (endpoints[subset][c][0] <= 0xFF));
  2218. assert((endpoints[subset][c][1] >= 0) && (endpoints[subset][c][1] <= 0xFF));
  2219. int le = endpoints[subset][c][0];
  2220. int he = endpoints[subset][c][1];
  2221. le = (le << 8) | le;
  2222. he = (he << 8) | he;
  2223. int k = weight_interpolate(le, he, w);
  2224. assert((k >= 0) && (k <= 0xFFFF));
  2225. comp[c] = k; // 1.0
  2226. }
  2227. else
  2228. {
  2229. assert((endpoints[subset][c][0] >= 0) && (endpoints[subset][c][0] <= 0xFFF));
  2230. assert((endpoints[subset][c][1] >= 0) && (endpoints[subset][c][1] <= 0xFFF));
  2231. int le = endpoints[subset][c][0] << 4;
  2232. int he = endpoints[subset][c][1] << 4;
  2233. int qlog16 = weight_interpolate(le, he, w);
  2234. comp[c] = qlog16_to_half(qlog16);
  2235. if (is_half_inf_or_nan((half_float)comp[c]))
  2236. comp[c] = 0x7BFF;
  2237. }
  2238. } // c
  2239. uint32_t packed;
  2240. if (is_ldr_endpoints[subset])
  2241. packed = pack_rgb9e5_ldr_astc(comp[0], comp[1], comp[2]);
  2242. else
  2243. packed = pack_rgb9e5_hdr_astc(comp[0], comp[1], comp[2]);
  2244. ((uint32_t*)pPixels)[pixel_index] = packed;
  2245. } // x
  2246. } // y
  2247. }
  2248. else if (dec_mode == cDecodeModeHDR16)
  2249. {
  2250. // Note: must round towards zero when converting float to half for ASTC (18.19 Weight Application)
  2251. // returns half floats
  2252. for (uint32_t y = 0; y < blk_height; y++)
  2253. {
  2254. for (uint32_t x = 0; x < blk_width; x++)
  2255. {
  2256. const uint32_t pixel_index = x + y * blk_width;
  2257. uint32_t subset = 0;
  2258. if (log_blk.m_num_partitions > 1)
  2259. {
  2260. if (use_precomputed_texel_partitions_4x4)
  2261. subset = get_precompute_texel_partitions_4x4(log_blk.m_partition_id, x, y, log_blk.m_num_partitions);
  2262. else if (use_precomputed_texel_partitions_6x6)
  2263. subset = get_precompute_texel_partitions_6x6(log_blk.m_partition_id, x, y, log_blk.m_num_partitions);
  2264. else
  2265. subset = compute_texel_partition(log_blk.m_partition_id, x, y, 0, log_blk.m_num_partitions, small_block);
  2266. }
  2267. for (uint32_t c = 0; c < 4; c++)
  2268. {
  2269. const uint32_t w = upsampled_weights[(c == ccs) ? 1 : 0][pixel_index];
  2270. half_float o;
  2271. if ( (is_ldr_endpoints[subset]) ||
  2272. ((log_blk.m_color_endpoint_modes[subset] == CEM_HDR_RGB_LDR_ALPHA) && (c == 3)) )
  2273. {
  2274. assert((endpoints[subset][c][0] >= 0) && (endpoints[subset][c][0] <= 0xFF));
  2275. assert((endpoints[subset][c][1] >= 0) && (endpoints[subset][c][1] <= 0xFF));
  2276. int le = endpoints[subset][c][0];
  2277. int he = endpoints[subset][c][1];
  2278. le = (le << 8) | le;
  2279. he = (he << 8) | he;
  2280. int k = weight_interpolate(le, he, w);
  2281. assert((k >= 0) && (k <= 0xFFFF));
  2282. if (k == 0xFFFF)
  2283. o = 0x3C00; // 1.0
  2284. else
  2285. o = float_to_half((float)k * (1.0f / 65536.0f), true);
  2286. }
  2287. else
  2288. {
  2289. assert((endpoints[subset][c][0] >= 0) && (endpoints[subset][c][0] <= 0xFFF));
  2290. assert((endpoints[subset][c][1] >= 0) && (endpoints[subset][c][1] <= 0xFFF));
  2291. int le = endpoints[subset][c][0] << 4;
  2292. int he = endpoints[subset][c][1] << 4;
  2293. int qlog16 = weight_interpolate(le, he, w);
  2294. o = qlog16_to_half(qlog16);
  2295. if (is_half_inf_or_nan(o))
  2296. o = 0x7BFF;
  2297. }
  2298. ((half_float*)pPixels)[pixel_index * 4 + c] = o;
  2299. }
  2300. } // x
  2301. } // y
  2302. }
  2303. else
  2304. {
  2305. // returns uint8_t's
  2306. for (uint32_t y = 0; y < blk_height; y++)
  2307. {
  2308. for (uint32_t x = 0; x < blk_width; x++)
  2309. {
  2310. const uint32_t pixel_index = x + y * blk_width;
  2311. uint32_t subset = 0;
  2312. if (log_blk.m_num_partitions > 1)
  2313. {
  2314. if (use_precomputed_texel_partitions_4x4)
  2315. subset = get_precompute_texel_partitions_4x4(log_blk.m_partition_id, x, y, log_blk.m_num_partitions);
  2316. else if (use_precomputed_texel_partitions_6x6)
  2317. subset = get_precompute_texel_partitions_6x6(log_blk.m_partition_id, x, y, log_blk.m_num_partitions);
  2318. else
  2319. subset = compute_texel_partition(log_blk.m_partition_id, x, y, 0, log_blk.m_num_partitions, small_block);
  2320. }
  2321. if (!is_ldr_endpoints[subset])
  2322. {
  2323. ((uint32_t*)pPixels)[pixel_index * 4] = 0xFFFF00FF;
  2324. success = false;
  2325. }
  2326. else
  2327. {
  2328. for (uint32_t c = 0; c < 4; c++)
  2329. {
  2330. const uint32_t w = upsampled_weights[(c == ccs) ? 1 : 0][pixel_index];
  2331. int le = endpoints[subset][c][0];
  2332. int he = endpoints[subset][c][1];
  2333. // FIXME: the spec is apparently wrong? this matches ARM's and Google's decoder
  2334. //if ((dec_mode == cDecodeModeSRGB8) && (c <= 2))
  2335. // See https://github.com/ARM-software/astc-encoder/issues/447
  2336. if (dec_mode == cDecodeModeSRGB8)
  2337. {
  2338. le = (le << 8) | 0x80;
  2339. he = (he << 8) | 0x80;
  2340. }
  2341. else
  2342. {
  2343. le = (le << 8) | le;
  2344. he = (he << 8) | he;
  2345. }
  2346. uint32_t k = weight_interpolate(le, he, w);
  2347. // FIXME: This is what the spec says to do in LDR mode, but this is not what ARM's decoder does
  2348. // See decompress_symbolic_block(), decode_texel() and unorm16_to_sf16.
  2349. // It seems to effectively divide by 65535.0 and convert to FP16, then back to float, mul by 255.0, add .5 and then convert to 8-bit.
  2350. ((uint8_t*)pPixels)[pixel_index * 4 + c] = (uint8_t)(k >> 8);
  2351. }
  2352. }
  2353. } // x
  2354. } // y
  2355. }
  2356. return success;
  2357. }
  2358. //------------------------------------------------
  2359. // Physical to logical block decoding
  2360. // unsigned 128-bit int, with some signed helpers
  2361. class uint128
  2362. {
  2363. uint64_t m_lo, m_hi;
  2364. public:
  2365. uint128() = default;
  2366. inline uint128(uint64_t lo) : m_lo(lo), m_hi(0) { }
  2367. inline uint128(uint64_t lo, uint64_t hi) : m_lo(lo), m_hi(hi) { }
  2368. inline uint128(const uint128& other) : m_lo(other.m_lo), m_hi(other.m_hi) { }
  2369. inline uint128& set_signed(int64_t lo) { m_lo = lo; m_hi = (lo < 0) ? UINT64_MAX : 0; return *this; }
  2370. inline uint128& set(uint64_t lo) { m_lo = lo; m_hi = 0; return *this; }
  2371. inline explicit operator uint8_t () const { return (uint8_t)m_lo; }
  2372. inline explicit operator uint16_t () const { return (uint16_t)m_lo; }
  2373. inline explicit operator uint32_t () const { return (uint32_t)m_lo; }
  2374. inline explicit operator uint64_t () const { return m_lo; }
  2375. inline uint128& operator= (const uint128& rhs) { m_lo = rhs.m_lo; m_hi = rhs.m_hi; return *this; }
  2376. inline uint128& operator= (const uint64_t val) { m_lo = val; m_hi = 0; return *this; }
  2377. inline uint64_t get_low() const { return m_lo; }
  2378. inline uint64_t& get_low() { return m_lo; }
  2379. inline uint64_t get_high() const { return m_hi; }
  2380. inline uint64_t& get_high() { return m_hi; }
  2381. inline bool operator== (const uint128& rhs) const { return (m_lo == rhs.m_lo) && (m_hi == rhs.m_hi); }
  2382. inline bool operator!= (const uint128& rhs) const { return (m_lo != rhs.m_lo) || (m_hi != rhs.m_hi); }
  2383. inline bool operator< (const uint128& rhs) const
  2384. {
  2385. if (m_hi < rhs.m_hi)
  2386. return true;
  2387. if (m_hi == rhs.m_hi)
  2388. {
  2389. if (m_lo < rhs.m_lo)
  2390. return true;
  2391. }
  2392. return false;
  2393. }
  2394. inline bool operator> (const uint128& rhs) const { return (rhs < *this); }
  2395. inline bool operator<= (const uint128& rhs) const { return (*this == rhs) || (*this < rhs); }
  2396. inline bool operator>= (const uint128& rhs) const { return (*this == rhs) || (*this > rhs); }
  2397. inline bool is_zero() const { return (m_lo == 0) && (m_hi == 0); }
  2398. inline bool is_all_ones() const { return (m_lo == UINT64_MAX) && (m_hi == UINT64_MAX); }
  2399. inline bool is_non_zero() const { return (m_lo != 0) || (m_hi != 0); }
  2400. inline explicit operator bool() const { return is_non_zero(); }
  2401. inline bool is_signed() const { return ((int64_t)m_hi) < 0; }
  2402. inline bool signed_less(const uint128& rhs) const
  2403. {
  2404. const bool l_signed = is_signed(), r_signed = rhs.is_signed();
  2405. if (l_signed == r_signed)
  2406. return *this < rhs;
  2407. if (l_signed && !r_signed)
  2408. return true;
  2409. assert(!l_signed && r_signed);
  2410. return false;
  2411. }
  2412. inline bool signed_greater(const uint128& rhs) const { return rhs.signed_less(*this); }
  2413. inline bool signed_less_equal(const uint128& rhs) const { return !rhs.signed_less(*this); }
  2414. inline bool signed_greater_equal(const uint128& rhs) const { return !signed_less(rhs); }
  2415. double get_double() const
  2416. {
  2417. double res = 0;
  2418. if (m_hi)
  2419. res = (double)m_hi * pow(2.0f, 64.0f);
  2420. res += (double)m_lo;
  2421. return res;
  2422. }
  2423. double get_signed_double() const
  2424. {
  2425. if (is_signed())
  2426. return -(uint128(*this).abs().get_double());
  2427. else
  2428. return get_double();
  2429. }
  2430. inline uint128 abs() const
  2431. {
  2432. uint128 res(*this);
  2433. if (res.is_signed())
  2434. res = -res;
  2435. return res;
  2436. }
  2437. inline uint128& operator<<= (int shift)
  2438. {
  2439. assert(shift >= 0);
  2440. if (shift < 0)
  2441. return *this;
  2442. m_hi = (shift >= 64) ? ((shift >= 128) ? 0 : (m_lo << (shift - 64))) : (m_hi << shift);
  2443. if ((shift) && (shift < 64))
  2444. m_hi |= (m_lo >> (64 - shift));
  2445. m_lo = (shift >= 64) ? 0 : (m_lo << shift);
  2446. return *this;
  2447. }
  2448. inline uint128 operator<< (int shift) const { uint128 res(*this); res <<= shift; return res; }
  2449. inline uint128& operator>>= (int shift)
  2450. {
  2451. assert(shift >= 0);
  2452. if (shift < 0)
  2453. return *this;
  2454. m_lo = (shift >= 64) ? ((shift >= 128) ? 0 : (m_hi >> (shift - 64))) : (m_lo >> shift);
  2455. if ((shift) && (shift < 64))
  2456. m_lo |= (m_hi << (64 - shift));
  2457. m_hi = (shift >= 64) ? 0 : (m_hi >> shift);
  2458. return *this;
  2459. }
  2460. inline uint128 operator>> (int shift) const { uint128 res(*this); res >>= shift; return res; }
  2461. inline uint128 signed_shift_right(int shift) const
  2462. {
  2463. uint128 res(*this);
  2464. res >>= shift;
  2465. if (is_signed())
  2466. {
  2467. uint128 x(0U);
  2468. x = ~x;
  2469. x >>= shift;
  2470. res |= (~x);
  2471. }
  2472. return res;
  2473. }
  2474. inline uint128& operator |= (const uint128& rhs) { m_lo |= rhs.m_lo; m_hi |= rhs.m_hi; return *this; }
  2475. inline uint128 operator | (const uint128& rhs) const { uint128 res(*this); res |= rhs; return res; }
  2476. inline uint128& operator &= (const uint128& rhs) { m_lo &= rhs.m_lo; m_hi &= rhs.m_hi; return *this; }
  2477. inline uint128 operator & (const uint128& rhs) const { uint128 res(*this); res &= rhs; return res; }
  2478. inline uint128& operator ^= (const uint128& rhs) { m_lo ^= rhs.m_lo; m_hi ^= rhs.m_hi; return *this; }
  2479. inline uint128 operator ^ (const uint128& rhs) const { uint128 res(*this); res ^= rhs; return res; }
  2480. inline uint128 operator ~() const { return uint128(~m_lo, ~m_hi); }
  2481. inline uint128 operator -() const { uint128 res(~*this); if (++res.m_lo == 0) ++res.m_hi; return res; }
  2482. // prefix
  2483. inline uint128 operator ++()
  2484. {
  2485. if (++m_lo == 0)
  2486. ++m_hi;
  2487. return *this;
  2488. }
  2489. // postfix
  2490. inline uint128 operator ++(int)
  2491. {
  2492. uint128 res(*this);
  2493. if (++m_lo == 0)
  2494. ++m_hi;
  2495. return res;
  2496. }
  2497. // prefix
  2498. inline uint128 operator --()
  2499. {
  2500. const uint64_t t = m_lo;
  2501. if (--m_lo > t)
  2502. --m_hi;
  2503. return *this;
  2504. }
  2505. // postfix
  2506. inline uint128 operator --(int)
  2507. {
  2508. const uint64_t t = m_lo;
  2509. uint128 res(*this);
  2510. if (--m_lo > t)
  2511. --m_hi;
  2512. return res;
  2513. }
  2514. inline uint128& operator+= (const uint128& rhs)
  2515. {
  2516. const uint64_t t = m_lo + rhs.m_lo;
  2517. m_hi = m_hi + rhs.m_hi + (t < m_lo);
  2518. m_lo = t;
  2519. return *this;
  2520. }
  2521. inline uint128 operator+ (const uint128& rhs) const { uint128 res(*this); res += rhs; return res; }
  2522. inline uint128& operator-= (const uint128& rhs)
  2523. {
  2524. const uint64_t t = m_lo - rhs.m_lo;
  2525. m_hi = m_hi - rhs.m_hi - (t > m_lo);
  2526. m_lo = t;
  2527. return *this;
  2528. }
  2529. inline uint128 operator- (const uint128& rhs) const { uint128 res(*this); res -= rhs; return res; }
  2530. // computes bit by bit, very slow
  2531. uint128& operator*=(const uint128& rhs)
  2532. {
  2533. uint128 temp(*this), result(0U);
  2534. for (uint128 bitmask(rhs); bitmask; bitmask >>= 1, temp <<= 1)
  2535. if (bitmask.get_low() & 1)
  2536. result += temp;
  2537. *this = result;
  2538. return *this;
  2539. }
  2540. uint128 operator*(const uint128& rhs) const { uint128 res(*this); res *= rhs; return res; }
  2541. // computes bit by bit, very slow
  2542. friend uint128 divide(const uint128& dividend, const uint128& divisor, uint128& remainder)
  2543. {
  2544. remainder = 0;
  2545. if (!divisor)
  2546. {
  2547. assert(0);
  2548. return ~uint128(0U);
  2549. }
  2550. uint128 quotient(0), one(1);
  2551. for (int i = 127; i >= 0; i--)
  2552. {
  2553. remainder = (remainder << 1) | ((dividend >> i) & one);
  2554. if (remainder >= divisor)
  2555. {
  2556. remainder -= divisor;
  2557. quotient |= (one << i);
  2558. }
  2559. }
  2560. return quotient;
  2561. }
  2562. uint128 operator/(const uint128& rhs) const { uint128 remainder, res; res = divide(*this, rhs, remainder); return res; }
  2563. uint128 operator/=(const uint128& rhs) { uint128 remainder; *this = divide(*this, rhs, remainder); return *this; }
  2564. uint128 operator%(const uint128& rhs) const { uint128 remainder; divide(*this, rhs, remainder); return remainder; }
  2565. uint128 operator%=(const uint128& rhs) { uint128 remainder; divide(*this, rhs, remainder); *this = remainder; return *this; }
  2566. void print_hex(FILE* pFile) const
  2567. {
  2568. fprintf(pFile, "0x%016llx%016llx", (unsigned long long int)m_hi, (unsigned long long int)m_lo);
  2569. }
  2570. void format_unsigned(std::string& res) const
  2571. {
  2572. basisu::vector<uint8_t> digits;
  2573. digits.reserve(39 + 1);
  2574. uint128 k(*this), ten(10);
  2575. do
  2576. {
  2577. uint128 r;
  2578. k = divide(k, ten, r);
  2579. digits.push_back((uint8_t)r);
  2580. } while (k);
  2581. for (int i = (int)digits.size() - 1; i >= 0; i--)
  2582. res += ('0' + digits[i]);
  2583. }
  2584. void format_signed(std::string& res) const
  2585. {
  2586. uint128 val(*this);
  2587. if (val.is_signed())
  2588. {
  2589. res.push_back('-');
  2590. val = -val;
  2591. }
  2592. val.format_unsigned(res);
  2593. }
  2594. void print_unsigned(FILE* pFile)
  2595. {
  2596. std::string str;
  2597. format_unsigned(str);
  2598. fprintf(pFile, "%s", str.c_str());
  2599. }
  2600. void print_signed(FILE* pFile)
  2601. {
  2602. std::string str;
  2603. format_signed(str);
  2604. fprintf(pFile, "%s", str.c_str());
  2605. }
  2606. uint128 get_reversed_bits() const
  2607. {
  2608. uint128 res;
  2609. const uint32_t* pSrc = (const uint32_t*)this;
  2610. uint32_t* pDst = (uint32_t*)&res;
  2611. pDst[0] = rev_dword(pSrc[3]);
  2612. pDst[1] = rev_dword(pSrc[2]);
  2613. pDst[2] = rev_dword(pSrc[1]);
  2614. pDst[3] = rev_dword(pSrc[0]);
  2615. return res;
  2616. }
  2617. uint128 get_byteswapped() const
  2618. {
  2619. uint128 res;
  2620. const uint8_t* pSrc = (const uint8_t*)this;
  2621. uint8_t* pDst = (uint8_t*)&res;
  2622. for (uint32_t i = 0; i < 16; i++)
  2623. pDst[i] = pSrc[15 - i];
  2624. return res;
  2625. }
  2626. inline uint64_t get_bits64(uint32_t bit_ofs, uint32_t bit_len) const
  2627. {
  2628. assert(bit_ofs < 128);
  2629. assert(bit_len && (bit_len <= 64) && ((bit_ofs + bit_len) <= 128));
  2630. uint128 res(*this);
  2631. res >>= bit_ofs;
  2632. const uint64_t bitmask = (bit_len == 64) ? UINT64_MAX : ((1ull << bit_len) - 1);
  2633. return res.get_low() & bitmask;
  2634. }
  2635. inline uint32_t get_bits(uint32_t bit_ofs, uint32_t bit_len) const
  2636. {
  2637. assert(bit_len <= 32);
  2638. return (uint32_t)get_bits64(bit_ofs, bit_len);
  2639. }
  2640. inline uint32_t next_bits(uint32_t& bit_ofs, uint32_t len) const
  2641. {
  2642. assert(len && (len <= 32));
  2643. uint32_t x = get_bits(bit_ofs, len);
  2644. bit_ofs += len;
  2645. return x;
  2646. }
  2647. inline uint128& set_bits(uint64_t val, uint32_t bit_ofs, uint32_t num_bits)
  2648. {
  2649. assert(bit_ofs < 128);
  2650. assert(num_bits && (num_bits <= 64) && ((bit_ofs + num_bits) <= 128));
  2651. uint128 bitmask(1);
  2652. bitmask = (bitmask << num_bits) - 1;
  2653. assert(uint128(val) <= bitmask);
  2654. bitmask <<= bit_ofs;
  2655. *this &= ~bitmask;
  2656. *this = *this | (uint128(val) << bit_ofs);
  2657. return *this;
  2658. }
  2659. };
  2660. static bool decode_void_extent(const uint128& bits, log_astc_block& log_blk)
  2661. {
  2662. if (bits.get_bits(10, 2) != 0b11)
  2663. return false;
  2664. uint32_t bit_ofs = 12;
  2665. const uint32_t min_s = bits.next_bits(bit_ofs, 13);
  2666. const uint32_t max_s = bits.next_bits(bit_ofs, 13);
  2667. const uint32_t min_t = bits.next_bits(bit_ofs, 13);
  2668. const uint32_t max_t = bits.next_bits(bit_ofs, 13);
  2669. assert(bit_ofs == 64);
  2670. const bool all_extents_all_ones = (min_s == 0x1FFF) && (max_s == 0x1FFF) && (min_t == 0x1FFF) && (max_t == 0x1FFF);
  2671. if (!all_extents_all_ones && ((min_s >= max_s) || (min_t >= max_t)))
  2672. return false;
  2673. const bool hdr_flag = bits.get_bits(9, 1) != 0;
  2674. if (hdr_flag)
  2675. log_blk.m_solid_color_flag_hdr = true;
  2676. else
  2677. log_blk.m_solid_color_flag_ldr = true;
  2678. log_blk.m_solid_color[0] = (uint16_t)bits.get_bits(64, 16);
  2679. log_blk.m_solid_color[1] = (uint16_t)bits.get_bits(80, 16);
  2680. log_blk.m_solid_color[2] = (uint16_t)bits.get_bits(96, 16);
  2681. log_blk.m_solid_color[3] = (uint16_t)bits.get_bits(112, 16);
  2682. if (log_blk.m_solid_color_flag_hdr)
  2683. {
  2684. for (uint32_t c = 0; c < 4; c++)
  2685. if (is_half_inf_or_nan(log_blk.m_solid_color[c]))
  2686. return false;
  2687. }
  2688. return true;
  2689. }
  2690. struct astc_dec_row
  2691. {
  2692. int8_t Dp_ofs, P_ofs, W_ofs, W_size, H_ofs, H_size, W_bias, H_bias, p0_ofs, p1_ofs, p2_ofs;
  2693. };
  2694. static const astc_dec_row s_dec_rows[10] =
  2695. {
  2696. // Dp_ofs, P_ofs, W_ofs, W_size, H_ofs, H_size, W_bias, H_bias, p0_ofs, p1_ofs, p2_ofs;
  2697. { 10, 9, 7, 2, 5, 2, 4, 2, 4, 0, 1 }, // 4 2
  2698. { 10, 9, 7, 2, 5, 2, 8, 2, 4, 0, 1 }, // 8 2
  2699. { 10, 9, 5, 2, 7, 2, 2, 8, 4, 0, 1 }, // 2 8
  2700. { 10, 9, 5, 2, 7, 1, 2, 6, 4, 0, 1 }, // 2 6
  2701. { 10, 9, 7, 1, 5, 2, 2, 2, 4, 0, 1 }, // 2 2
  2702. { 10, 9, 0, 0, 5, 2, 12, 2, 4, 2, 3 }, // 12 2
  2703. { 10, 9, 5, 2, 0, 0, 2, 12, 4, 2, 3 }, // 2 12
  2704. { 10, 9, 0, 0, 0, 0, 6, 10, 4, 2, 3 }, // 6 10
  2705. { 10, 9, 0, 0, 0, 0, 10, 6, 4, 2, 3 }, // 10 6
  2706. { -1, -1, 5, 2, 9, 2, 6, 6, 4, 2, 3 }, // 6 6
  2707. };
  2708. static bool decode_config(const uint128& bits, log_astc_block& log_blk)
  2709. {
  2710. // Reserved
  2711. if (bits.get_bits(0, 4) == 0)
  2712. return false;
  2713. // Reserved
  2714. if ((bits.get_bits(0, 2) == 0) && (bits.get_bits(6, 3) == 0b111))
  2715. {
  2716. if (bits.get_bits(2, 4) != 0b1111)
  2717. return false;
  2718. }
  2719. // Void extent
  2720. if (bits.get_bits(0, 9) == 0b111111100)
  2721. return decode_void_extent(bits, log_blk);
  2722. // Check rows
  2723. const uint32_t x0_2 = bits.get_bits(0, 2), x2_2 = bits.get_bits(2, 2);
  2724. const uint32_t x5_4 = bits.get_bits(5, 4), x8_1 = bits.get_bits(8, 1);
  2725. const uint32_t x7_2 = bits.get_bits(7, 2);
  2726. int row_index = -1;
  2727. if (x0_2 == 0)
  2728. {
  2729. if (x7_2 == 0b00)
  2730. row_index = 5;
  2731. else if (x7_2 == 0b01)
  2732. row_index = 6;
  2733. else if (x5_4 == 0b1100)
  2734. row_index = 7;
  2735. else if (x5_4 == 0b1101)
  2736. row_index = 8;
  2737. else if (x7_2 == 0b10)
  2738. row_index = 9;
  2739. }
  2740. else
  2741. {
  2742. if (x2_2 == 0b00)
  2743. row_index = 0;
  2744. else if (x2_2 == 0b01)
  2745. row_index = 1;
  2746. else if (x2_2 == 0b10)
  2747. row_index = 2;
  2748. else if ((x2_2 == 0b11) && (x8_1 == 0))
  2749. row_index = 3;
  2750. else if ((x2_2 == 0b11) && (x8_1 == 1))
  2751. row_index = 4;
  2752. }
  2753. if (row_index < 0)
  2754. return false;
  2755. const astc_dec_row& r = s_dec_rows[row_index];
  2756. bool P = false, Dp = false;
  2757. uint32_t W = r.W_bias, H = r.H_bias;
  2758. if (r.P_ofs >= 0)
  2759. P = bits.get_bits(r.P_ofs, 1) != 0;
  2760. if (r.Dp_ofs >= 0)
  2761. Dp = bits.get_bits(r.Dp_ofs, 1) != 0;
  2762. if (r.W_size)
  2763. W += bits.get_bits(r.W_ofs, r.W_size);
  2764. if (r.H_size)
  2765. H += bits.get_bits(r.H_ofs, r.H_size);
  2766. assert((W >= MIN_GRID_DIM) && (W <= MAX_BLOCK_DIM));
  2767. assert((H >= MIN_GRID_DIM) && (H <= MAX_BLOCK_DIM));
  2768. int p0 = bits.get_bits(r.p0_ofs, 1);
  2769. int p1 = bits.get_bits(r.p1_ofs, 1);
  2770. int p2 = bits.get_bits(r.p2_ofs, 1);
  2771. uint32_t p = p0 | (p1 << 1) | (p2 << 2);
  2772. if (p < 2)
  2773. return false;
  2774. log_blk.m_grid_width = (uint8_t)W;
  2775. log_blk.m_grid_height = (uint8_t)H;
  2776. log_blk.m_weight_ise_range = (uint8_t)((p - 2) + (P * BISE_10_LEVELS));
  2777. assert(log_blk.m_weight_ise_range <= LAST_VALID_WEIGHT_ISE_RANGE);
  2778. log_blk.m_dual_plane = Dp;
  2779. return true;
  2780. }
  2781. static inline uint32_t read_le_dword(const uint8_t* pBytes)
  2782. {
  2783. return (pBytes[0]) | (pBytes[1] << 8U) | (pBytes[2] << 16U) | (pBytes[3] << 24U);
  2784. }
  2785. // See 18.12.Integer Sequence Encoding - tables computed by executing the decoder functions with all possible 8/7-bit inputs.
  2786. static const uint8_t s_trit_decode[256][5] =
  2787. {
  2788. {0,0,0,0,0},{1,0,0,0,0},{2,0,0,0,0},{0,0,2,0,0},{0,1,0,0,0},{1,1,0,0,0},{2,1,0,0,0},{1,0,2,0,0},
  2789. {0,2,0,0,0},{1,2,0,0,0},{2,2,0,0,0},{2,0,2,0,0},{0,2,2,0,0},{1,2,2,0,0},{2,2,2,0,0},{2,0,2,0,0},
  2790. {0,0,1,0,0},{1,0,1,0,0},{2,0,1,0,0},{0,1,2,0,0},{0,1,1,0,0},{1,1,1,0,0},{2,1,1,0,0},{1,1,2,0,0},
  2791. {0,2,1,0,0},{1,2,1,0,0},{2,2,1,0,0},{2,1,2,0,0},{0,0,0,2,2},{1,0,0,2,2},{2,0,0,2,2},{0,0,2,2,2},
  2792. {0,0,0,1,0},{1,0,0,1,0},{2,0,0,1,0},{0,0,2,1,0},{0,1,0,1,0},{1,1,0,1,0},{2,1,0,1,0},{1,0,2,1,0},
  2793. {0,2,0,1,0},{1,2,0,1,0},{2,2,0,1,0},{2,0,2,1,0},{0,2,2,1,0},{1,2,2,1,0},{2,2,2,1,0},{2,0,2,1,0},
  2794. {0,0,1,1,0},{1,0,1,1,0},{2,0,1,1,0},{0,1,2,1,0},{0,1,1,1,0},{1,1,1,1,0},{2,1,1,1,0},{1,1,2,1,0},
  2795. {0,2,1,1,0},{1,2,1,1,0},{2,2,1,1,0},{2,1,2,1,0},{0,1,0,2,2},{1,1,0,2,2},{2,1,0,2,2},{1,0,2,2,2},
  2796. {0,0,0,2,0},{1,0,0,2,0},{2,0,0,2,0},{0,0,2,2,0},{0,1,0,2,0},{1,1,0,2,0},{2,1,0,2,0},{1,0,2,2,0},
  2797. {0,2,0,2,0},{1,2,0,2,0},{2,2,0,2,0},{2,0,2,2,0},{0,2,2,2,0},{1,2,2,2,0},{2,2,2,2,0},{2,0,2,2,0},
  2798. {0,0,1,2,0},{1,0,1,2,0},{2,0,1,2,0},{0,1,2,2,0},{0,1,1,2,0},{1,1,1,2,0},{2,1,1,2,0},{1,1,2,2,0},
  2799. {0,2,1,2,0},{1,2,1,2,0},{2,2,1,2,0},{2,1,2,2,0},{0,2,0,2,2},{1,2,0,2,2},{2,2,0,2,2},{2,0,2,2,2},
  2800. {0,0,0,0,2},{1,0,0,0,2},{2,0,0,0,2},{0,0,2,0,2},{0,1,0,0,2},{1,1,0,0,2},{2,1,0,0,2},{1,0,2,0,2},
  2801. {0,2,0,0,2},{1,2,0,0,2},{2,2,0,0,2},{2,0,2,0,2},{0,2,2,0,2},{1,2,2,0,2},{2,2,2,0,2},{2,0,2,0,2},
  2802. {0,0,1,0,2},{1,0,1,0,2},{2,0,1,0,2},{0,1,2,0,2},{0,1,1,0,2},{1,1,1,0,2},{2,1,1,0,2},{1,1,2,0,2},
  2803. {0,2,1,0,2},{1,2,1,0,2},{2,2,1,0,2},{2,1,2,0,2},{0,2,2,2,2},{1,2,2,2,2},{2,2,2,2,2},{2,0,2,2,2},
  2804. {0,0,0,0,1},{1,0,0,0,1},{2,0,0,0,1},{0,0,2,0,1},{0,1,0,0,1},{1,1,0,0,1},{2,1,0,0,1},{1,0,2,0,1},
  2805. {0,2,0,0,1},{1,2,0,0,1},{2,2,0,0,1},{2,0,2,0,1},{0,2,2,0,1},{1,2,2,0,1},{2,2,2,0,1},{2,0,2,0,1},
  2806. {0,0,1,0,1},{1,0,1,0,1},{2,0,1,0,1},{0,1,2,0,1},{0,1,1,0,1},{1,1,1,0,1},{2,1,1,0,1},{1,1,2,0,1},
  2807. {0,2,1,0,1},{1,2,1,0,1},{2,2,1,0,1},{2,1,2,0,1},{0,0,1,2,2},{1,0,1,2,2},{2,0,1,2,2},{0,1,2,2,2},
  2808. {0,0,0,1,1},{1,0,0,1,1},{2,0,0,1,1},{0,0,2,1,1},{0,1,0,1,1},{1,1,0,1,1},{2,1,0,1,1},{1,0,2,1,1},
  2809. {0,2,0,1,1},{1,2,0,1,1},{2,2,0,1,1},{2,0,2,1,1},{0,2,2,1,1},{1,2,2,1,1},{2,2,2,1,1},{2,0,2,1,1},
  2810. {0,0,1,1,1},{1,0,1,1,1},{2,0,1,1,1},{0,1,2,1,1},{0,1,1,1,1},{1,1,1,1,1},{2,1,1,1,1},{1,1,2,1,1},
  2811. {0,2,1,1,1},{1,2,1,1,1},{2,2,1,1,1},{2,1,2,1,1},{0,1,1,2,2},{1,1,1,2,2},{2,1,1,2,2},{1,1,2,2,2},
  2812. {0,0,0,2,1},{1,0,0,2,1},{2,0,0,2,1},{0,0,2,2,1},{0,1,0,2,1},{1,1,0,2,1},{2,1,0,2,1},{1,0,2,2,1},
  2813. {0,2,0,2,1},{1,2,0,2,1},{2,2,0,2,1},{2,0,2,2,1},{0,2,2,2,1},{1,2,2,2,1},{2,2,2,2,1},{2,0,2,2,1},
  2814. {0,0,1,2,1},{1,0,1,2,1},{2,0,1,2,1},{0,1,2,2,1},{0,1,1,2,1},{1,1,1,2,1},{2,1,1,2,1},{1,1,2,2,1},
  2815. {0,2,1,2,1},{1,2,1,2,1},{2,2,1,2,1},{2,1,2,2,1},{0,2,1,2,2},{1,2,1,2,2},{2,2,1,2,2},{2,1,2,2,2},
  2816. {0,0,0,1,2},{1,0,0,1,2},{2,0,0,1,2},{0,0,2,1,2},{0,1,0,1,2},{1,1,0,1,2},{2,1,0,1,2},{1,0,2,1,2},
  2817. {0,2,0,1,2},{1,2,0,1,2},{2,2,0,1,2},{2,0,2,1,2},{0,2,2,1,2},{1,2,2,1,2},{2,2,2,1,2},{2,0,2,1,2},
  2818. {0,0,1,1,2},{1,0,1,1,2},{2,0,1,1,2},{0,1,2,1,2},{0,1,1,1,2},{1,1,1,1,2},{2,1,1,1,2},{1,1,2,1,2},
  2819. {0,2,1,1,2},{1,2,1,1,2},{2,2,1,1,2},{2,1,2,1,2},{0,2,2,2,2},{1,2,2,2,2},{2,2,2,2,2},{2,1,2,2,2}
  2820. };
  2821. static const uint8_t s_quint_decode[128][3] =
  2822. {
  2823. {0,0,0},{1,0,0},{2,0,0},{3,0,0},{4,0,0},{0,4,0},{4,4,0},{4,4,4},
  2824. {0,1,0},{1,1,0},{2,1,0},{3,1,0},{4,1,0},{1,4,0},{4,4,1},{4,4,4},
  2825. {0,2,0},{1,2,0},{2,2,0},{3,2,0},{4,2,0},{2,4,0},{4,4,2},{4,4,4},
  2826. {0,3,0},{1,3,0},{2,3,0},{3,3,0},{4,3,0},{3,4,0},{4,4,3},{4,4,4},
  2827. {0,0,1},{1,0,1},{2,0,1},{3,0,1},{4,0,1},{0,4,1},{4,0,4},{0,4,4},
  2828. {0,1,1},{1,1,1},{2,1,1},{3,1,1},{4,1,1},{1,4,1},{4,1,4},{1,4,4},
  2829. {0,2,1},{1,2,1},{2,2,1},{3,2,1},{4,2,1},{2,4,1},{4,2,4},{2,4,4},
  2830. {0,3,1},{1,3,1},{2,3,1},{3,3,1},{4,3,1},{3,4,1},{4,3,4},{3,4,4},
  2831. {0,0,2},{1,0,2},{2,0,2},{3,0,2},{4,0,2},{0,4,2},{2,0,4},{3,0,4},
  2832. {0,1,2},{1,1,2},{2,1,2},{3,1,2},{4,1,2},{1,4,2},{2,1,4},{3,1,4},
  2833. {0,2,2},{1,2,2},{2,2,2},{3,2,2},{4,2,2},{2,4,2},{2,2,4},{3,2,4},
  2834. {0,3,2},{1,3,2},{2,3,2},{3,3,2},{4,3,2},{3,4,2},{2,3,4},{3,3,4},
  2835. {0,0,3},{1,0,3},{2,0,3},{3,0,3},{4,0,3},{0,4,3},{0,0,4},{1,0,4},
  2836. {0,1,3},{1,1,3},{2,1,3},{3,1,3},{4,1,3},{1,4,3},{0,1,4},{1,1,4},
  2837. {0,2,3},{1,2,3},{2,2,3},{3,2,3},{4,2,3},{2,4,3},{0,2,4},{1,2,4},
  2838. {0,3,3},{1,3,3},{2,3,3},{3,3,3},{4,3,3},{3,4,3},{0,3,4},{1,3,4}
  2839. };
  2840. static void decode_trit_block(uint8_t* pVals, uint32_t num_vals, const uint128& bits, uint32_t& bit_ofs, uint32_t bits_per_val)
  2841. {
  2842. assert((num_vals >= 1) && (num_vals <= 5));
  2843. uint32_t m[5] = { 0 }, T = 0;
  2844. static const uint8_t s_t_bits[5] = { 2, 2, 1, 2, 1 };
  2845. for (uint32_t T_ofs = 0, c = 0; c < num_vals; c++)
  2846. {
  2847. if (bits_per_val)
  2848. m[c] = bits.next_bits(bit_ofs, bits_per_val);
  2849. T |= (bits.next_bits(bit_ofs, s_t_bits[c]) << T_ofs);
  2850. T_ofs += s_t_bits[c];
  2851. }
  2852. const uint8_t (&p_trits)[5] = s_trit_decode[T];
  2853. for (uint32_t i = 0; i < num_vals; i++)
  2854. pVals[i] = (uint8_t)((p_trits[i] << bits_per_val) | m[i]);
  2855. }
  2856. static void decode_quint_block(uint8_t* pVals, uint32_t num_vals, const uint128& bits, uint32_t& bit_ofs, uint32_t bits_per_val)
  2857. {
  2858. assert((num_vals >= 1) && (num_vals <= 3));
  2859. uint32_t m[3] = { 0 }, T = 0;
  2860. static const uint8_t s_t_bits[3] = { 3, 2, 2 };
  2861. for (uint32_t T_ofs = 0, c = 0; c < num_vals; c++)
  2862. {
  2863. if (bits_per_val)
  2864. m[c] = bits.next_bits(bit_ofs, bits_per_val);
  2865. T |= (bits.next_bits(bit_ofs, s_t_bits[c]) << T_ofs);
  2866. T_ofs += s_t_bits[c];
  2867. }
  2868. const uint8_t (&p_quints)[3] = s_quint_decode[T];
  2869. for (uint32_t i = 0; i < num_vals; i++)
  2870. pVals[i] = (uint8_t)((p_quints[i] << bits_per_val) | m[i]);
  2871. }
  2872. static void decode_bise(uint32_t ise_range, uint8_t* pVals, uint32_t num_vals, const uint128& bits, uint32_t bit_ofs)
  2873. {
  2874. assert(num_vals && (ise_range < TOTAL_ISE_RANGES));
  2875. const uint32_t bits_per_val = g_ise_range_table[ise_range][0];
  2876. if (g_ise_range_table[ise_range][1])
  2877. {
  2878. // Trits+bits, 5 vals per block, 7 bits extra per block
  2879. const uint32_t total_blocks = (num_vals + 4) / 5;
  2880. for (uint32_t b = 0; b < total_blocks; b++)
  2881. {
  2882. const uint32_t num_vals_in_block = std::min<int>(num_vals - 5 * b, 5);
  2883. decode_trit_block(pVals + 5 * b, num_vals_in_block, bits, bit_ofs, bits_per_val);
  2884. }
  2885. }
  2886. else if (g_ise_range_table[ise_range][2])
  2887. {
  2888. // Quints+bits, 3 vals per block, 8 bits extra per block
  2889. const uint32_t total_blocks = (num_vals + 2) / 3;
  2890. for (uint32_t b = 0; b < total_blocks; b++)
  2891. {
  2892. const uint32_t num_vals_in_block = std::min<int>(num_vals - 3 * b, 3);
  2893. decode_quint_block(pVals + 3 * b, num_vals_in_block, bits, bit_ofs, bits_per_val);
  2894. }
  2895. }
  2896. else
  2897. {
  2898. assert(bits_per_val);
  2899. // Only bits
  2900. for (uint32_t i = 0; i < num_vals; i++)
  2901. pVals[i] = (uint8_t)bits.next_bits(bit_ofs, bits_per_val);
  2902. }
  2903. }
  2904. void decode_bise(uint32_t ise_range, uint8_t* pVals, uint32_t num_vals, const uint8_t* pBits128, uint32_t bit_ofs)
  2905. {
  2906. const uint128 bits(
  2907. (uint64_t)read_le_dword(pBits128) | (((uint64_t)read_le_dword(pBits128 + sizeof(uint32_t))) << 32),
  2908. (uint64_t)read_le_dword(pBits128 + sizeof(uint32_t) * 2) | (((uint64_t)read_le_dword(pBits128 + sizeof(uint32_t) * 3)) << 32));
  2909. return decode_bise(ise_range, pVals, num_vals, bits, bit_ofs);
  2910. }
  2911. // Decodes a physical ASTC block to a logical ASTC block.
  2912. // blk_width/blk_height are only used to validate the weight grid's dimensions.
  2913. bool unpack_block(const void* pASTC_block, log_astc_block& log_blk, uint32_t blk_width, uint32_t blk_height)
  2914. {
  2915. assert(is_valid_block_size(blk_width, blk_height));
  2916. const uint8_t* pS = (uint8_t*)pASTC_block;
  2917. log_blk.clear();
  2918. log_blk.m_error_flag = true;
  2919. const uint128 bits(
  2920. (uint64_t)read_le_dword(pS) | (((uint64_t)read_le_dword(pS + sizeof(uint32_t))) << 32),
  2921. (uint64_t)read_le_dword(pS + sizeof(uint32_t) * 2) | (((uint64_t)read_le_dword(pS + sizeof(uint32_t) * 3)) << 32));
  2922. const uint128 rev_bits(bits.get_reversed_bits());
  2923. if (!decode_config(bits, log_blk))
  2924. return false;
  2925. if (log_blk.m_solid_color_flag_hdr || log_blk.m_solid_color_flag_ldr)
  2926. {
  2927. // Void extent
  2928. log_blk.m_error_flag = false;
  2929. return true;
  2930. }
  2931. // Check grid dimensions
  2932. if ((log_blk.m_grid_width > blk_width) || (log_blk.m_grid_height > blk_height))
  2933. return false;
  2934. // Now we have the grid width/height, dual plane, weight ISE range
  2935. const uint32_t total_grid_weights = (log_blk.m_dual_plane ? 2 : 1) * (log_blk.m_grid_width * log_blk.m_grid_height);
  2936. const uint32_t total_weight_bits = get_ise_sequence_bits(total_grid_weights, log_blk.m_weight_ise_range);
  2937. // 18.24 Illegal Encodings
  2938. if ((!total_grid_weights) || (total_grid_weights > MAX_GRID_WEIGHTS) || (total_weight_bits < 24) || (total_weight_bits > 96))
  2939. return false;
  2940. const uint32_t end_of_weight_bit_ofs = 128 - total_weight_bits;
  2941. uint32_t total_extra_bits = 0;
  2942. // Right before the weight bits, there may be extra CEM bits, then the 2 CCS bits if dual plane.
  2943. log_blk.m_num_partitions = (uint8_t)(bits.get_bits(11, 2) + 1);
  2944. if (log_blk.m_num_partitions == 1)
  2945. log_blk.m_color_endpoint_modes[0] = (uint8_t)(bits.get_bits(13, 4)); // read CEM bits
  2946. else
  2947. {
  2948. // 2 or more partitions
  2949. if (log_blk.m_dual_plane && (log_blk.m_num_partitions == 4))
  2950. return false;
  2951. log_blk.m_partition_id = (uint16_t)bits.get_bits(13, 10);
  2952. uint32_t cem_bits = bits.get_bits(23, 6);
  2953. if ((cem_bits & 3) == 0)
  2954. {
  2955. // All CEM's the same
  2956. for (uint32_t i = 0; i < log_blk.m_num_partitions; i++)
  2957. log_blk.m_color_endpoint_modes[i] = (uint8_t)(cem_bits >> 2);
  2958. }
  2959. else
  2960. {
  2961. // CEM's different, but within up to 2 adjacent classes
  2962. const uint32_t first_cem_index = ((cem_bits & 3) - 1) * 4;
  2963. total_extra_bits = 3 * log_blk.m_num_partitions - 4;
  2964. if ((total_weight_bits + total_extra_bits) > 128)
  2965. return false;
  2966. uint32_t cem_bit_pos = end_of_weight_bit_ofs - total_extra_bits;
  2967. uint32_t c[4] = { 0 }, m[4] = { 0 };
  2968. cem_bits >>= 2;
  2969. for (uint32_t i = 0; i < log_blk.m_num_partitions; i++, cem_bits >>= 1)
  2970. c[i] = cem_bits & 1;
  2971. switch (log_blk.m_num_partitions)
  2972. {
  2973. case 2:
  2974. {
  2975. m[0] = cem_bits & 3;
  2976. m[1] = bits.next_bits(cem_bit_pos, 2);
  2977. break;
  2978. }
  2979. case 3:
  2980. {
  2981. m[0] = cem_bits & 1;
  2982. m[0] |= (bits.next_bits(cem_bit_pos, 1) << 1);
  2983. m[1] = bits.next_bits(cem_bit_pos, 2);
  2984. m[2] = bits.next_bits(cem_bit_pos, 2);
  2985. break;
  2986. }
  2987. case 4:
  2988. {
  2989. for (uint32_t i = 0; i < 4; i++)
  2990. m[i] = bits.next_bits(cem_bit_pos, 2);
  2991. break;
  2992. }
  2993. default:
  2994. {
  2995. assert(0);
  2996. break;
  2997. }
  2998. }
  2999. assert(cem_bit_pos == end_of_weight_bit_ofs);
  3000. for (uint32_t i = 0; i < log_blk.m_num_partitions; i++)
  3001. {
  3002. log_blk.m_color_endpoint_modes[i] = (uint8_t)(first_cem_index + (c[i] * 4) + m[i]);
  3003. assert(log_blk.m_color_endpoint_modes[i] <= 15);
  3004. }
  3005. }
  3006. }
  3007. // Now we have all the CEM indices.
  3008. if (log_blk.m_dual_plane)
  3009. {
  3010. // Read CCS bits, beneath any CEM bits
  3011. total_extra_bits += 2;
  3012. if (total_extra_bits > end_of_weight_bit_ofs)
  3013. return false;
  3014. uint32_t ccs_bit_pos = end_of_weight_bit_ofs - total_extra_bits;
  3015. log_blk.m_color_component_selector = (uint8_t)(bits.get_bits(ccs_bit_pos, 2));
  3016. }
  3017. uint32_t config_bit_pos = 11 + 2; // config+num_parts
  3018. if (log_blk.m_num_partitions == 1)
  3019. config_bit_pos += 4; // CEM bits
  3020. else
  3021. config_bit_pos += 10 + 6; // part_id+CEM bits
  3022. // config+num_parts+total_extra_bits (CEM extra+CCS)
  3023. uint32_t total_config_bits = config_bit_pos + total_extra_bits;
  3024. // Compute number of remaining bits in block
  3025. const int num_remaining_bits = 128 - (int)total_config_bits - (int)total_weight_bits;
  3026. if (num_remaining_bits < 0)
  3027. return false;
  3028. // Compute total number of ISE encoded color endpoint mode values
  3029. uint32_t total_cem_vals = 0;
  3030. for (uint32_t j = 0; j < log_blk.m_num_partitions; j++)
  3031. total_cem_vals += get_num_cem_values(log_blk.m_color_endpoint_modes[j]);
  3032. if (total_cem_vals > MAX_ENDPOINTS)
  3033. return false;
  3034. // Infer endpoint ISE range based off the # of values we need to encode, and the # of remaining bits in the block
  3035. int endpoint_ise_range = -1;
  3036. for (int k = 20; k > 0; k--)
  3037. {
  3038. int b = get_ise_sequence_bits(total_cem_vals, k);
  3039. if (b <= num_remaining_bits)
  3040. {
  3041. endpoint_ise_range = k;
  3042. break;
  3043. }
  3044. }
  3045. // See 23.24 Illegal Encodings, [0,5] is the minimum ISE encoding for endpoints
  3046. if (endpoint_ise_range < (int)FIRST_VALID_ENDPOINT_ISE_RANGE)
  3047. return false;
  3048. log_blk.m_endpoint_ise_range = (uint8_t)endpoint_ise_range;
  3049. // Decode endpoints forwards in block
  3050. decode_bise(log_blk.m_endpoint_ise_range, log_blk.m_endpoints, total_cem_vals, bits, config_bit_pos);
  3051. // Decode grid weights backwards in block
  3052. decode_bise(log_blk.m_weight_ise_range, log_blk.m_weights, total_grid_weights, rev_bits, 0);
  3053. log_blk.m_error_flag = false;
  3054. return true;
  3055. }
  3056. } // namespace astc_helpers
  3057. #endif //BASISU_ASTC_HELPERS_IMPLEMENTATION