yariv.h 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383
  1. // The latest version of this library is available on GitHub;
  2. // https://github.com/sheredom/yari-v
  3. // This is free and unencumbered software released into the public domain.
  4. //
  5. // Anyone is free to copy, modify, publish, use, compile, sell, or
  6. // distribute this software, either in source code form or as a compiled
  7. // binary, for any purpose, commercial or non-commercial, and by any
  8. // means.
  9. //
  10. // In jurisdictions that recognize copyright laws, the author or authors
  11. // of this software dedicate any and all copyright interest in the
  12. // software to the public domain. We make this dedication for the benefit
  13. // of the public at large and to the detriment of our heirs and
  14. // successors. We intend this dedication to be an overt act of
  15. // relinquishment in perpetuity of all present and future rights to this
  16. // software under copyright law.
  17. //
  18. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  21. // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  22. // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  23. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  24. // OTHER DEALINGS IN THE SOFTWARE.
  25. //
  26. // For more information, please refer to <http://unlicense.org/>
  27. #ifndef SHEREDOM_YARIV_H_INCLUDED
  28. #define SHEREDOM_YARIV_H_INCLUDED
  29. #include <stddef.h>
  30. #include <stdint.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #ifdef __cplusplus
  34. extern "C" {
  35. #endif
  36. enum yariv_encode_flags_e {
  37. yariv_encode_flags_default = 0,
  38. // enable the SPIR-V to be stripped of all non-essential information
  39. yariv_encode_flags_strip = 0x1
  40. };
  41. #if defined(__clang__) || defined(__GNUC__)
  42. #define yariv_nonnull __attribute__((nonnull))
  43. #define yariv_weak __attribute__((weak))
  44. #elif defined(_MSC_VER)
  45. #define yariv_nonnull
  46. #define yariv_weak __inline
  47. #else
  48. #error Non clang, non gcc, non MSVC compiler found!
  49. #endif
  50. yariv_nonnull yariv_weak size_t yariv_encode_size(uint32_t encode_flags,
  51. const void *spirv,
  52. size_t spirv_size);
  53. yariv_nonnull yariv_weak int yariv_encode(uint32_t encode_flags,
  54. void *out_yariv,
  55. size_t out_yariv_size,
  56. const void *spirv, size_t spirv_size);
  57. yariv_nonnull yariv_weak size_t yariv_decode_size(const void *yariv,
  58. size_t yariv_size);
  59. yariv_nonnull yariv_weak int yariv_decode(void *out_spirv,
  60. size_t out_spirv_size,
  61. const void *yariv, size_t yariv_size);
  62. yariv_weak size_t yariv_encode_signed_varint(int32_t i, uint8_t *out);
  63. yariv_weak size_t yariv_decode_signed_varint(const uint8_t *in, int32_t *out);
  64. yariv_weak size_t yariv_encode_unsigned_varint(uint32_t i, uint8_t *out);
  65. yariv_weak size_t yariv_decode_unsigned_varint(const uint8_t *in,
  66. uint32_t *out);
  67. yariv_weak uint32_t yariv_shuffle_opcode(uint32_t opcode);
  68. yariv_weak int yariv_opcode_has_word_count(uint32_t opcode,
  69. uint32_t *word_count);
  70. yariv_weak int yariv_opcode_has_id(uint32_t opcode);
  71. yariv_weak int yariv_opcode_has_type_and_id(uint32_t opcode);
  72. yariv_weak uint32_t yariv_opcode_maybe_split(uint32_t opcode,
  73. const uint32_t *spirv,
  74. uint32_t word_count);
  75. yariv_weak uint32_t yariv_word_count_constant_part(uint32_t opcode);
  76. yariv_weak uint32_t yariv_word_count_to_id_delta(uint32_t opcode,
  77. uint32_t word_count);
  78. #undef yariv_weak
  79. #undef yariv_nonnull
  80. enum YarivOpcode_s {
  81. YarivOpNop = 0,
  82. YarivOpUndef = 1,
  83. YarivOpSourceContinued = 2,
  84. YarivOpSource = 3,
  85. YarivOpSourceExtension = 4,
  86. YarivOpName = 5,
  87. YarivOpMemberName = 6,
  88. YarivOpString = 7,
  89. YarivOpLine = 8,
  90. YarivOp9 = 9, // There is a gap in the SPIR-V opcode numbering here
  91. YarivOpExtension = 10,
  92. YarivOpExtInstImport = 11,
  93. YarivOpExtInst = 12,
  94. YarivOp13 = 13, // There is a gap in the SPIR-V opcode numbering here
  95. YarivOpMemoryModel = 14,
  96. YarivOpEntryPoint = 15,
  97. YarivOpExecutionMode = 16,
  98. YarivOpCapability = 17,
  99. YarivOp18 = 18, // There is a gap in the SPIR-V opcode numbering here
  100. YarivOpTypeVoid = 19,
  101. YarivOpTypeBool = 20,
  102. YarivOpTypeInt = 21,
  103. YarivOpTypeFloat = 22,
  104. YarivOpTypeVector = 23,
  105. YarivOpTypeMatrix = 24,
  106. YarivOpTypeImage = 25,
  107. YarivOpTypeSampler = 26,
  108. YarivOpTypeSampledImage = 27,
  109. YarivOpTypeArray = 28,
  110. YarivOpTypeRuntimeArray = 29,
  111. YarivOpTypeStruct = 30,
  112. YarivOpTypeOpaque = 31,
  113. YarivOpTypePointer = 32,
  114. YarivOpTypeFunction = 33,
  115. YarivOpTypeEvent = 34,
  116. YarivOpTypeDeviceEvent = 35,
  117. YarivOpTypeReserveId = 36,
  118. YarivOpTypeQueue = 37,
  119. YarivOpTypePipe = 38,
  120. YarivOpTypeForwardPointer = 39,
  121. YarivOp40 = 40, // There is a gap in the SPIR-V opcode numbering here
  122. YarivOpConstantTrue = 41,
  123. YarivOpConstantFalse = 42,
  124. YarivOpConstant = 43,
  125. YarivOpConstantComposite = 44,
  126. YarivOpConstantSampler = 45,
  127. YarivOpConstantNull = 46,
  128. YarivOp47 = 47, // There is a gap in the SPIR-V opcode numbering here
  129. YarivOpSpecConstantTrue = 48,
  130. YarivOpSpecConstantFalse = 49,
  131. YarivOpSpecConstant = 50,
  132. YarivOpSpecConstantComposite = 51,
  133. YarivOpSpecConstantOp = 52,
  134. YarivOp53 = 53, // There is a gap in the SPIR-V opcode numbering here
  135. YarivOpFunction = 54,
  136. YarivOpFunctionParameter = 55,
  137. YarivOpFunctionEnd = 56,
  138. YarivOpFunctionCall = 57,
  139. YarivOp58 = 58, // There is a gap in the SPIR-V opcode numbering here
  140. YarivOpVariable = 59,
  141. YarivOpImageTexelPointer = 60,
  142. YarivOpLoad = 61,
  143. YarivOpStore = 62,
  144. YarivOpCopyMemory = 63,
  145. YarivOpCopyMemorySized = 64,
  146. YarivOpAccessChain = 65,
  147. YarivOpInBoundsAccessChain = 66,
  148. YarivOpPtrAccessChain = 67,
  149. YarivOpArrayLength = 68,
  150. YarivOpGenericPtrMemSemantics = 69,
  151. YarivOpInBoundsPtrAccessChain = 70,
  152. YarivOpDecorate = 71,
  153. YarivOpMemberDecorate = 72,
  154. YarivOpDecorationGroup = 73,
  155. YarivOpGroupDecorate = 74,
  156. YarivOpGroupMemberDecorate = 75,
  157. YarivOp76 = 76, // There is a gap in the SPIR-V opcode numbering here
  158. YarivOpVectorExtractDynamic = 77,
  159. YarivOpVectorInsertDynamic = 78,
  160. YarivOpVectorShuffle = 79,
  161. YarivOpCompositeConstruct = 80,
  162. YarivOpCompositeExtract = 81,
  163. YarivOpCompositeInsert = 82,
  164. YarivOpCopyObject = 83,
  165. YarivOpTranspose = 84,
  166. YarivOp85 = 85, // There is a gap in the SPIR-V opcode numbering here
  167. YarivOpSampledImage = 86,
  168. YarivOpImageSampleImplicitLod = 87,
  169. YarivOpImageSampleExplicitLod = 88,
  170. YarivOpImageSampleDrefImplicitLod = 89,
  171. YarivOpImageSampleDrefExplicitLod = 90,
  172. YarivOpImageSampleProjImplicitLod = 91,
  173. YarivOpImageSampleProjExplicitLod = 92,
  174. YarivOpImageSampleProjDrefImplicitLod = 93,
  175. YarivOpImageSampleProjDrefExplicitLod = 94,
  176. YarivOpImageFetch = 95,
  177. YarivOpImageGather = 96,
  178. YarivOpImageDrefGather = 97,
  179. YarivOpImageRead = 98,
  180. YarivOpImageWrite = 99,
  181. YarivOpImage = 100,
  182. YarivOpImageQueryFormat = 101,
  183. YarivOpImageQueryOrder = 102,
  184. YarivOpImageQuerySizeLod = 103,
  185. YarivOpImageQuerySize = 104,
  186. YarivOpImageQueryLod = 105,
  187. YarivOpImageQueryLevels = 106,
  188. YarivOpImageQuerySamples = 107,
  189. YarivOp108 = 108, // There is a gap in the SPIR-V opcode numbering here
  190. YarivOpConvertFToU = 109,
  191. YarivOpConvertFToS = 110,
  192. YarivOpConvertSToF = 111,
  193. YarivOpConvertUToF = 112,
  194. YarivOpUConvert = 113,
  195. YarivOpSConvert = 114,
  196. YarivOpFConvert = 115,
  197. YarivOpQuantizeToF16 = 116,
  198. YarivOpConvertPtrToU = 117,
  199. YarivOpSatConvertSToU = 118,
  200. YarivOpSatConvertUToS = 119,
  201. YarivOpConvertUToPtr = 120,
  202. YarivOpPtrCastToGeneric = 121,
  203. YarivOpGenericCastToPtr = 122,
  204. YarivOpGenericCastToPtrExplicit = 123,
  205. YarivOpBitcast = 124,
  206. YarivOp125 = 125, // There is a gap in the SPIR-V opcode numbering here
  207. YarivOpSNegate = 126,
  208. YarivOpFNegate = 127,
  209. YarivOpIAdd = 128,
  210. YarivOpFAdd = 129,
  211. YarivOpISub = 130,
  212. YarivOpFSub = 131,
  213. YarivOpIMul = 132,
  214. YarivOpFMul = 133,
  215. YarivOpUDiv = 134,
  216. YarivOpSDiv = 135,
  217. YarivOpFDiv = 136,
  218. YarivOpUMod = 137,
  219. YarivOpSRem = 138,
  220. YarivOpSMod = 139,
  221. YarivOpFRem = 140,
  222. YarivOpFMod = 141,
  223. YarivOpVectorTimesScalar = 142,
  224. YarivOpMatrixTimesScalar = 143,
  225. YarivOpVectorTimesMatrix = 144,
  226. YarivOpMatrixTimesVector = 145,
  227. YarivOpMatrixTimesMatrix = 146,
  228. YarivOpOuterProduct = 147,
  229. YarivOpDot = 148,
  230. YarivOpIAddCarry = 149,
  231. YarivOpISubBorrow = 150,
  232. YarivOpUMulExtended = 151,
  233. YarivOpSMulExtended = 152,
  234. YarivOpAny = 154,
  235. YarivOpAll = 155,
  236. YarivOpIsNan = 156,
  237. YarivOpIsInf = 157,
  238. YarivOpIsFinite = 158,
  239. YarivOpIsNormal = 159,
  240. YarivOpSignBitSet = 160,
  241. YarivOpLessOrGreater = 161,
  242. YarivOpOrdered = 162,
  243. YarivOpUnordered = 163,
  244. YarivOpLogicalEqual = 164,
  245. YarivOpLogicalNotEqual = 165,
  246. YarivOpLogicalOr = 166,
  247. YarivOpLogicalAnd = 167,
  248. YarivOpLogicalNot = 168,
  249. YarivOpSelect = 169,
  250. YarivOpIEqual = 170,
  251. YarivOpINotEqual = 171,
  252. YarivOpUGreaterThan = 172,
  253. YarivOpSGreaterThan = 173,
  254. YarivOpUGreaterThanEqual = 174,
  255. YarivOpSGreaterThanEqual = 175,
  256. YarivOpULessThan = 176,
  257. YarivOpSLessThan = 177,
  258. YarivOpULessThanEqual = 178,
  259. YarivOpSLessThanEqual = 179,
  260. YarivOpFOrdEqual = 180,
  261. YarivOpFUnordEqual = 181,
  262. YarivOpFOrdNotEqual = 182,
  263. YarivOpFUnordNotEqual = 183,
  264. YarivOpFOrdLessThan = 184,
  265. YarivOpFUnordLessThan = 185,
  266. YarivOpFOrdGreaterThan = 186,
  267. YarivOpFUnordGreaterThan = 187,
  268. YarivOpFOrdLessThanEqual = 188,
  269. YarivOpFUnordLessThanEqual = 189,
  270. YarivOpFOrdGreaterThanEqual = 190,
  271. YarivOpFUnordGreaterThanEqual = 191,
  272. YarivOpShiftRightLogical = 194,
  273. YarivOpShiftRightArithmetic = 195,
  274. YarivOpShiftLeftLogical = 196,
  275. YarivOpBitwiseOr = 197,
  276. YarivOpBitwiseXor = 198,
  277. YarivOpBitwiseAnd = 199,
  278. YarivOpNot = 200,
  279. YarivOpBitFieldInsert = 201,
  280. YarivOpBitFieldSExtract = 202,
  281. YarivOpBitFieldUExtract = 203,
  282. YarivOpBitReverse = 204,
  283. YarivOpBitCount = 205,
  284. YarivOpDPdx = 207,
  285. YarivOpDPdy = 208,
  286. YarivOpFwidth = 209,
  287. YarivOpDPdxFine = 210,
  288. YarivOpDPdyFine = 211,
  289. YarivOpFwidthFine = 212,
  290. YarivOpDPdxCoarse = 213,
  291. YarivOpDPdyCoarse = 214,
  292. YarivOpFwidthCoarse = 215,
  293. YarivOpEmitVertex = 218,
  294. YarivOpEndPrimitive = 219,
  295. YarivOpEmitStreamVertex = 220,
  296. YarivOpEndStreamPrimitive = 221,
  297. YarivOpControlBarrier = 224,
  298. YarivOpMemoryBarrier = 225,
  299. YarivOpAtomicLoad = 227,
  300. YarivOpAtomicStore = 228,
  301. YarivOpAtomicExchange = 229,
  302. YarivOpAtomicCompareExchange = 230,
  303. YarivOpAtomicCompareExchangeWeak = 231,
  304. YarivOpAtomicIIncrement = 232,
  305. YarivOpAtomicIDecrement = 233,
  306. YarivOpAtomicIAdd = 234,
  307. YarivOpAtomicISub = 235,
  308. YarivOpAtomicSMin = 236,
  309. YarivOpAtomicUMin = 237,
  310. YarivOpAtomicSMax = 238,
  311. YarivOpAtomicUMax = 239,
  312. YarivOpAtomicAnd = 240,
  313. YarivOpAtomicOr = 241,
  314. YarivOpAtomicXor = 242,
  315. YarivOpPhi = 245,
  316. YarivOpLoopMerge = 246,
  317. YarivOpSelectionMerge = 247,
  318. YarivOpLabel = 248,
  319. YarivOpBranch = 249,
  320. YarivOpBranchConditional = 250,
  321. YarivOpSwitch = 251,
  322. YarivOpKill = 252,
  323. YarivOpReturn = 253,
  324. YarivOpReturnValue = 254,
  325. YarivOpUnreachable = 255,
  326. YarivOpLifetimeStart = 256,
  327. YarivOpLifetimeStop = 257,
  328. YarivOpGroupAsyncCopy = 259,
  329. YarivOpGroupWaitEvents = 260,
  330. YarivOpGroupAll = 261,
  331. YarivOpGroupAny = 262,
  332. YarivOpGroupBroadcast = 263,
  333. YarivOpGroupIAdd = 264,
  334. YarivOpGroupFAdd = 265,
  335. YarivOpGroupFMin = 266,
  336. YarivOpGroupUMin = 267,
  337. YarivOpGroupSMin = 268,
  338. YarivOpGroupFMax = 269,
  339. YarivOpGroupUMax = 270,
  340. YarivOpGroupSMax = 271,
  341. YarivOpReadPipe = 274,
  342. YarivOpWritePipe = 275,
  343. YarivOpReservedReadPipe = 276,
  344. YarivOpReservedWritePipe = 277,
  345. YarivOpReserveReadPipePackets = 278,
  346. YarivOpReserveWritePipePackets = 279,
  347. YarivOpCommitReadPipe = 280,
  348. YarivOpCommitWritePipe = 281,
  349. YarivOpIsValidReserveId = 282,
  350. YarivOpGetNumPipePackets = 283,
  351. YarivOpGetMaxPipePackets = 284,
  352. YarivOpGroupReserveReadPipePackets = 285,
  353. YarivOpGroupReserveWritePipePackets = 286,
  354. YarivOpGroupCommitReadPipe = 287,
  355. YarivOpGroupCommitWritePipe = 288,
  356. YarivOpEnqueueMarker = 291,
  357. YarivOpEnqueueKernel = 292,
  358. YarivOpGetKernelNDrangeSubGroupCount = 293,
  359. YarivOpGetKernelNDrangeMaxSubGroupSize = 294,
  360. YarivOpGetKernelWorkGroupSize = 295,
  361. YarivOpGetKernelPreferredWorkGroupSizeMultiple = 296,
  362. YarivOpRetainEvent = 297,
  363. YarivOpReleaseEvent = 298,
  364. YarivOpCreateUserEvent = 299,
  365. YarivOpIsValidEvent = 300,
  366. YarivOpSetUserEventStatus = 301,
  367. YarivOpCaptureEventProfilingInfo = 302,
  368. YarivOpGetDefaultQueue = 303,
  369. YarivOpBuildNDRange = 304,
  370. YarivOpImageSparseSampleImplicitLod = 305,
  371. YarivOpImageSparseSampleExplicitLod = 306,
  372. YarivOpImageSparseSampleDrefImplicitLod = 307,
  373. YarivOpImageSparseSampleDrefExplicitLod = 308,
  374. YarivOpImageSparseSampleProjImplicitLod = 309,
  375. YarivOpImageSparseSampleProjExplicitLod = 310,
  376. YarivOpImageSparseSampleProjDrefImplicitLod = 311,
  377. YarivOpImageSparseSampleProjDrefExplicitLod = 312,
  378. YarivOpImageSparseFetch = 313,
  379. YarivOpImageSparseGather = 314,
  380. YarivOpImageSparseDrefGather = 315,
  381. YarivOpImageSparseTexelsResident = 316,
  382. YarivOpNoLine = 317,
  383. YarivOpAtomicFlagTestAndSet = 318,
  384. YarivOpAtomicFlagClear = 319,
  385. YarivOpImageSparseRead = 320,
  386. // the following are not actual SPIR-V opcodes, but I want to generate them
  387. // and treat them as such in the encoder/decoder
  388. YarivOpLoadWithMemoryAccess = 500,
  389. YarivOpStoreWithMemoryAccess = 501,
  390. YarivOpDecorateWithNoLiterals = 502,
  391. YarivOpDecorateWithOneLiteral = 503,
  392. YarivOpMemberDecorateWithNoLiterals = 504,
  393. YarivOpMemberDecorateWithOneLiteral = 505,
  394. YarivOpVariableWithInitializer = 506,
  395. YarivOpConstantWithManyLiterals = 507,
  396. YarivOpAccessChainWithOneIndex = 508,
  397. YarivOpAccessChainWithTwoIndices = 509,
  398. YarivOpAccessChainWithThreeIndices = 510,
  399. YarivOpVectorShuffleTwoLiterals = 511,
  400. YarivOpVectorShuffleThreeLiterals = 512,
  401. YarivOpVectorShuffleFourLiterals = 513,
  402. YarivOp514 = 514,
  403. YarivOp515 = 515,
  404. YarivOp516 = 516,
  405. YarivOpVectorSwizzleTwoLiterals = 517,
  406. YarivOpVectorSwizzleThreeLiterals = 518,
  407. YarivOpVectorSwizzleFourLiterals = 519,
  408. YarivOpCompositeExtractWithLiteralZero = 520,
  409. YarivOpCompositeExtractWithLiteralOne = 521,
  410. YarivOpCompositeExtractWithLiteralTwo = 522,
  411. YarivOpCompositeExtractWithLiteralThree = 523,
  412. YarivOpCompositeConstructOneConstituent = 524,
  413. YarivOpCompositeConstructTwoConstituents = 525,
  414. YarivOpCompositeConstructThreeConstituents = 526,
  415. YarivOpDecorateRelaxedPrecision = 527,
  416. YarivOpMemberDecorateOffset = 528,
  417. YarivOpConstantWithOneFloatLiteral = 529,
  418. YarivOpDecorateLocation = 530
  419. };
  420. #if defined(__cplusplus)
  421. #define YARIV_CAST(type, x) (static_cast<type>(x))
  422. #else
  423. #define YARIV_CAST(type, x) ((type)(x))
  424. #endif
  425. size_t yariv_encode_size(uint32_t encode_flags, const void *spirv,
  426. size_t spirv_size) {
  427. size_t yariv_size = 0;
  428. size_t i, e;
  429. int32_t last_id = 1;
  430. const uint32_t type_offset = 1;
  431. // for the SPIR-V header
  432. // * we skip encoding SPIR-V's magic number at the beginning of the binary
  433. // * we use two bytes to encode the version number
  434. yariv_size += 2;
  435. // * we use varint encoding for the generators magic number
  436. yariv_size +=
  437. yariv_encode_unsigned_varint(YARIV_CAST(const uint32_t *, spirv)[2], 0);
  438. // * we use varint encoding for the bound (maximum ID used)
  439. yariv_size +=
  440. yariv_encode_unsigned_varint(YARIV_CAST(const uint32_t *, spirv)[3], 0);
  441. // * we skip encoding the instruction schema
  442. // iterate through all the opcodes
  443. for (i = 5, e = spirv_size / 4; i < e;) {
  444. const uint32_t *from = YARIV_CAST(const uint32_t *, spirv) + i;
  445. const uint32_t word_count = (*from) >> 16;
  446. uint32_t opcode = (*from) & 0xFFFFu;
  447. uint32_t k;
  448. int32_t maybe_update_id = last_id;
  449. // if we can strip opcodes
  450. if (yariv_encode_flags_strip & encode_flags) {
  451. switch (opcode) {
  452. default:
  453. break;
  454. case YarivOpNop:
  455. case YarivOpSourceContinued:
  456. case YarivOpSource:
  457. case YarivOpSourceExtension:
  458. case YarivOpName:
  459. case YarivOpMemberName:
  460. case YarivOpString:
  461. case YarivOpLine:
  462. case YarivOpNoLine:
  463. // all of these opcodes can be stripped, so we skip them!
  464. i += word_count;
  465. continue;
  466. }
  467. }
  468. opcode = yariv_opcode_maybe_split(opcode, from, word_count);
  469. // we encode the opcode first as a varint
  470. yariv_size += yariv_encode_unsigned_varint(yariv_shuffle_opcode(opcode), 0);
  471. // followed by the word_count as a varint
  472. if (!yariv_opcode_has_word_count(opcode, 0)) {
  473. // we encode word count minus the constant part of the word count (derived
  474. // from the opcode)
  475. yariv_size += yariv_encode_unsigned_varint(
  476. word_count - yariv_word_count_constant_part(opcode), 0);
  477. }
  478. // by default, we use unsigned varint encoding from the word immediately
  479. // following the opcode/word-count word
  480. k = 1;
  481. if (yariv_opcode_has_id(opcode)) {
  482. // if our opcode has an id, we want to use signed varint encoding
  483. // relative to the last id we used
  484. const int32_t id = YARIV_CAST(const int32_t *, spirv)[i + 1];
  485. yariv_size += yariv_encode_signed_varint(id - last_id, 0);
  486. maybe_update_id = id;
  487. // and since we have already encoded the first word, k should skip
  488. // another word for the remaining unsigned varint encoding
  489. k += 1;
  490. } else if (yariv_opcode_has_type_and_id(opcode)) {
  491. // if our opcode has a type and id, we want to use signed varint
  492. // encoding for the id relative to the last id we used
  493. const uint32_t type = YARIV_CAST(const uint32_t *, spirv)[i + 1];
  494. const int32_t id = YARIV_CAST(const int32_t *, spirv)[i + 2];
  495. yariv_size += yariv_encode_unsigned_varint(type - type_offset, 0);
  496. yariv_size += yariv_encode_signed_varint(id - last_id, 0);
  497. maybe_update_id = id;
  498. // and since we have already encoded the first two words, k should skip
  499. // another two words for the remaining unsigned varint encoding
  500. k += 2;
  501. }
  502. switch (opcode) {
  503. default:
  504. // then we encode some words as signed varints
  505. for (; k < yariv_word_count_to_id_delta(opcode, word_count); k++) {
  506. const int32_t id = YARIV_CAST(const int32_t *, spirv)[i + k];
  507. yariv_size += yariv_encode_signed_varint(id - last_id, 0);
  508. }
  509. // then we encode the remaining words as unsigned varints
  510. for (; k < word_count; k++) {
  511. yariv_size += yariv_encode_unsigned_varint(
  512. YARIV_CAST(const uint32_t *, spirv)[i + k], 0);
  513. }
  514. break;
  515. case YarivOpExtInstImport:
  516. // our literal string can just be memcpy'ed over
  517. yariv_size += sizeof(uint32_t) * (word_count - k);
  518. break;
  519. case YarivOpVectorShuffleTwoLiterals:
  520. case YarivOpVectorShuffleThreeLiterals:
  521. case YarivOpVectorShuffleFourLiterals: {
  522. const int32_t vecid1 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  523. const int32_t vecid2 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  524. // we use the signed varint encoding relative to last id for the two
  525. // vectors we are shuffling (but we don't update last id crucially)
  526. yariv_size += yariv_encode_signed_varint(vecid1 - last_id, 0);
  527. yariv_size += yariv_encode_signed_varint(vecid2 - last_id, 0);
  528. // our literals are at most 3 bits each, and we have n of them
  529. if (YarivOpVectorShuffleTwoLiterals == opcode) {
  530. yariv_size += sizeof(uint8_t);
  531. } else {
  532. yariv_size += sizeof(uint8_t) * 2;
  533. }
  534. } break;
  535. case YarivOpVectorSwizzleTwoLiterals:
  536. case YarivOpVectorSwizzleThreeLiterals:
  537. case YarivOpVectorSwizzleFourLiterals: {
  538. // both our IDs are the same, so we output it only once
  539. const int32_t vecid1 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  540. // skip the ID that is the same
  541. k++;
  542. // we use the signed varint encoding relative to last id for the two
  543. // vectors we are shuffling (but we don't update last id crucially)
  544. yariv_size += yariv_encode_signed_varint(vecid1 - last_id, 0);
  545. // our literals are at most 2 bits each, and we have n of them
  546. yariv_size += sizeof(uint8_t);
  547. } break;
  548. case YarivOpCompositeExtractWithLiteralZero:
  549. case YarivOpCompositeExtractWithLiteralOne:
  550. case YarivOpCompositeExtractWithLiteralTwo:
  551. case YarivOpCompositeExtractWithLiteralThree: {
  552. // the id of the composite we are extracting from
  553. const int32_t composite = YARIV_CAST(const int32_t *, spirv)[i + k++];
  554. // we use the signed varint encoding relative to last id for the two
  555. // vectors we are shuffling (but we don't update last id crucially)
  556. yariv_size += yariv_encode_signed_varint(composite - last_id, 0);
  557. // skip the literal that we are not going to encode
  558. k++;
  559. } break;
  560. case YarivOpDecorateRelaxedPrecision:
  561. // skip the decoration for relaxed precision that we are not going to
  562. // encode
  563. k++;
  564. break;
  565. case YarivOpMemberDecorateOffset:
  566. // encode the member literal as a varint
  567. yariv_size += yariv_encode_unsigned_varint(
  568. YARIV_CAST(const uint32_t *, spirv)[i + k++], 0);
  569. // skip the decoration for offset that we are not going to encode
  570. k++;
  571. // encode the byte offset as a varint
  572. yariv_size += yariv_encode_unsigned_varint(
  573. YARIV_CAST(const uint32_t *, spirv)[i + k++], 0);
  574. break;
  575. case YarivOpConstantWithOneFloatLiteral:
  576. // our literal is a float, so we just encode it using 4 bytes
  577. yariv_size += sizeof(uint32_t);
  578. break;
  579. case YarivOpDecorateLocation:
  580. // skip the decoration for location that we are not going to encode
  581. k++;
  582. // encode the location as a varint
  583. yariv_size += yariv_encode_unsigned_varint(
  584. YARIV_CAST(const uint32_t *, spirv)[i + k++], 0);
  585. break;
  586. }
  587. // bump i along
  588. i += word_count;
  589. // set last id to be the one we (might) have set
  590. last_id = maybe_update_id;
  591. }
  592. return yariv_size;
  593. }
  594. int yariv_encode(uint32_t encode_flags, void *out_yariv, size_t out_yariv_size,
  595. const void *spirv, size_t spirv_size) {
  596. size_t i, e;
  597. int32_t last_id = 1;
  598. const uint32_t type_offset = 1;
  599. uint8_t *yariv = YARIV_CAST(uint8_t *, out_yariv);
  600. // FIXME: I should really check as I go that we don't try and write into
  601. // our_yariv beyond out_yariv_size!
  602. (void)out_yariv_size;
  603. // for the SPIR-V header
  604. // * encode the two bytes of the version number
  605. *yariv++ =
  606. YARIV_CAST(uint8_t, (YARIV_CAST(const uint32_t *, spirv)[1] >> 16));
  607. *yariv++ = YARIV_CAST(uint8_t, (YARIV_CAST(const uint32_t *, spirv)[1] >> 8));
  608. // * encode the varint for the generators magic number
  609. yariv += yariv_encode_unsigned_varint(YARIV_CAST(const uint32_t *, spirv)[2],
  610. yariv);
  611. // * encode the varint for the bound
  612. yariv += yariv_encode_unsigned_varint(YARIV_CAST(const uint32_t *, spirv)[3],
  613. yariv);
  614. // iterate through all the opcodes
  615. for (i = 5, e = spirv_size / 4; i < e;) {
  616. const uint32_t *from = YARIV_CAST(const uint32_t *, spirv) + i;
  617. const uint32_t word_count = (*from) >> 16;
  618. uint32_t opcode = (*from) & 0xFFFFu;
  619. uint32_t k;
  620. int32_t maybe_update_id = last_id;
  621. // if we can strip opcodes
  622. if (yariv_encode_flags_strip & encode_flags) {
  623. switch (opcode) {
  624. default:
  625. break;
  626. case YarivOpNop:
  627. case YarivOpSourceContinued:
  628. case YarivOpSource:
  629. case YarivOpSourceExtension:
  630. case YarivOpName:
  631. case YarivOpMemberName:
  632. case YarivOpString:
  633. case YarivOpLine:
  634. case YarivOpNoLine:
  635. // all of these opcodes can be stripped, so we skip them!
  636. i += word_count;
  637. continue;
  638. }
  639. }
  640. opcode = yariv_opcode_maybe_split(opcode, from, word_count);
  641. // for all opcodes we encode the opcode first as a varint
  642. yariv += yariv_encode_unsigned_varint(yariv_shuffle_opcode(opcode), yariv);
  643. if (!yariv_opcode_has_word_count(opcode, 0)) {
  644. // followed by the word count as a varint (removing the known constant
  645. // part of word count)
  646. yariv += yariv_encode_unsigned_varint(
  647. word_count - yariv_word_count_constant_part(opcode), yariv);
  648. }
  649. // by default, we use unsigned varint encoding from the word immediately
  650. // following the opcode/word-count word
  651. k = 1;
  652. if (yariv_opcode_has_id(opcode)) {
  653. // if our opcode has an id, we want to use signed varint encoding
  654. // relative to the last id we used
  655. const int32_t id = YARIV_CAST(const int32_t *, spirv)[i + 1];
  656. yariv += yariv_encode_signed_varint(id - last_id, yariv);
  657. maybe_update_id = id;
  658. // and since we have already encoded the first word, k should skip
  659. // another word for the remaining unsigned varint encoding
  660. k += 1;
  661. } else if (yariv_opcode_has_type_and_id(opcode)) {
  662. // if our opcode has a type and id, we want to use signed varint
  663. // encoding for the id relative to the last id we used
  664. const uint32_t type = YARIV_CAST(const uint32_t *, spirv)[i + 1];
  665. const int32_t id = YARIV_CAST(const int32_t *, spirv)[i + 2];
  666. yariv += yariv_encode_unsigned_varint(type - type_offset, yariv);
  667. yariv += yariv_encode_signed_varint(id - last_id, yariv);
  668. maybe_update_id = id;
  669. // and since we have already encoded the first two words, k should skip
  670. // another two words for the remaining unsigned varint encoding
  671. k += 2;
  672. }
  673. switch (opcode) {
  674. default:
  675. // then we encode some words as signed varints
  676. for (; k < yariv_word_count_to_id_delta(opcode, word_count); k++) {
  677. const int32_t id = YARIV_CAST(const int32_t *, spirv)[i + k];
  678. yariv += yariv_encode_signed_varint(id - last_id, yariv);
  679. }
  680. // then we encode the remaining words as unsigned varints
  681. for (; k < word_count; k++) {
  682. yariv += yariv_encode_unsigned_varint(
  683. YARIV_CAST(const uint32_t *, spirv)[i + k], yariv);
  684. }
  685. break;
  686. case YarivOpExtInstImport:
  687. // our literal string can just be memcpy'ed over
  688. memcpy(yariv, YARIV_CAST(const uint32_t *, spirv) + i + k,
  689. sizeof(uint32_t) * (word_count - k));
  690. yariv += sizeof(uint32_t) * (word_count - k);
  691. break;
  692. case YarivOpVectorShuffleTwoLiterals:
  693. case YarivOpVectorShuffleThreeLiterals:
  694. case YarivOpVectorShuffleFourLiterals: {
  695. const int32_t vecid1 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  696. const int32_t vecid2 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  697. // we use the signed varint encoding relative to last id for the two
  698. // vectors we are shuffling (but we don't update last id crucially)
  699. yariv += yariv_encode_signed_varint(vecid1 - last_id, yariv);
  700. yariv += yariv_encode_signed_varint(vecid2 - last_id, yariv);
  701. // our literals are at most 3 bits each, and we have n of them
  702. if (YarivOpVectorShuffleTwoLiterals == opcode) {
  703. const int32_t component0 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  704. const int32_t component1 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  705. *yariv++ = YARIV_CAST(uint8_t, ((component0 << 3) | component1) & 0xFF);
  706. } else if (YarivOpVectorShuffleThreeLiterals == opcode) {
  707. const int32_t component0 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  708. const int32_t component1 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  709. const int32_t component2 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  710. *yariv++ = YARIV_CAST(uint8_t, ((component0 << 3) | component1) & 0xFF);
  711. *yariv++ = YARIV_CAST(uint8_t, (component2)&0xFF);
  712. } else if (YarivOpVectorShuffleFourLiterals == opcode) {
  713. const int32_t component0 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  714. const int32_t component1 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  715. const int32_t component2 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  716. const int32_t component3 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  717. *yariv++ = YARIV_CAST(uint8_t, ((component0 << 3) | component1) & 0xFF);
  718. *yariv++ = YARIV_CAST(uint8_t, ((component2 << 3) | component3) & 0xFF);
  719. }
  720. } break;
  721. case YarivOpVectorSwizzleTwoLiterals:
  722. case YarivOpVectorSwizzleThreeLiterals:
  723. case YarivOpVectorSwizzleFourLiterals: {
  724. // both our IDs are the same, so we output it only once
  725. const int32_t vecid1 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  726. // skip the ID that is the same
  727. k++;
  728. // we use the signed varint encoding relative to last id for the one
  729. // vector we are shuffling (but we don't update last id crucially)
  730. yariv += yariv_encode_signed_varint(vecid1 - last_id, yariv);
  731. // our literals are at most 2 bits each, and we have n of them
  732. if (YarivOpVectorSwizzleTwoLiterals == opcode) {
  733. const int32_t component0 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  734. const int32_t component1 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  735. *yariv++ = YARIV_CAST(uint8_t, ((component0 << 2) | component1) & 0xFF);
  736. } else if (YarivOpVectorSwizzleThreeLiterals == opcode) {
  737. const int32_t component0 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  738. const int32_t component1 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  739. const int32_t component2 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  740. *yariv++ = YARIV_CAST(
  741. uint8_t,
  742. ((component0 << 4) | (component1 << 2) | component2) & 0xFF);
  743. } else if (YarivOpVectorSwizzleFourLiterals == opcode) {
  744. const int32_t component0 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  745. const int32_t component1 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  746. const int32_t component2 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  747. const int32_t component3 = YARIV_CAST(const int32_t *, spirv)[i + k++];
  748. *yariv++ = YARIV_CAST(uint8_t, ((component0 << 6) | (component1 << 4) |
  749. (component2 << 2) | component3) &
  750. 0xFF);
  751. }
  752. } break;
  753. case YarivOpCompositeExtractWithLiteralZero:
  754. case YarivOpCompositeExtractWithLiteralOne:
  755. case YarivOpCompositeExtractWithLiteralTwo:
  756. case YarivOpCompositeExtractWithLiteralThree: {
  757. // the id of the composite we are extracting from
  758. const int32_t composite = YARIV_CAST(const int32_t *, spirv)[i + k++];
  759. // we use the signed varint encoding relative to last id for the two
  760. // vectors we are shuffling (but we don't update last id crucially)
  761. yariv += yariv_encode_signed_varint(composite - last_id, yariv);
  762. // skip the literal that we are not going to encode
  763. k++;
  764. } break;
  765. case YarivOpDecorateRelaxedPrecision:
  766. // skip the decoration for relaxed precision that we are not going to
  767. // encode
  768. k++;
  769. break;
  770. case YarivOpMemberDecorateOffset:
  771. // encode the member literal as a varint
  772. yariv += yariv_encode_unsigned_varint(
  773. YARIV_CAST(const uint32_t *, spirv)[i + k++], yariv);
  774. // skip the decoration for offset that we are not going to encode
  775. k++;
  776. // encode the byte offset as a varint
  777. yariv += yariv_encode_unsigned_varint(
  778. YARIV_CAST(const uint32_t *, spirv)[i + k++], yariv);
  779. break;
  780. case YarivOpConstantWithOneFloatLiteral:
  781. // our literal is a float, so we just encode it using 4 bytes
  782. memcpy(yariv, YARIV_CAST(const uint32_t *, spirv) + i + k++,
  783. sizeof(uint32_t));
  784. yariv += sizeof(uint32_t);
  785. break;
  786. case YarivOpDecorateLocation:
  787. // skip the decoration for location that we are not going to encode
  788. k++;
  789. // encode the location as a varint
  790. yariv += yariv_encode_unsigned_varint(
  791. YARIV_CAST(const uint32_t *, spirv)[i + k++], yariv);
  792. break;
  793. }
  794. // and move i along to the next opcode
  795. i += word_count;
  796. // and (maybe) update last_id too!
  797. last_id = maybe_update_id;
  798. }
  799. return 0;
  800. }
  801. size_t yariv_decode_size(const void *yariv, size_t yariv_size) {
  802. // the SPIR-V header is 5 words
  803. size_t spirv_size = 5 * sizeof(uint32_t);
  804. size_t i = 2;
  805. // we need to decode the varints in the header
  806. // * the first varint is for our generators magic number
  807. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i, 0);
  808. // * the second varint is for our bound
  809. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i, 0);
  810. // iterate through all the opcodes
  811. while (i < yariv_size) {
  812. uint32_t opcode, word_count, k;
  813. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  814. &opcode);
  815. // shuffle the opcode back to its actual opcode
  816. opcode = yariv_shuffle_opcode(opcode);
  817. // our opcode/word-count pair takes up at least one word
  818. spirv_size += sizeof(uint32_t);
  819. if (!yariv_opcode_has_word_count(opcode, &word_count)) {
  820. // if the word count wasn't constant for the opcode, we encoded it as a
  821. // varint
  822. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  823. &word_count);
  824. // when we encoded the word count, we removed the known constant part of
  825. // the word count (derived from the opcode) we need to re-add this as we
  826. // re-encode word count
  827. word_count += yariv_word_count_constant_part(opcode);
  828. }
  829. // by default, we use unsigned varint encoding from the word immediately
  830. // following the opcode/word-count word
  831. k = 1;
  832. if (yariv_opcode_has_id(opcode)) {
  833. // if our opcode has an id, we used a signed varint encoding relative to
  834. // the last id
  835. i +=
  836. yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i, 0);
  837. spirv_size += sizeof(uint32_t);
  838. // and since we have already decoded the first word, k should skip
  839. // another word for the remaining unsigned varint decoding
  840. k += 1;
  841. } else if (yariv_opcode_has_type_and_id(opcode)) {
  842. // if our opcode has a type and id, we used a signed varint encoding
  843. // for the id relative to the last id
  844. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  845. 0);
  846. spirv_size += sizeof(uint32_t);
  847. i +=
  848. yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i, 0);
  849. spirv_size += sizeof(uint32_t);
  850. // and since we have already decoded the first two words, k should skip
  851. // two words for the remaining unsigned varint decoding
  852. k += 2;
  853. }
  854. switch (opcode) {
  855. default:
  856. // then we decode some words as signed varints
  857. for (; k < yariv_word_count_to_id_delta(opcode, word_count); k++) {
  858. i += yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  859. 0);
  860. spirv_size += sizeof(uint32_t);
  861. }
  862. // then we decode the remaining words as unsigned varints
  863. for (; k < word_count; k++) {
  864. i += yariv_decode_unsigned_varint(
  865. YARIV_CAST(const uint8_t *, yariv) + i, 0);
  866. spirv_size += sizeof(uint32_t);
  867. }
  868. break;
  869. case YarivOpExtInstImport:
  870. // our literal string was just be memcpy'ed over
  871. spirv_size += sizeof(uint32_t) * (word_count - k);
  872. i += sizeof(uint32_t) * (word_count - k);
  873. break;
  874. case YarivOpVectorShuffleTwoLiterals:
  875. case YarivOpVectorShuffleThreeLiterals:
  876. case YarivOpVectorShuffleFourLiterals:
  877. // we use the signed varint encoding relative to last id for the two
  878. // vectors we are shuffling (but we don't update last id crucially)
  879. i +=
  880. yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i, 0);
  881. spirv_size += sizeof(uint32_t);
  882. i +=
  883. yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i, 0);
  884. spirv_size += sizeof(uint32_t);
  885. // our literals are at most 3 bits each, and we have n of them
  886. if (YarivOpVectorShuffleTwoLiterals == opcode) {
  887. spirv_size += 2 * sizeof(uint32_t);
  888. i += sizeof(uint8_t);
  889. } else if (YarivOpVectorShuffleThreeLiterals == opcode) {
  890. spirv_size += 3 * sizeof(uint32_t);
  891. i += sizeof(uint8_t) * 2;
  892. } else if (YarivOpVectorShuffleFourLiterals == opcode) {
  893. spirv_size += 4 * sizeof(uint32_t);
  894. i += sizeof(uint8_t) * 2;
  895. }
  896. break;
  897. case YarivOpVectorSwizzleTwoLiterals:
  898. case YarivOpVectorSwizzleThreeLiterals:
  899. case YarivOpVectorSwizzleFourLiterals:
  900. // we use the signed varint encoding relative to last id for the one
  901. // vector we are shuffling (but we don't update last id crucially)
  902. i +=
  903. yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i, 0);
  904. spirv_size += sizeof(uint32_t);
  905. spirv_size += sizeof(uint32_t);
  906. // our literals are at most 2 bits each, and we have n of them
  907. i += sizeof(uint8_t);
  908. if (YarivOpVectorSwizzleTwoLiterals == opcode) {
  909. spirv_size += 2 * sizeof(uint32_t);
  910. } else if (YarivOpVectorSwizzleThreeLiterals == opcode) {
  911. spirv_size += 3 * sizeof(uint32_t);
  912. } else if (YarivOpVectorSwizzleFourLiterals == opcode) {
  913. spirv_size += 4 * sizeof(uint32_t);
  914. }
  915. break;
  916. case YarivOpCompositeExtractWithLiteralZero:
  917. case YarivOpCompositeExtractWithLiteralOne:
  918. case YarivOpCompositeExtractWithLiteralTwo:
  919. case YarivOpCompositeExtractWithLiteralThree:
  920. // we use the signed varint encoding relative to last id for the one
  921. // vector we are shuffling (but we don't update last id crucially)
  922. i +=
  923. yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i, 0);
  924. spirv_size += sizeof(uint32_t);
  925. // we skipped a literal that we need to re-encode
  926. spirv_size += sizeof(uint32_t);
  927. break;
  928. case YarivOpDecorateRelaxedPrecision:
  929. // we skipped a decoration that we need to re-encode
  930. spirv_size += sizeof(uint32_t);
  931. break;
  932. case YarivOpMemberDecorateOffset:
  933. // we encoded the member literal as a varint
  934. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  935. 0);
  936. spirv_size += sizeof(uint32_t);
  937. // we skipped a decoration that we need to re-encode
  938. spirv_size += sizeof(uint32_t);
  939. // we encoded the offset as a varint
  940. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  941. 0);
  942. spirv_size += sizeof(uint32_t);
  943. break;
  944. case YarivOpConstantWithOneFloatLiteral:
  945. // we encoded our literal as a 4 byte value
  946. spirv_size += sizeof(uint32_t);
  947. i += sizeof(uint32_t);
  948. break;
  949. case YarivOpDecorateLocation:
  950. // we skipped a decoration that we need to re-encode
  951. spirv_size += sizeof(uint32_t);
  952. // we encoded the offset as a varint
  953. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  954. 0);
  955. spirv_size += sizeof(uint32_t);
  956. break;
  957. }
  958. }
  959. return spirv_size;
  960. }
  961. int yariv_decode(void *out_spirv, size_t out_spirv_size, const void *yariv,
  962. size_t yariv_size) {
  963. size_t i;
  964. int32_t last_id = 1, temp_id, maybe_update_id;
  965. const uint32_t type_offset = 1;
  966. uint32_t *spirv = YARIV_CAST(uint32_t *, out_spirv);
  967. // FIXME: I should really check we don't try and write beyond out_spirv_size
  968. // in out_spirv!
  969. (void)out_spirv_size;
  970. // for the SPIR-V header
  971. // * we re-encode SPIR-V's magic number
  972. *spirv++ = 0x07230203u;
  973. // * we re-encode the version number
  974. *spirv++ =
  975. (YARIV_CAST(uint32_t, YARIV_CAST(const uint8_t *, yariv)[0]) << 16) |
  976. (YARIV_CAST(uint32_t, YARIV_CAST(const uint8_t *, yariv)[1]) << 8);
  977. i = 2;
  978. // * we used varint encoding for the generators magic number
  979. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  980. spirv++);
  981. // * we used varint encoding for the bound
  982. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  983. spirv++);
  984. // * we re-encode the instruction schema (which is zero)
  985. *spirv++ = 0;
  986. while (i < yariv_size) {
  987. uint32_t opcode, word_count, word, k;
  988. maybe_update_id = last_id;
  989. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  990. &opcode);
  991. // shuffle the opcode back to its actual opcode
  992. opcode = yariv_shuffle_opcode(opcode);
  993. if (!yariv_opcode_has_word_count(opcode, &word_count)) {
  994. // if the word count wasn't constant for the opcode, we encoded it as a
  995. // varint
  996. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  997. &word_count);
  998. // when we encoded the word count, we removed the known constant part of
  999. // the word count (derived from the opcode) we need to re-add this as we
  1000. // re-encode word count
  1001. word_count += yariv_word_count_constant_part(opcode);
  1002. }
  1003. switch (opcode) {
  1004. default:
  1005. *spirv++ = (word_count << 16) | opcode;
  1006. break;
  1007. case YarivOpStoreWithMemoryAccess:
  1008. // we added this fake opcode during encoding to allow us to compress
  1009. // some more, so now we have to undo this
  1010. *spirv++ = (word_count << 16) | YarivOpStore;
  1011. break;
  1012. case YarivOpLoadWithMemoryAccess:
  1013. // we added this fake opcode during encoding to allow us to compress
  1014. // some more, so now we have to undo this
  1015. *spirv++ = (word_count << 16) | YarivOpLoad;
  1016. break;
  1017. case YarivOpDecorateRelaxedPrecision:
  1018. case YarivOpDecorateWithNoLiterals:
  1019. case YarivOpDecorateWithOneLiteral:
  1020. case YarivOpDecorateLocation:
  1021. // we added this fake opcode during encoding to allow us to compress
  1022. // some more, so now we have to undo this
  1023. *spirv++ = (word_count << 16) | YarivOpDecorate;
  1024. break;
  1025. case YarivOpMemberDecorateWithNoLiterals:
  1026. case YarivOpMemberDecorateWithOneLiteral:
  1027. case YarivOpMemberDecorateOffset:
  1028. // we added this fake opcode during encoding to allow us to compress
  1029. // some more, so now we have to undo this
  1030. *spirv++ = (word_count << 16) | YarivOpMemberDecorate;
  1031. break;
  1032. case YarivOpVariableWithInitializer:
  1033. // we added this fake opcode during encoding to allow us to compress
  1034. // some more, so now we have to undo this
  1035. *spirv++ = (word_count << 16) | YarivOpVariable;
  1036. break;
  1037. case YarivOpConstantWithManyLiterals:
  1038. case YarivOpConstantWithOneFloatLiteral:
  1039. // we added this fake opcode during encoding to allow us to compress
  1040. // some more, so now we have to undo this
  1041. *spirv++ = (word_count << 16) | YarivOpConstant;
  1042. break;
  1043. case YarivOpAccessChainWithOneIndex:
  1044. case YarivOpAccessChainWithTwoIndices:
  1045. case YarivOpAccessChainWithThreeIndices:
  1046. // we added this fake opcode during encoding to allow us to compress
  1047. // some more, so now we have to undo this
  1048. *spirv++ = (word_count << 16) | YarivOpAccessChain;
  1049. break;
  1050. case YarivOpVectorShuffleTwoLiterals:
  1051. case YarivOpVectorShuffleThreeLiterals:
  1052. case YarivOpVectorShuffleFourLiterals:
  1053. case YarivOpVectorSwizzleTwoLiterals:
  1054. case YarivOpVectorSwizzleThreeLiterals:
  1055. case YarivOpVectorSwizzleFourLiterals:
  1056. // we added this fake opcode during encoding to allow us to compress
  1057. // some more, so now we have to undo this
  1058. *spirv++ = (word_count << 16) | YarivOpVectorShuffle;
  1059. break;
  1060. case YarivOpCompositeExtractWithLiteralZero:
  1061. case YarivOpCompositeExtractWithLiteralOne:
  1062. case YarivOpCompositeExtractWithLiteralTwo:
  1063. case YarivOpCompositeExtractWithLiteralThree:
  1064. // we added this fake opcode during encoding to allow us to compress
  1065. // some more, so now we have to undo this
  1066. *spirv++ = (word_count << 16) | YarivOpCompositeExtract;
  1067. break;
  1068. case YarivOpCompositeConstructOneConstituent:
  1069. case YarivOpCompositeConstructTwoConstituents:
  1070. case YarivOpCompositeConstructThreeConstituents:
  1071. // we added this fake opcode during encoding to allow us to compress
  1072. // some more, so now we have to undo this
  1073. *spirv++ = (word_count << 16) | YarivOpCompositeConstruct;
  1074. break;
  1075. }
  1076. // by default, we use unsigned varint encoding from the word immediately
  1077. // following the opcode/word-count word
  1078. k = 1;
  1079. if (yariv_opcode_has_id(opcode)) {
  1080. // if our opcode has an id, we used a signed varint encoding relative to
  1081. // the last id
  1082. int32_t id;
  1083. i += yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1084. &id);
  1085. maybe_update_id += id;
  1086. *spirv++ = YARIV_CAST(uint32_t, maybe_update_id);
  1087. // and since we have already decoded the first word, k should skip
  1088. // another word for the remaining unsigned varint decoding
  1089. k += 1;
  1090. } else if (yariv_opcode_has_type_and_id(opcode)) {
  1091. // if our opcode has a type and id, we used a signed varint encoding
  1092. // relative for the id to the last id
  1093. uint32_t type;
  1094. int32_t id;
  1095. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1096. &type);
  1097. *spirv++ = YARIV_CAST(uint32_t, type + type_offset);
  1098. i += yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1099. &id);
  1100. maybe_update_id += id;
  1101. *spirv++ = YARIV_CAST(uint32_t, maybe_update_id);
  1102. // and since we have already decoded the first two words, k should skip
  1103. // two words for the remaining unsigned varint decoding
  1104. k += 2;
  1105. }
  1106. switch (opcode) {
  1107. default:
  1108. // then we decode some words as signed varints
  1109. for (; k < yariv_word_count_to_id_delta(opcode, word_count); k++) {
  1110. i += yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1111. &temp_id);
  1112. *spirv++ = YARIV_CAST(uint32_t, temp_id + last_id);
  1113. }
  1114. // followed by all remaining words as varints
  1115. for (; k < word_count; k++) {
  1116. i += yariv_decode_unsigned_varint(
  1117. YARIV_CAST(const uint8_t *, yariv) + i, &word);
  1118. *spirv++ = word;
  1119. }
  1120. break;
  1121. case YarivOpExtInstImport:
  1122. // our literal string was just be memcpy'ed over
  1123. memcpy(spirv, YARIV_CAST(const uint8_t *, yariv) + i,
  1124. sizeof(uint32_t) * (word_count - k));
  1125. spirv += word_count - k;
  1126. i += sizeof(uint32_t) * (word_count - k);
  1127. break;
  1128. case YarivOpVectorShuffleTwoLiterals:
  1129. case YarivOpVectorShuffleThreeLiterals:
  1130. case YarivOpVectorShuffleFourLiterals:
  1131. // we use the signed varint encoding relative to last id for the two
  1132. // vectors we are shuffling (but we don't update last id crucially)
  1133. i += yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1134. &temp_id);
  1135. *spirv++ = YARIV_CAST(uint32_t, last_id + temp_id);
  1136. i += yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1137. &temp_id);
  1138. *spirv++ = YARIV_CAST(uint32_t, last_id + temp_id);
  1139. // our literals were at most 3 bits each, and we have n of them
  1140. if (YarivOpVectorShuffleTwoLiterals == opcode) {
  1141. const uint32_t component0 = YARIV_CAST(const uint8_t *, yariv)[i++];
  1142. *spirv++ = component0 >> 3;
  1143. *spirv++ = component0 & 0x7u;
  1144. } else if (YarivOpVectorShuffleThreeLiterals == opcode) {
  1145. const uint32_t component0 = YARIV_CAST(const uint8_t *, yariv)[i++];
  1146. const uint32_t component1 = YARIV_CAST(const uint8_t *, yariv)[i++];
  1147. *spirv++ = component0 >> 3;
  1148. *spirv++ = component0 & 0x7u;
  1149. *spirv++ = component1;
  1150. } else if (YarivOpVectorShuffleFourLiterals == opcode) {
  1151. const uint32_t component0 = YARIV_CAST(const uint8_t *, yariv)[i++];
  1152. const uint32_t component1 = YARIV_CAST(const uint8_t *, yariv)[i++];
  1153. *spirv++ = component0 >> 3;
  1154. *spirv++ = component0 & 0x7u;
  1155. *spirv++ = component1 >> 3;
  1156. *spirv++ = component1 & 0x7u;
  1157. }
  1158. break;
  1159. case YarivOpVectorSwizzleTwoLiterals:
  1160. case YarivOpVectorSwizzleThreeLiterals:
  1161. case YarivOpVectorSwizzleFourLiterals:
  1162. // we use the signed varint encoding relative to last id for the one
  1163. // vector we are shuffling (but we don't update last id crucially)
  1164. i += yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1165. &temp_id);
  1166. *spirv++ = YARIV_CAST(uint32_t, last_id + temp_id);
  1167. *spirv++ = YARIV_CAST(uint32_t, last_id + temp_id);
  1168. // our literals were at most 2 bits each, and we have n of them
  1169. if (YarivOpVectorSwizzleTwoLiterals == opcode) {
  1170. const uint32_t component = YARIV_CAST(const uint8_t *, yariv)[i++];
  1171. *spirv++ = component >> 2;
  1172. *spirv++ = component & 0x3u;
  1173. } else if (YarivOpVectorSwizzleThreeLiterals == opcode) {
  1174. const uint32_t component = YARIV_CAST(const uint8_t *, yariv)[i++];
  1175. *spirv++ = component >> 4;
  1176. *spirv++ = (component >> 2) & 0x3u;
  1177. *spirv++ = component & 0x3u;
  1178. } else if (YarivOpVectorSwizzleFourLiterals == opcode) {
  1179. const uint32_t component = YARIV_CAST(const uint8_t *, yariv)[i++];
  1180. *spirv++ = component >> 6;
  1181. *spirv++ = (component >> 4) & 0x3u;
  1182. *spirv++ = (component >> 2) & 0x3u;
  1183. *spirv++ = component & 0x3u;
  1184. }
  1185. break;
  1186. case YarivOpCompositeExtractWithLiteralZero:
  1187. case YarivOpCompositeExtractWithLiteralOne:
  1188. case YarivOpCompositeExtractWithLiteralTwo:
  1189. case YarivOpCompositeExtractWithLiteralThree:
  1190. // we use the signed varint encoding relative to last id for the one
  1191. // vector we are shuffling (but we don't update last id crucially)
  1192. i += yariv_decode_signed_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1193. &temp_id);
  1194. *spirv++ = YARIV_CAST(uint32_t, last_id + temp_id);
  1195. // we skipped a literal that we need to re-encode
  1196. if (YarivOpCompositeExtractWithLiteralZero == opcode) {
  1197. *spirv++ = 0;
  1198. } else if (YarivOpCompositeExtractWithLiteralOne == opcode) {
  1199. *spirv++ = 1;
  1200. } else if (YarivOpCompositeExtractWithLiteralTwo == opcode) {
  1201. *spirv++ = 2;
  1202. } else if (YarivOpCompositeExtractWithLiteralThree == opcode) {
  1203. *spirv++ = 3;
  1204. }
  1205. break;
  1206. case YarivOpDecorateRelaxedPrecision:
  1207. // we skipped a decoration that we need to re-encode
  1208. *spirv++ = 0; // output the RelaxedPrecision decoration
  1209. break;
  1210. case YarivOpMemberDecorateOffset:
  1211. // we encoded the member literal as a varint
  1212. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1213. &k);
  1214. *spirv++ = k;
  1215. // we skipped a decoration that we need to re-encode
  1216. *spirv++ = 35; // output the Offset decoration
  1217. // we encoded the offset as a varint
  1218. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1219. &k);
  1220. *spirv++ = k;
  1221. break;
  1222. case YarivOpConstantWithOneFloatLiteral:
  1223. memcpy(spirv++, YARIV_CAST(const uint8_t *, yariv) + i, sizeof(uint32_t));
  1224. i += sizeof(uint32_t);
  1225. break;
  1226. case YarivOpDecorateLocation:
  1227. // we skipped a decoration that we need to re-encode
  1228. *spirv++ = 30; // output the Location decoration
  1229. // we encoded the location as a varint
  1230. i += yariv_decode_unsigned_varint(YARIV_CAST(const uint8_t *, yariv) + i,
  1231. &k);
  1232. *spirv++ = k;
  1233. break;
  1234. }
  1235. // and maybe move the id along
  1236. last_id = maybe_update_id;
  1237. }
  1238. return 0;
  1239. }
  1240. uint32_t yariv_word_count_to_id_delta(uint32_t opcode, uint32_t word_count) {
  1241. (void)word_count;
  1242. switch (opcode) {
  1243. default:
  1244. // by default we want no IDs to be delta encoded
  1245. return 0;
  1246. case YarivOpAccessChain:
  1247. case YarivOpStore:
  1248. case YarivOpLoad:
  1249. case YarivOpFMul:
  1250. case YarivOpFAdd:
  1251. case YarivOpFSub:
  1252. case YarivOpConstantComposite:
  1253. case YarivOpCompositeConstruct:
  1254. case YarivOpCompositeConstructOneConstituent:
  1255. case YarivOpCompositeConstructTwoConstituents:
  1256. case YarivOpCompositeConstructThreeConstituents:
  1257. case YarivOpDot:
  1258. case YarivOpVectorTimesScalar:
  1259. case YarivOpFNegate:
  1260. case YarivOpFDiv:
  1261. case YarivOpFOrdEqual:
  1262. case YarivOpFOrdLessThan:
  1263. case YarivOpFOrdLessThanEqual:
  1264. case YarivOpFOrdGreaterThan:
  1265. case YarivOpFOrdGreaterThanEqual:
  1266. case YarivOpFOrdNotEqual:
  1267. case YarivOpIEqual:
  1268. case YarivOpIAdd:
  1269. case YarivOpFunctionCall:
  1270. case YarivOpSDiv:
  1271. case YarivOpUDiv:
  1272. case YarivOpSLessThan:
  1273. case YarivOpSLessThanEqual:
  1274. case YarivOpPhi:
  1275. case YarivOpLogicalAnd:
  1276. case YarivOpVectorTimesMatrix:
  1277. case YarivOpMatrixTimesVector:
  1278. case YarivOpLogicalNot:
  1279. case YarivOpIMul:
  1280. case YarivOpISub:
  1281. case YarivOpConvertSToF:
  1282. case YarivOpConvertFToS:
  1283. case YarivOpConvertUToF:
  1284. case YarivOpConvertFToU:
  1285. case YarivOpFMod:
  1286. case YarivOpLogicalOr:
  1287. case YarivOpBitcast:
  1288. case YarivOpShiftLeftLogical:
  1289. case YarivOpShiftRightArithmetic:
  1290. case YarivOpShiftRightLogical:
  1291. case YarivOpMatrixTimesScalar:
  1292. case YarivOpMatrixTimesMatrix:
  1293. case YarivOpSelect:
  1294. case YarivOpTranspose:
  1295. return word_count;
  1296. case YarivOpBranchConditional:
  1297. return 4;
  1298. case YarivOpVectorShuffle:
  1299. return 5;
  1300. case YarivOpImageSampleImplicitLod:
  1301. case YarivOpImageSampleExplicitLod:
  1302. return 5;
  1303. case YarivOpImageSampleDrefImplicitLod:
  1304. case YarivOpImageSampleDrefExplicitLod:
  1305. return 6;
  1306. }
  1307. }
  1308. uint32_t yariv_word_count_constant_part(uint32_t opcode) {
  1309. switch (opcode) {
  1310. default:
  1311. // by default we can assume we have a word count of at least one, because
  1312. // the opcode itself must reside in a word count
  1313. return 1;
  1314. case YarivOpSourceContinued:
  1315. case YarivOpSourceExtension:
  1316. case YarivOpGroupDecorate:
  1317. case YarivOpGroupMemberDecorate:
  1318. case YarivOpExtension:
  1319. case YarivOpTypeStruct:
  1320. return 2;
  1321. case YarivOpSource:
  1322. case YarivOpName:
  1323. case YarivOpString:
  1324. case YarivOpDecorate:
  1325. case YarivOpExtInstImport:
  1326. case YarivOpExecutionMode:
  1327. case YarivOpTypeOpaque:
  1328. case YarivOpTypeFunction:
  1329. case YarivOpConstant:
  1330. case YarivOpConstantComposite:
  1331. case YarivOpSpecConstant:
  1332. case YarivOpSpecConstantComposite:
  1333. case YarivOpStore:
  1334. case YarivOpCopyMemory:
  1335. case YarivOpCompositeConstruct:
  1336. case YarivOpPhi:
  1337. case YarivOpSwitch:
  1338. return 3;
  1339. case YarivOpMemberName:
  1340. case YarivOpMemberDecorate:
  1341. case YarivOpEntryPoint:
  1342. case YarivOpSpecConstantOp:
  1343. case YarivOpVariable:
  1344. case YarivOpLoad:
  1345. case YarivOpCopyMemorySized:
  1346. case YarivOpAccessChain:
  1347. case YarivOpInBoundsAccessChain:
  1348. case YarivOpFunctionCall:
  1349. case YarivOpImageWrite:
  1350. case YarivOpCompositeExtract:
  1351. case YarivOpBranchConditional:
  1352. return 4;
  1353. case YarivOpExtInst:
  1354. case YarivOpPtrAccessChain:
  1355. case YarivOpInBoundsPtrAccessChain:
  1356. case YarivOpImageSampleImplicitLod:
  1357. case YarivOpImageSampleProjImplicitLod:
  1358. case YarivOpImageFetch:
  1359. case YarivOpImageRead:
  1360. case YarivOpImageSparseSampleImplicitLod:
  1361. case YarivOpImageSparseSampleProjImplicitLod:
  1362. case YarivOpImageSparseFetch:
  1363. case YarivOpImageSparseRead:
  1364. case YarivOpVectorShuffle:
  1365. case YarivOpCompositeInsert:
  1366. return 5;
  1367. case YarivOpImageSparseSampleProjDrefImplicitLod:
  1368. return 6;
  1369. case YarivOpImageSparseSampleProjExplicitLod:
  1370. return 7;
  1371. }
  1372. }
  1373. uint32_t yariv_opcode_maybe_split(uint32_t opcode, const uint32_t *spirv,
  1374. uint32_t word_count) {
  1375. uint32_t k;
  1376. switch (opcode) {
  1377. default:
  1378. break;
  1379. case YarivOpStore:
  1380. // if the store has a memory access, we will encode it as a different
  1381. // opcode instead to allow us to compress load some more
  1382. if (4 == word_count) {
  1383. opcode = YarivOpStoreWithMemoryAccess;
  1384. }
  1385. break;
  1386. case YarivOpLoad:
  1387. // if the load have a memory access, we will encode it as a different
  1388. // opcode instead to allow us to compress load some more
  1389. if (5 == word_count) {
  1390. opcode = YarivOpLoadWithMemoryAccess;
  1391. }
  1392. break;
  1393. case YarivOpDecorate:
  1394. // if the decoration has 0 or 1 literals, we will encode it as a different
  1395. // opcode instead to allow us to compress decorate some more
  1396. if (3 == word_count) {
  1397. if (0 == spirv[2]) {
  1398. opcode = YarivOpDecorateRelaxedPrecision;
  1399. } else {
  1400. opcode = YarivOpDecorateWithNoLiterals;
  1401. }
  1402. } else if (4 == word_count) {
  1403. if (30 == spirv[2]) {
  1404. opcode = YarivOpDecorateLocation;
  1405. } else {
  1406. opcode = YarivOpDecorateWithOneLiteral;
  1407. }
  1408. }
  1409. break;
  1410. case YarivOpMemberDecorate:
  1411. // if the decoration has 0 or 1 literals, we will encode it as a different
  1412. // opcode instead to allow us to compress decorate some more
  1413. if (4 == word_count) {
  1414. opcode = YarivOpMemberDecorateWithNoLiterals;
  1415. } else if (5 == word_count) {
  1416. if (35 == spirv[3]) {
  1417. opcode = YarivOpMemberDecorateOffset;
  1418. } else {
  1419. opcode = YarivOpMemberDecorateWithOneLiteral;
  1420. }
  1421. }
  1422. break;
  1423. case YarivOpVariable:
  1424. if (5 == word_count) {
  1425. opcode = YarivOpVariableWithInitializer;
  1426. }
  1427. break;
  1428. case YarivOpConstant:
  1429. if (4 < word_count) {
  1430. opcode = YarivOpConstantWithManyLiterals;
  1431. } else if (0xFF800000u & spirv[3]) {
  1432. opcode = YarivOpConstantWithOneFloatLiteral;
  1433. }
  1434. break;
  1435. case YarivOpAccessChain:
  1436. // If the access chain had one, two or three indices, we will encode it as a
  1437. // different opcode instead to allow us to compress it some more
  1438. if (5 == word_count) {
  1439. opcode = YarivOpAccessChainWithOneIndex;
  1440. } else if (6 == word_count) {
  1441. opcode = YarivOpAccessChainWithTwoIndices;
  1442. } else if (7 == word_count) {
  1443. opcode = YarivOpAccessChainWithThreeIndices;
  1444. }
  1445. break;
  1446. case YarivOpVectorShuffle: {
  1447. const int haveBothIdsTheSame = spirv[3] == spirv[4];
  1448. int hasUndef = 0;
  1449. int hasLiteralsLessThan4 = 1;
  1450. int hasLiteralsLessThan8 = 1;
  1451. // If the vector shuffle has no undef literals (0xFFFFFFFu), and it is
  1452. // requesting a result vector of two, three or four width, we will encode it
  1453. // as a different opcode instead to allow us to compress it some more
  1454. for (k = 5; k < word_count; k++) {
  1455. if (0xFFFFFFFFu == spirv[k]) {
  1456. // we are using the undef literal so we can't encode the shuffle more
  1457. // efficiently!
  1458. hasUndef = 1;
  1459. break;
  1460. } else {
  1461. if (3 < spirv[k]) {
  1462. // we are using vector types greater than vec4's so we can't encode
  1463. // the
  1464. // shuffle more efficiently!
  1465. hasLiteralsLessThan4 = 0;
  1466. }
  1467. if (7 < spirv[k]) {
  1468. // we are using vector types greater than vec4's so we can't encode
  1469. // the
  1470. // shuffle more efficiently!
  1471. hasLiteralsLessThan8 = 0;
  1472. }
  1473. }
  1474. }
  1475. // we found an undef, so we can't encode the opcode differently
  1476. if (hasUndef) {
  1477. break;
  1478. }
  1479. if (hasLiteralsLessThan4) {
  1480. if (haveBothIdsTheSame) {
  1481. if (7 == word_count) {
  1482. opcode = YarivOpVectorSwizzleTwoLiterals;
  1483. } else if (8 == word_count) {
  1484. opcode = YarivOpVectorSwizzleThreeLiterals;
  1485. } else if (9 == word_count) {
  1486. opcode = YarivOpVectorSwizzleFourLiterals;
  1487. }
  1488. }
  1489. } else if (hasLiteralsLessThan8) {
  1490. if (7 == word_count) {
  1491. opcode = YarivOpVectorShuffleTwoLiterals;
  1492. } else if (8 == word_count) {
  1493. opcode = YarivOpVectorShuffleThreeLiterals;
  1494. } else if (9 == word_count) {
  1495. opcode = YarivOpVectorShuffleFourLiterals;
  1496. }
  1497. }
  1498. } break;
  1499. case YarivOpCompositeExtract:
  1500. if (5 == word_count) {
  1501. switch (spirv[4]) {
  1502. default:
  1503. break;
  1504. case 0:
  1505. opcode = YarivOpCompositeExtractWithLiteralZero;
  1506. break;
  1507. case 1:
  1508. opcode = YarivOpCompositeExtractWithLiteralOne;
  1509. break;
  1510. case 2:
  1511. opcode = YarivOpCompositeExtractWithLiteralTwo;
  1512. break;
  1513. case 3:
  1514. opcode = YarivOpCompositeExtractWithLiteralThree;
  1515. break;
  1516. }
  1517. }
  1518. break;
  1519. case YarivOpCompositeConstruct:
  1520. if (4 == word_count) {
  1521. opcode = YarivOpCompositeConstructOneConstituent;
  1522. } else if (5 == word_count) {
  1523. opcode = YarivOpCompositeConstructTwoConstituents;
  1524. } else if (6 == word_count) {
  1525. opcode = YarivOpCompositeConstructThreeConstituents;
  1526. }
  1527. break;
  1528. }
  1529. return opcode;
  1530. }
  1531. int yariv_opcode_has_id(uint32_t opcode) {
  1532. switch (opcode) {
  1533. default:
  1534. // by default we assume the opcode does not have an id
  1535. return 0;
  1536. case YarivOpName:
  1537. case YarivOpMemberName:
  1538. // technically member name has a type and no id, but it behaves like
  1539. // an ID for the context we require
  1540. case YarivOpString:
  1541. case YarivOpLine:
  1542. case YarivOpDecorate:
  1543. case YarivOpMemberDecorate:
  1544. // technically member decorate has a type and no id, but it behaves like
  1545. // an ID for the context we require
  1546. case YarivOpDecorationGroup:
  1547. case YarivOpGroupDecorate:
  1548. case YarivOpGroupMemberDecorate:
  1549. case YarivOpExtInstImport:
  1550. case YarivOpExtInst:
  1551. case YarivOpExecutionMode:
  1552. case YarivOpStore:
  1553. case YarivOpCopyMemory:
  1554. case YarivOpCopyMemorySized:
  1555. case YarivOpLoopMerge:
  1556. case YarivOpSelectionMerge:
  1557. case YarivOpLabel:
  1558. case YarivOpBranch:
  1559. case YarivOpBranchConditional:
  1560. case YarivOpSwitch:
  1561. case YarivOpReturnValue:
  1562. case YarivOpLifetimeStart:
  1563. case YarivOpLifetimeStop:
  1564. case YarivOpAtomicFlagClear:
  1565. case YarivOpEmitStreamVertex:
  1566. case YarivOpEndStreamPrimitive:
  1567. case YarivOpControlBarrier:
  1568. case YarivOpMemoryBarrier:
  1569. case YarivOpRetainEvent:
  1570. case YarivOpReleaseEvent:
  1571. case YarivOpSetUserEventStatus:
  1572. case YarivOpCaptureEventProfilingInfo:
  1573. case YarivOpDecorateWithNoLiterals:
  1574. case YarivOpDecorateWithOneLiteral:
  1575. case YarivOpMemberDecorateWithNoLiterals:
  1576. case YarivOpMemberDecorateWithOneLiteral:
  1577. case YarivOpDecorateRelaxedPrecision:
  1578. case YarivOpMemberDecorateOffset:
  1579. case YarivOpDecorateLocation:
  1580. return 1;
  1581. }
  1582. }
  1583. int yariv_opcode_has_type_and_id(uint32_t opcode) {
  1584. switch (opcode) {
  1585. default:
  1586. // by default we assume the opcode does not have a type and id
  1587. return 0;
  1588. case YarivOpUndef:
  1589. case YarivOpExtInst:
  1590. case YarivOpConstantTrue:
  1591. case YarivOpConstantFalse:
  1592. case YarivOpConstant:
  1593. case YarivOpConstantComposite:
  1594. case YarivOpConstantSampler:
  1595. case YarivOpConstantNull:
  1596. case YarivOpSpecConstantTrue:
  1597. case YarivOpSpecConstantFalse:
  1598. case YarivOpSpecConstant:
  1599. case YarivOpSpecConstantComposite:
  1600. case YarivOpSpecConstantOp:
  1601. case YarivOpVariable:
  1602. case YarivOpImageTexelPointer:
  1603. case YarivOpLoad:
  1604. case YarivOpAccessChain:
  1605. case YarivOpInBoundsAccessChain:
  1606. case YarivOpPtrAccessChain:
  1607. case YarivOpArrayLength:
  1608. case YarivOpGenericPtrMemSemantics:
  1609. case YarivOpInBoundsPtrAccessChain:
  1610. case YarivOpFunction:
  1611. case YarivOpFunctionParameter:
  1612. case YarivOpFunctionCall:
  1613. case YarivOpSampledImage:
  1614. case YarivOpImageSampleImplicitLod:
  1615. case YarivOpImageSampleExplicitLod:
  1616. case YarivOpImageSampleDrefImplicitLod:
  1617. case YarivOpImageSampleDrefExplicitLod:
  1618. case YarivOpImageSampleProjImplicitLod:
  1619. case YarivOpImageSampleProjExplicitLod:
  1620. case YarivOpImageSampleProjDrefImplicitLod:
  1621. case YarivOpImageSampleProjDrefExplicitLod:
  1622. case YarivOpImageFetch:
  1623. case YarivOpImageGather:
  1624. case YarivOpImageDrefGather:
  1625. case YarivOpImageRead:
  1626. case YarivOpImageWrite:
  1627. case YarivOpImage:
  1628. case YarivOpImageQueryFormat:
  1629. case YarivOpImageQueryOrder:
  1630. case YarivOpImageQuerySizeLod:
  1631. case YarivOpImageQuerySize:
  1632. case YarivOpImageQueryLod:
  1633. case YarivOpImageQueryLevels:
  1634. case YarivOpImageQuerySamples:
  1635. case YarivOpImageSparseSampleImplicitLod:
  1636. case YarivOpImageSparseSampleExplicitLod:
  1637. case YarivOpImageSparseSampleDrefImplicitLod:
  1638. case YarivOpImageSparseSampleDrefExplicitLod:
  1639. case YarivOpImageSparseSampleProjImplicitLod:
  1640. case YarivOpImageSparseSampleProjExplicitLod:
  1641. case YarivOpImageSparseSampleProjDrefImplicitLod:
  1642. case YarivOpImageSparseSampleProjDrefExplicitLod:
  1643. case YarivOpImageSparseFetch:
  1644. case YarivOpImageSparseGather:
  1645. case YarivOpImageSparseDrefGather:
  1646. case YarivOpImageSparseTexelsResident:
  1647. case YarivOpImageSparseRead:
  1648. case YarivOpConvertFToU:
  1649. case YarivOpConvertFToS:
  1650. case YarivOpConvertSToF:
  1651. case YarivOpConvertUToF:
  1652. case YarivOpUConvert:
  1653. case YarivOpSConvert:
  1654. case YarivOpFConvert:
  1655. case YarivOpQuantizeToF16:
  1656. case YarivOpConvertPtrToU:
  1657. case YarivOpSatConvertSToU:
  1658. case YarivOpSatConvertUToS:
  1659. case YarivOpConvertUToPtr:
  1660. case YarivOpPtrCastToGeneric:
  1661. case YarivOpGenericCastToPtr:
  1662. case YarivOpGenericCastToPtrExplicit:
  1663. case YarivOpBitcast:
  1664. case YarivOpVectorExtractDynamic:
  1665. case YarivOpVectorInsertDynamic:
  1666. case YarivOpVectorShuffle:
  1667. case YarivOpCompositeConstruct:
  1668. case YarivOpCompositeExtract:
  1669. case YarivOpCompositeInsert:
  1670. case YarivOpCopyObject:
  1671. case YarivOpTranspose:
  1672. case YarivOpSNegate:
  1673. case YarivOpFNegate:
  1674. case YarivOpIAdd:
  1675. case YarivOpFAdd:
  1676. case YarivOpISub:
  1677. case YarivOpFSub:
  1678. case YarivOpIMul:
  1679. case YarivOpFMul:
  1680. case YarivOpUDiv:
  1681. case YarivOpSDiv:
  1682. case YarivOpFDiv:
  1683. case YarivOpUMod:
  1684. case YarivOpSRem:
  1685. case YarivOpSMod:
  1686. case YarivOpFRem:
  1687. case YarivOpFMod:
  1688. case YarivOpVectorTimesScalar:
  1689. case YarivOpMatrixTimesScalar:
  1690. case YarivOpVectorTimesMatrix:
  1691. case YarivOpMatrixTimesVector:
  1692. case YarivOpMatrixTimesMatrix:
  1693. case YarivOpOuterProduct:
  1694. case YarivOpDot:
  1695. case YarivOpIAddCarry:
  1696. case YarivOpISubBorrow:
  1697. case YarivOpUMulExtended:
  1698. case YarivOpSMulExtended:
  1699. case YarivOpShiftRightLogical:
  1700. case YarivOpShiftRightArithmetic:
  1701. case YarivOpShiftLeftLogical:
  1702. case YarivOpBitwiseOr:
  1703. case YarivOpBitwiseXor:
  1704. case YarivOpBitwiseAnd:
  1705. case YarivOpNot:
  1706. case YarivOpBitFieldInsert:
  1707. case YarivOpBitFieldSExtract:
  1708. case YarivOpBitFieldUExtract:
  1709. case YarivOpBitReverse:
  1710. case YarivOpBitCount:
  1711. case YarivOpAny:
  1712. case YarivOpAll:
  1713. case YarivOpIsNan:
  1714. case YarivOpIsInf:
  1715. case YarivOpIsFinite:
  1716. case YarivOpIsNormal:
  1717. case YarivOpSignBitSet:
  1718. case YarivOpLessOrGreater:
  1719. case YarivOpOrdered:
  1720. case YarivOpUnordered:
  1721. case YarivOpLogicalEqual:
  1722. case YarivOpLogicalNotEqual:
  1723. case YarivOpLogicalOr:
  1724. case YarivOpLogicalAnd:
  1725. case YarivOpLogicalNot:
  1726. case YarivOpSelect:
  1727. case YarivOpIEqual:
  1728. case YarivOpINotEqual:
  1729. case YarivOpUGreaterThan:
  1730. case YarivOpSGreaterThan:
  1731. case YarivOpUGreaterThanEqual:
  1732. case YarivOpSGreaterThanEqual:
  1733. case YarivOpULessThan:
  1734. case YarivOpSLessThan:
  1735. case YarivOpULessThanEqual:
  1736. case YarivOpSLessThanEqual:
  1737. case YarivOpFOrdEqual:
  1738. case YarivOpFUnordEqual:
  1739. case YarivOpFOrdNotEqual:
  1740. case YarivOpFUnordNotEqual:
  1741. case YarivOpFOrdLessThan:
  1742. case YarivOpFUnordLessThan:
  1743. case YarivOpFOrdGreaterThan:
  1744. case YarivOpFUnordGreaterThan:
  1745. case YarivOpFOrdLessThanEqual:
  1746. case YarivOpFUnordLessThanEqual:
  1747. case YarivOpFOrdGreaterThanEqual:
  1748. case YarivOpFUnordGreaterThanEqual:
  1749. case YarivOpDPdx:
  1750. case YarivOpDPdy:
  1751. case YarivOpFwidth:
  1752. case YarivOpDPdxFine:
  1753. case YarivOpDPdyFine:
  1754. case YarivOpFwidthFine:
  1755. case YarivOpDPdxCoarse:
  1756. case YarivOpDPdyCoarse:
  1757. case YarivOpFwidthCoarse:
  1758. case YarivOpPhi:
  1759. case YarivOpAtomicLoad:
  1760. case YarivOpAtomicStore:
  1761. case YarivOpAtomicExchange:
  1762. case YarivOpAtomicCompareExchange:
  1763. case YarivOpAtomicCompareExchangeWeak:
  1764. case YarivOpAtomicIIncrement:
  1765. case YarivOpAtomicIDecrement:
  1766. case YarivOpAtomicIAdd:
  1767. case YarivOpAtomicISub:
  1768. case YarivOpAtomicSMin:
  1769. case YarivOpAtomicUMin:
  1770. case YarivOpAtomicSMax:
  1771. case YarivOpAtomicUMax:
  1772. case YarivOpAtomicAnd:
  1773. case YarivOpAtomicOr:
  1774. case YarivOpAtomicXor:
  1775. case YarivOpAtomicFlagTestAndSet:
  1776. case YarivOpLoadWithMemoryAccess:
  1777. case YarivOpStoreWithMemoryAccess:
  1778. case YarivOpVariableWithInitializer:
  1779. case YarivOpConstantWithManyLiterals:
  1780. case YarivOpAccessChainWithOneIndex:
  1781. case YarivOpAccessChainWithTwoIndices:
  1782. case YarivOpAccessChainWithThreeIndices:
  1783. case YarivOpVectorShuffleTwoLiterals:
  1784. case YarivOpVectorShuffleThreeLiterals:
  1785. case YarivOpVectorShuffleFourLiterals:
  1786. case YarivOpVectorSwizzleTwoLiterals:
  1787. case YarivOpVectorSwizzleThreeLiterals:
  1788. case YarivOpVectorSwizzleFourLiterals:
  1789. case YarivOpCompositeExtractWithLiteralZero:
  1790. case YarivOpCompositeExtractWithLiteralOne:
  1791. case YarivOpCompositeExtractWithLiteralTwo:
  1792. case YarivOpCompositeExtractWithLiteralThree:
  1793. case YarivOpCompositeConstructOneConstituent:
  1794. case YarivOpCompositeConstructTwoConstituents:
  1795. case YarivOpCompositeConstructThreeConstituents:
  1796. case YarivOpConstantWithOneFloatLiteral:
  1797. return 1;
  1798. }
  1799. }
  1800. int yariv_opcode_has_word_count(uint32_t opcode, uint32_t *word_count) {
  1801. uint32_t count;
  1802. switch (opcode) {
  1803. default:
  1804. // word count was not static for this opcode, so we can't infer it!
  1805. return 0;
  1806. case YarivOpNop:
  1807. case YarivOpNoLine:
  1808. case YarivOpFunctionEnd:
  1809. case YarivOpKill:
  1810. case YarivOpReturn:
  1811. case YarivOpEmitVertex:
  1812. case YarivOpEndPrimitive:
  1813. count = 1;
  1814. break;
  1815. case YarivOpDecorationGroup:
  1816. case YarivOpCapability:
  1817. case YarivOpTypeVoid:
  1818. case YarivOpTypeBool:
  1819. case YarivOpTypeSampler:
  1820. case YarivOpTypeEvent:
  1821. case YarivOpTypeDeviceEvent:
  1822. case YarivOpTypeReserveId:
  1823. case YarivOpTypeQueue:
  1824. case YarivOpLabel:
  1825. case YarivOpBranch:
  1826. case YarivOpReturnValue:
  1827. case YarivOpEmitStreamVertex:
  1828. case YarivOpEndStreamPrimitive:
  1829. case YarivOpRetainEvent:
  1830. case YarivOpReleaseEvent:
  1831. count = 2;
  1832. break;
  1833. case YarivOpUndef:
  1834. case YarivOpMemoryModel:
  1835. case YarivOpTypeFloat:
  1836. case YarivOpTypeSampledImage:
  1837. case YarivOpTypeRuntimeArray:
  1838. case YarivOpTypePipe:
  1839. case YarivOpTypeForwardPointer:
  1840. case YarivOpConstantTrue:
  1841. case YarivOpConstantFalse:
  1842. case YarivOpConstantNull:
  1843. case YarivOpSpecConstantTrue:
  1844. case YarivOpSpecConstantFalse:
  1845. case YarivOpFunctionParameter:
  1846. case YarivOpSelectionMerge:
  1847. case YarivOpLifetimeStart:
  1848. case YarivOpLifetimeStop:
  1849. case YarivOpMemoryBarrier:
  1850. case YarivOpCreateUserEvent:
  1851. case YarivOpSetUserEventStatus:
  1852. case YarivOpGetDefaultQueue:
  1853. count = 3;
  1854. break;
  1855. case YarivOpLine:
  1856. case YarivOpTypeInt:
  1857. case YarivOpTypeVector:
  1858. case YarivOpTypeMatrix:
  1859. case YarivOpTypeArray:
  1860. case YarivOpTypePointer:
  1861. case YarivOpGenericPtrMemSemantics:
  1862. case YarivOpImage:
  1863. case YarivOpImageQueryFormat:
  1864. case YarivOpImageQueryOrder:
  1865. case YarivOpImageQuerySize:
  1866. case YarivOpImageQueryLevels:
  1867. case YarivOpImageQuerySamples:
  1868. case YarivOpImageSparseTexelsResident:
  1869. case YarivOpConvertFToU:
  1870. case YarivOpConvertFToS:
  1871. case YarivOpConvertSToF:
  1872. case YarivOpConvertUToF:
  1873. case YarivOpUConvert:
  1874. case YarivOpSConvert:
  1875. case YarivOpFConvert:
  1876. case YarivOpQuantizeToF16:
  1877. case YarivOpConvertPtrToU:
  1878. case YarivOpSatConvertSToU:
  1879. case YarivOpSatConvertUToS:
  1880. case YarivOpConvertUToPtr:
  1881. case YarivOpPtrCastToGeneric:
  1882. case YarivOpGenericCastToPtr:
  1883. case YarivOpBitcast:
  1884. case YarivOpCopyObject:
  1885. case YarivOpTranspose:
  1886. case YarivOpSNegate:
  1887. case YarivOpFNegate:
  1888. case YarivOpNot:
  1889. case YarivOpBitReverse:
  1890. case YarivOpBitCount:
  1891. case YarivOpAny:
  1892. case YarivOpAll:
  1893. case YarivOpIsNan:
  1894. case YarivOpIsInf:
  1895. case YarivOpIsFinite:
  1896. case YarivOpIsNormal:
  1897. case YarivOpSignBitSet:
  1898. case YarivOpLogicalNot:
  1899. case YarivOpDPdx:
  1900. case YarivOpDPdy:
  1901. case YarivOpFwidth:
  1902. case YarivOpDPdxFine:
  1903. case YarivOpDPdyFine:
  1904. case YarivOpFwidthFine:
  1905. case YarivOpDPdxCoarse:
  1906. case YarivOpDPdyCoarse:
  1907. case YarivOpFwidthCoarse:
  1908. case YarivOpLoopMerge:
  1909. case YarivOpAtomicFlagClear:
  1910. case YarivOpControlBarrier:
  1911. case YarivOpGroupWaitEvents:
  1912. case YarivOpIsValidEvent:
  1913. case YarivOpCaptureEventProfilingInfo:
  1914. case YarivOpIsValidReserveId:
  1915. count = 4;
  1916. break;
  1917. case YarivOpArrayLength:
  1918. case YarivOpFunction:
  1919. case YarivOpSampledImage:
  1920. case YarivOpImageQuerySizeLod:
  1921. case YarivOpImageQueryLod:
  1922. case YarivOpGenericCastToPtrExplicit:
  1923. case YarivOpVectorExtractDynamic:
  1924. case YarivOpIAdd:
  1925. case YarivOpFAdd:
  1926. case YarivOpISub:
  1927. case YarivOpFSub:
  1928. case YarivOpIMul:
  1929. case YarivOpFMul:
  1930. case YarivOpUDiv:
  1931. case YarivOpSDiv:
  1932. case YarivOpFDiv:
  1933. case YarivOpUMod:
  1934. case YarivOpSRem:
  1935. case YarivOpSMod:
  1936. case YarivOpFRem:
  1937. case YarivOpFMod:
  1938. case YarivOpVectorTimesScalar:
  1939. case YarivOpMatrixTimesScalar:
  1940. case YarivOpVectorTimesMatrix:
  1941. case YarivOpMatrixTimesVector:
  1942. case YarivOpMatrixTimesMatrix:
  1943. case YarivOpOuterProduct:
  1944. case YarivOpDot:
  1945. case YarivOpIAddCarry:
  1946. case YarivOpISubBorrow:
  1947. case YarivOpUMulExtended:
  1948. case YarivOpSMulExtended:
  1949. case YarivOpShiftRightLogical:
  1950. case YarivOpShiftRightArithmetic:
  1951. case YarivOpShiftLeftLogical:
  1952. case YarivOpBitwiseOr:
  1953. case YarivOpBitwiseXor:
  1954. case YarivOpBitwiseAnd:
  1955. case YarivOpLessOrGreater:
  1956. case YarivOpOrdered:
  1957. case YarivOpUnordered:
  1958. case YarivOpLogicalEqual:
  1959. case YarivOpLogicalNotEqual:
  1960. case YarivOpLogicalOr:
  1961. case YarivOpLogicalAnd:
  1962. case YarivOpIEqual:
  1963. case YarivOpINotEqual:
  1964. case YarivOpUGreaterThan:
  1965. case YarivOpSGreaterThan:
  1966. case YarivOpUGreaterThanEqual:
  1967. case YarivOpSGreaterThanEqual:
  1968. case YarivOpULessThan:
  1969. case YarivOpSLessThan:
  1970. case YarivOpULessThanEqual:
  1971. case YarivOpSLessThanEqual:
  1972. case YarivOpFOrdEqual:
  1973. case YarivOpFUnordEqual:
  1974. case YarivOpFOrdNotEqual:
  1975. case YarivOpFUnordNotEqual:
  1976. case YarivOpFOrdLessThan:
  1977. case YarivOpFUnordLessThan:
  1978. case YarivOpFOrdGreaterThan:
  1979. case YarivOpFUnordGreaterThan:
  1980. case YarivOpFOrdLessThanEqual:
  1981. case YarivOpFUnordLessThanEqual:
  1982. case YarivOpFOrdGreaterThanEqual:
  1983. case YarivOpFUnordGreaterThanEqual:
  1984. case YarivOpAtomicStore:
  1985. case YarivOpGroupAll:
  1986. case YarivOpGroupAny:
  1987. case YarivOpCommitReadPipe:
  1988. case YarivOpCommitWritePipe:
  1989. count = 5;
  1990. break;
  1991. case YarivOpConstantSampler:
  1992. case YarivOpImageTexelPointer:
  1993. case YarivOpVectorInsertDynamic:
  1994. case YarivOpBitFieldSExtract:
  1995. case YarivOpBitFieldUExtract:
  1996. case YarivOpSelect:
  1997. case YarivOpAtomicLoad:
  1998. case YarivOpAtomicIIncrement:
  1999. case YarivOpAtomicIDecrement:
  2000. case YarivOpAtomicFlagTestAndSet:
  2001. case YarivOpGroupBroadcast:
  2002. case YarivOpGroupIAdd:
  2003. case YarivOpGroupFAdd:
  2004. case YarivOpGroupFMin:
  2005. case YarivOpGroupUMin:
  2006. case YarivOpGroupSMin:
  2007. case YarivOpGroupFMax:
  2008. case YarivOpGroupUMax:
  2009. case YarivOpGroupSMax:
  2010. case YarivOpBuildNDRange:
  2011. case YarivOpGetNumPipePackets:
  2012. case YarivOpGetMaxPipePackets:
  2013. case YarivOpGroupCommitReadPipe:
  2014. case YarivOpGroupCommitWritePipe:
  2015. count = 6;
  2016. break;
  2017. case YarivOpBitFieldInsert:
  2018. case YarivOpAtomicExchange:
  2019. case YarivOpAtomicIAdd:
  2020. case YarivOpAtomicISub:
  2021. case YarivOpAtomicSMin:
  2022. case YarivOpAtomicUMin:
  2023. case YarivOpAtomicSMax:
  2024. case YarivOpAtomicUMax:
  2025. case YarivOpAtomicAnd:
  2026. case YarivOpAtomicOr:
  2027. case YarivOpAtomicXor:
  2028. case YarivOpEnqueueMarker:
  2029. case YarivOpGetKernelWorkGroupSize:
  2030. case YarivOpGetKernelPreferredWorkGroupSizeMultiple:
  2031. case YarivOpReadPipe:
  2032. case YarivOpWritePipe:
  2033. case YarivOpReserveReadPipePackets:
  2034. case YarivOpReserveWritePipePackets:
  2035. count = 7;
  2036. break;
  2037. case YarivOpGetKernelNDrangeSubGroupCount:
  2038. case YarivOpGetKernelNDrangeMaxSubGroupSize:
  2039. case YarivOpGroupReserveReadPipePackets:
  2040. case YarivOpGroupReserveWritePipePackets:
  2041. count = 8;
  2042. break;
  2043. case YarivOpAtomicCompareExchange:
  2044. case YarivOpAtomicCompareExchangeWeak:
  2045. case YarivOpGroupAsyncCopy:
  2046. case YarivOpReservedReadPipe:
  2047. case YarivOpReservedWritePipe:
  2048. count = 9;
  2049. break;
  2050. case YarivOpStore: // beware: in SPIR-V this has a non constant encoding!
  2051. case YarivOpDecorateWithNoLiterals: // this fake opcode has a static size
  2052. case YarivOpDecorateRelaxedPrecision: // this fake opcode has a static size
  2053. count = 3;
  2054. break;
  2055. case YarivOpConstant: // beware: in SPIR-V this has a non constant encoding!
  2056. case YarivOpLoad: // beware: in SPIR-V this has a non constant encoding!
  2057. case YarivOpVariable: // beware: in SPIR-V this has a non constant encoding!
  2058. case YarivOpStoreWithMemoryAccess: // this fake opcode has a static size
  2059. case YarivOpDecorateWithOneLiteral: // this fake opcode has a static size
  2060. case YarivOpMemberDecorateWithNoLiterals: // this fake opcode has a static
  2061. // size
  2062. case YarivOpCompositeConstructOneConstituent: // this fake opcode has a static
  2063. // size
  2064. case YarivOpConstantWithOneFloatLiteral: // this fake opcode has a static size
  2065. case YarivOpDecorateLocation: // this fake opcode has a static size
  2066. count = 4;
  2067. break;
  2068. case YarivOpLoadWithMemoryAccess: // this fake opcode has a static size
  2069. case YarivOpMemberDecorateWithOneLiteral: // this fake opcode has a static
  2070. // size
  2071. case YarivOpVariableWithInitializer: // this fake opcode has a static size
  2072. case YarivOpConstantWithManyLiterals: // this fake opcode has a static size
  2073. case YarivOpAccessChainWithOneIndex: // this fake opcode has a static size
  2074. case YarivOpCompositeExtractWithLiteralZero: // this fake opcode has a static
  2075. // size
  2076. case YarivOpCompositeExtractWithLiteralOne: // this fake opcode has a static
  2077. // size
  2078. case YarivOpCompositeExtractWithLiteralTwo: // this fake opcode has a static
  2079. // size
  2080. case YarivOpCompositeExtractWithLiteralThree: // this fake opcode has a static
  2081. // size
  2082. case YarivOpCompositeConstructTwoConstituents: // this fake opcode has a
  2083. // static size
  2084. case YarivOpMemberDecorateOffset: // this fake opcode has a static size
  2085. count = 5;
  2086. break;
  2087. case YarivOpAccessChainWithTwoIndices: // this fake opcode has a static size
  2088. case YarivOpCompositeConstructThreeConstituents: // this fake opcode has a
  2089. // static size
  2090. count = 6;
  2091. break;
  2092. case YarivOpAccessChainWithThreeIndices: // this fake opcode has a static size
  2093. case YarivOpVectorShuffleTwoLiterals: // this fake opcode has a static size
  2094. case YarivOpVectorSwizzleTwoLiterals: // this fake opcode has a static size
  2095. count = 7;
  2096. break;
  2097. case YarivOpVectorShuffleThreeLiterals: // this fake opcode has a static size
  2098. case YarivOpVectorSwizzleThreeLiterals: // this fake opcode has a static size
  2099. count = 8;
  2100. break;
  2101. case YarivOpVectorShuffleFourLiterals: // this fake opcode has a static size
  2102. case YarivOpVectorSwizzleFourLiterals: // this fake opcode has a static size
  2103. count = 9;
  2104. break;
  2105. }
  2106. if (word_count) {
  2107. *word_count = count;
  2108. }
  2109. return 1;
  2110. }
  2111. uint32_t yariv_shuffle_opcode(uint32_t opcode) {
  2112. switch (opcode) {
  2113. default:
  2114. return opcode;
  2115. #define YARIV_SWAP(x, y) \
  2116. case (x): \
  2117. return (y); \
  2118. case (y): \
  2119. return (x)
  2120. YARIV_SWAP(YarivOpLabel, YarivOpNop);
  2121. YARIV_SWAP(YarivOpFSub, YarivOpUndef);
  2122. YARIV_SWAP(YarivOpFMul, YarivOpSourceContinued);
  2123. YARIV_SWAP(YarivOpFAdd, YarivOpSource);
  2124. YARIV_SWAP(YarivOpBranch, YarivOpSourceExtension);
  2125. YARIV_SWAP(YarivOpDecorateWithNoLiterals, YarivOpLine);
  2126. YARIV_SWAP(YarivOpDecorateWithOneLiteral, YarivOpExtension);
  2127. YARIV_SWAP(YarivOpMemberDecorateWithNoLiterals, YarivOpExtInstImport);
  2128. YARIV_SWAP(YarivOpMemberDecorateWithOneLiteral, YarivOpMemoryModel);
  2129. YARIV_SWAP(YarivOpAccessChainWithOneIndex, YarivOpExecutionMode);
  2130. YARIV_SWAP(YarivOpAccessChainWithTwoIndices, YarivOpCapability);
  2131. YARIV_SWAP(YarivOpAccessChainWithThreeIndices, YarivOpTypeVoid);
  2132. YARIV_SWAP(YarivOpVectorShuffleTwoLiterals, YarivOp9);
  2133. YARIV_SWAP(YarivOpVectorShuffleThreeLiterals, YarivOp13);
  2134. YARIV_SWAP(YarivOpVectorShuffleFourLiterals, YarivOp18);
  2135. YARIV_SWAP(YarivOpDot, YarivOp40);
  2136. YARIV_SWAP(YarivOpVectorTimesScalar, YarivOp47);
  2137. YARIV_SWAP(YarivOpFDiv, YarivOp53);
  2138. YARIV_SWAP(YarivOpVectorSwizzleTwoLiterals, YarivOp58);
  2139. YARIV_SWAP(YarivOpVectorSwizzleThreeLiterals, YarivOp76);
  2140. YARIV_SWAP(YarivOpVectorSwizzleFourLiterals, YarivOp85);
  2141. YARIV_SWAP(YarivOpBranchConditional, YarivOpTypeEvent);
  2142. YARIV_SWAP(YarivOpSelectionMerge, YarivOpTypeDeviceEvent);
  2143. YARIV_SWAP(YarivOpCompositeExtractWithLiteralZero,
  2144. YarivOpGenericPtrMemSemantics);
  2145. YARIV_SWAP(YarivOpCompositeExtractWithLiteralOne, YarivOpPtrCastToGeneric);
  2146. YARIV_SWAP(YarivOpCompositeExtractWithLiteralTwo, YarivOpGenericCastToPtr);
  2147. YARIV_SWAP(YarivOpCompositeExtractWithLiteralThree,
  2148. YarivOpGenericCastToPtrExplicit);
  2149. YARIV_SWAP(YarivOpCompositeConstructOneConstituent, YarivOpTypeReserveId);
  2150. YARIV_SWAP(YarivOpCompositeConstructTwoConstituents, YarivOpTypeQueue);
  2151. YARIV_SWAP(YarivOpCompositeConstructThreeConstituents, YarivOpTypePipe);
  2152. YARIV_SWAP(YarivOpDecorateRelaxedPrecision, YarivOpImageTexelPointer);
  2153. YARIV_SWAP(YarivOpMemberDecorateOffset, YarivOp108);
  2154. YARIV_SWAP(YarivOpConstantWithOneFloatLiteral, YarivOpTypeForwardPointer);
  2155. YARIV_SWAP(YarivOpDecorateLocation, YarivOp125);
  2156. YARIV_SWAP(YarivOpReturnValue, YarivOpTypeRuntimeArray);
  2157. YARIV_SWAP(YarivOpFOrdEqual, YarivOpCompositeInsert);
  2158. YARIV_SWAP(YarivOpFOrdLessThanEqual, YarivOpVectorExtractDynamic);
  2159. YARIV_SWAP(YarivOpFOrdLessThan, YarivOpConstantFalse);
  2160. YARIV_SWAP(YarivOpIEqual, YarivOpTranspose);
  2161. YARIV_SWAP(YarivOpReturn, YarivOpSNegate);
  2162. YARIV_SWAP(YarivOpIAdd, YarivOpCopyObject);
  2163. #undef YARIV_SWAP
  2164. }
  2165. }
  2166. size_t yariv_encode_signed_varint(int32_t i, uint8_t *out) {
  2167. // we use zig-zag encoding of the original integer
  2168. return yariv_encode_unsigned_varint(
  2169. YARIV_CAST(uint32_t, (i << 1) ^ (i >> 31)), out);
  2170. }
  2171. size_t yariv_decode_signed_varint(const uint8_t *in, int32_t *out) {
  2172. uint32_t u;
  2173. const size_t r = yariv_decode_unsigned_varint(in, &u);
  2174. if (out) {
  2175. // we use zig-zag decoding of the unsigned integer
  2176. *out = YARIV_CAST(int32_t, u >> 1) ^ -(YARIV_CAST(int32_t, u) & 1);
  2177. }
  2178. return r;
  2179. }
  2180. size_t yariv_encode_unsigned_varint(uint32_t i, uint8_t *out) {
  2181. size_t r = 0;
  2182. while (i > 127) {
  2183. if (out) {
  2184. out[r] = (YARIV_CAST(uint8_t, i) & 0x7Fu) | 0x80u;
  2185. }
  2186. i >>= 7;
  2187. r++;
  2188. }
  2189. if (out) {
  2190. out[r] = YARIV_CAST(uint8_t, i);
  2191. }
  2192. return r + 1;
  2193. }
  2194. size_t yariv_decode_unsigned_varint(const uint8_t *in, uint32_t *out) {
  2195. uint32_t r = 0;
  2196. size_t i;
  2197. // the maximum length of a uint32_t varint is 5 bytes
  2198. for (i = 0; i < 5; i++) {
  2199. // bring in the 7 significant bits of this part of the varint
  2200. r |= (0x7Fu & in[i]) << 7 * i;
  2201. // if we don't have the 'there is another byte in our varint' bit set
  2202. if (0u == (0x80u & in[i])) {
  2203. if (out) {
  2204. *out = r;
  2205. }
  2206. return i + 1;
  2207. }
  2208. }
  2209. return 0;
  2210. }
  2211. #undef YARIV_CAST
  2212. #ifdef __cplusplus
  2213. }
  2214. #endif
  2215. #endif // SHEREDOM_YARIV_H_INCLUDED