shader_spirv.cpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. /*
  2. * Copyright 2011-2020 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  4. */
  5. #include "bgfx_p.h"
  6. #include "shader_spirv.h"
  7. namespace bgfx
  8. {
  9. #define SPV_OPERAND_1(_a0) SpvOperand::_a0
  10. #define SPV_OPERAND_2(_a0, _a1) SPV_OPERAND_1(_a0), SPV_OPERAND_1(_a1)
  11. #define SPV_OPERAND_3(_a0, _a1, _a2) SPV_OPERAND_1(_a0), SPV_OPERAND_2(_a1, _a2)
  12. #define SPV_OPERAND_4(_a0, _a1, _a2, _a3) SPV_OPERAND_1(_a0), SPV_OPERAND_3(_a1, _a2, _a3)
  13. #define SPV_OPERAND_5(_a0, _a1, _a2, _a3, _a4) SPV_OPERAND_1(_a0), SPV_OPERAND_4(_a1, _a2, _a3, _a4)
  14. #define SPV_OPERAND_6(_a0, _a1, _a2, _a3, _a4, _a5) SPV_OPERAND_1(_a0), SPV_OPERAND_5(_a1, _a2, _a3, _a4, _a5)
  15. #define SPV_OPERAND_7(_a0, _a1, _a2, _a3, _a4, _a5, _a6) SPV_OPERAND_1(_a0), SPV_OPERAND_6(_a1, _a2, _a3, _a4, _a5, _a6)
  16. #define SPV_OPERAND_8(_a0, _a1, _a2, _a3, _a4, _a5, _a6, _a7) SPV_OPERAND_1(_a0), SPV_OPERAND_7(_a1, _a2, _a3, _a4, _a5, _a6, _a7)
  17. #define SPV_OPERAND_9(_a0, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) SPV_OPERAND_1(_a0), SPV_OPERAND_8(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8)
  18. #if BX_COMPILER_MSVC
  19. // Workaround MSVS bug...
  20. # define SPV_OPERAND(...) { BX_MACRO_DISPATCHER(SPV_OPERAND_, __VA_ARGS__) BX_VA_ARGS_PASS(__VA_ARGS__) }
  21. #else
  22. # define SPV_OPERAND(...) { BX_MACRO_DISPATCHER(SPV_OPERAND_, __VA_ARGS__)(__VA_ARGS__) }
  23. #endif // BX_COMPILER_MSVC
  24. #define _ Count
  25. bool isDebug(SpvOpcode::Enum _opcode)
  26. {
  27. return (SpvOpcode::SourceContinued <= _opcode && SpvOpcode::Line >= _opcode)
  28. || SpvOpcode::NoLine == _opcode
  29. ;
  30. }
  31. struct SpvOpcodeInfo
  32. {
  33. bool hasType;
  34. bool hasResult;
  35. SpvOperand::Enum operands[8];
  36. };
  37. static const SpvOpcodeInfo s_spvOpcodeInfo[] =
  38. {
  39. { false, false, /* Nop, // 0 */ SPV_OPERAND(_) },
  40. { true, true, /* Undef, // 1 */ SPV_OPERAND(_) },
  41. { false, false, /* SourceContinued, // 2 */ SPV_OPERAND(_) },
  42. { false, false, /* Source, // 3 */ SPV_OPERAND(SourceLanguage, LiteralNumber, Id, LiteralString) },
  43. { false, false, /* SourceExtension, // 4 */ SPV_OPERAND(LiteralString) },
  44. { false, true, /* Name, // 5 */ SPV_OPERAND(LiteralString) },
  45. { false, true, /* MemberName, // 6 */ SPV_OPERAND(LiteralNumber, LiteralString) },
  46. { false, false, /* String, // 7 */ SPV_OPERAND(_) },
  47. { false, false, /* Line, // 8 */ SPV_OPERAND(_) },
  48. { false, false, /* ------------------------------- Invalid9 // 9 */ SPV_OPERAND(_) },
  49. { false, false, /* Extension, // 10 */ SPV_OPERAND(LiteralString) },
  50. { false, true, /* ExtInstImport, // 11 */ SPV_OPERAND(LiteralString) },
  51. { true, true, /* ExtInst, // 12 */ SPV_OPERAND(LiteralNumber) },
  52. { false, false, /* ------------------------------ Invalid13 // 13 */ SPV_OPERAND(_) },
  53. { false, false, /* MemoryModel, // 14 */ SPV_OPERAND(AddressingModel, MemoryModel) },
  54. { false, false, /* EntryPoint, // 15 */ SPV_OPERAND(ExecutionModel, Id, LiteralString) },
  55. { true, true, /* ExecutionMode, // 16 */ SPV_OPERAND(_) },
  56. { false, false, /* Capability, // 17 */ SPV_OPERAND(Capability ) },
  57. { false, false, /* ------------------------------ Invalid18 // 18 */ SPV_OPERAND(_) },
  58. { false, true, /* TypeVoid, // 19 */ SPV_OPERAND(LiteralNumber) },
  59. { false, true, /* TypeBool, // 20 */ SPV_OPERAND(LiteralNumber) },
  60. { false, true, /* TypeInt, // 21 */ SPV_OPERAND(LiteralNumber) },
  61. { false, true, /* TypeFloat, // 22 */ SPV_OPERAND(LiteralNumber) },
  62. { false, true, /* TypeVector, // 23 */ SPV_OPERAND(ComponentType, LiteralNumber) },
  63. { false, true, /* TypeMatrix, // 24 */ SPV_OPERAND(LiteralNumber) },
  64. { false, true, /* TypeImage, // 25 */ SPV_OPERAND(SampledType, Dim, LiteralNumber, LiteralNumber, LiteralNumber, LiteralNumber, ImageFormat, AccessQualifier) },
  65. { false, true, /* TypeSampler, // 26 */ SPV_OPERAND(LiteralNumber) },
  66. { false, true, /* TypeSampledImage, // 27 */ SPV_OPERAND(LiteralNumber) },
  67. { false, true, /* TypeArray, // 28 */ SPV_OPERAND(ElementType, LiteralNumber) },
  68. { false, true, /* TypeRuntimeArray, // 29 */ SPV_OPERAND(ElementType) },
  69. { false, true, /* TypeStruct, // 30 */ SPV_OPERAND(IdRep) },
  70. { false, true, /* TypeOpaque, // 31 */ SPV_OPERAND(LiteralString) },
  71. { false, true, /* TypePointer, // 32 */ SPV_OPERAND(StorageClass, Id) },
  72. { false, true, /* TypeFunction, // 33 */ SPV_OPERAND(Id, Id, Id, Id, Id) },
  73. { false, true, /* TypeEvent, // 34 */ SPV_OPERAND(_) },
  74. { false, true, /* TypeDeviceEvent, // 35 */ SPV_OPERAND(_) },
  75. { false, true, /* TypeReserveId, // 36 */ SPV_OPERAND(_) },
  76. { false, true, /* TypeQueue, // 37 */ SPV_OPERAND(_) },
  77. { false, true, /* TypePipe, // 38 */ SPV_OPERAND(_) },
  78. { false, true, /* TypeForwardPointer, // 39 */ SPV_OPERAND(_) },
  79. { false, false, /* ------------------------------ Invalid40 // 40 */ SPV_OPERAND(_) },
  80. { true, true, /* ConstantTrue, // 41 */ SPV_OPERAND(_) },
  81. { true, true, /* ConstantFalse, // 42 */ SPV_OPERAND(_) },
  82. { true, true, /* Constant, // 43 */ SPV_OPERAND(LiteralRep) },
  83. { true, true, /* ConstantComposite, // 44 */ SPV_OPERAND(LiteralRep) },
  84. { true, true, /* ConstantSampler, // 45 */ SPV_OPERAND(SamplerAddressingMode, LiteralNumber, SamplerFilterMode) },
  85. { true, true, /* ConstantNull, // 46 */ SPV_OPERAND(_) },
  86. { false, false, /* ------------------------------ Invalid47 // 47 */ SPV_OPERAND(_) },
  87. { true, true, /* SpecConstantTrue, // 48 */ SPV_OPERAND(_) },
  88. { true, true, /* SpecConstantFalse, // 49 */ SPV_OPERAND(_) },
  89. { true, true, /* SpecConstant, // 50 */ SPV_OPERAND(_) },
  90. { true, true, /* SpecConstantComposite, // 51 */ SPV_OPERAND(_) },
  91. { true, true, /* SpecConstantOp, // 52 */ SPV_OPERAND(_) },
  92. { false, false, /* ------------------------------ Invalid53 // 53 */ SPV_OPERAND(_) },
  93. { true, true, /* Function, // 54 */ SPV_OPERAND(FunctionControl, Id) },
  94. { true, true, /* FunctionParameter, // 55 */ SPV_OPERAND(_) },
  95. { false, false, /* FunctionEnd, // 56 */ SPV_OPERAND(_) },
  96. { true, true, /* FunctionCall, // 57 */ SPV_OPERAND(Function, IdRep) },
  97. { false, false, /* ------------------------------ Invalid58 // 58 */ SPV_OPERAND(_) },
  98. { true, true, /* Variable, // 59 */ SPV_OPERAND(StorageClass, Id) },
  99. { true, true, /* ImageTexelPointer, // 60 */ SPV_OPERAND(_) },
  100. { true, true, /* Load, // 61 */ SPV_OPERAND(Pointer, MemoryAccess) },
  101. { false, false, /* Store, // 62 */ SPV_OPERAND(Pointer, Object, MemoryAccess) },
  102. { false, false, /* CopyMemory, // 63 */ SPV_OPERAND(_) },
  103. { false, false, /* CopyMemorySized, // 64 */ SPV_OPERAND(_) },
  104. { true, true, /* AccessChain, // 65 */ SPV_OPERAND(Base, IdRep) },
  105. { true, true, /* InBoundsAccessChain, // 66 */ SPV_OPERAND(Base, IdRep) },
  106. { true, true, /* PtrAccessChain, // 67 */ SPV_OPERAND(_) },
  107. { true, true, /* ArrayLength, // 68 */ SPV_OPERAND(_) },
  108. { true, true, /* GenericPtrMemSemantics, // 69 */ SPV_OPERAND(_) },
  109. { true, true, /* InBoundsPtrAccessChain, // 70 */ SPV_OPERAND(_) },
  110. { false, false, /* Decorate, // 71 */ SPV_OPERAND(Id, Decoration, LiteralRep) },
  111. { false, false, /* MemberDecorate, // 72 */ SPV_OPERAND(StructureType, LiteralNumber, Decoration, LiteralRep) },
  112. { false, false, /* DecorationGroup, // 73 */ SPV_OPERAND(_) },
  113. { false, false, /* GroupDecorate, // 74 */ SPV_OPERAND(_) },
  114. { false, false, /* GroupMemberDecorate, // 75 */ SPV_OPERAND(_) },
  115. { false, false, /* ------------------------------ Invalid76 // 76 */ SPV_OPERAND(_) },
  116. { true, true, /* VectorExtractDynamic, // 77 */ SPV_OPERAND(_) },
  117. { true, true, /* VectorInsertDynamic, // 78 */ SPV_OPERAND(_) },
  118. { true, true, /* VectorShuffle, // 79 */ SPV_OPERAND(Id, Id, LiteralRep) },
  119. { true, true, /* CompositeConstruct, // 80 */ SPV_OPERAND(IdRep) },
  120. { true, true, /* CompositeExtract, // 81 */ SPV_OPERAND(Composite, LiteralRep) },
  121. { true, true, /* CompositeInsert, // 82 */ SPV_OPERAND(Id, Composite, LiteralRep) },
  122. { true, true, /* CopyObject, // 83 */ SPV_OPERAND(Id) },
  123. { true, true, /* Transpose, // 84 */ SPV_OPERAND(Matrix) },
  124. { false, false, /* ------------------------------ Invalid85 // 85 */ SPV_OPERAND(_) },
  125. { true, true, /* SampledImage, // 86 */ SPV_OPERAND(_) },
  126. { true, true, /* ImageSampleImplicitLod, // 87 */ SPV_OPERAND(SampledImage, Coordinate, ImageOperands, IdRep) },
  127. { true, true, /* ImageSampleExplicitLod, // 88 */ SPV_OPERAND(SampledImage, Coordinate, ImageOperands, Id, IdRep) },
  128. { true, true, /* ImageSampleDrefImplicitLod, // 89 */ SPV_OPERAND(_) },
  129. { true, true, /* ImageSampleDrefExplicitLod, // 90 */ SPV_OPERAND(_) },
  130. { true, true, /* ImageSampleProjImplicitLod, // 91 */ SPV_OPERAND(_) },
  131. { true, true, /* ImageSampleProjExplicitLod, // 92 */ SPV_OPERAND(_) },
  132. { true, true, /* ImageSampleProjDrefImplicitLod, // 93 */ SPV_OPERAND(_) },
  133. { true, true, /* ImageSampleProjDrefExplicitLod, // 94 */ SPV_OPERAND(_) },
  134. { true, true, /* ImageFetch, // 95 */ SPV_OPERAND(_) },
  135. { true, true, /* ImageGather, // 96 */ SPV_OPERAND(SampledImage, Coordinate, Component, ImageOperands, IdRep) },
  136. { true, true, /* ImageDrefGather, // 97 */ SPV_OPERAND(SampledImage, Coordinate, Dref, ImageOperands, IdRep) },
  137. { true, true, /* ImageRead, // 98 */ SPV_OPERAND(_) },
  138. { false, false, /* ImageWrite, // 99 */ SPV_OPERAND(_) },
  139. { true, true, /* Image, // 100 */ SPV_OPERAND(_) },
  140. { true, true, /* ImageQueryFormat, // 101 */ SPV_OPERAND(_) },
  141. { true, true, /* ImageQueryOrder, // 102 */ SPV_OPERAND(_) },
  142. { true, true, /* ImageQuerySizeLod, // 103 */ SPV_OPERAND(_) },
  143. { true, true, /* ImageQuerySize, // 104 */ SPV_OPERAND(_) },
  144. { true, true, /* ImageQueryLod, // 105 */ SPV_OPERAND(_) },
  145. { true, true, /* ImageQueryLevels, // 106 */ SPV_OPERAND(_) },
  146. { true, true, /* ImageQuerySamples, // 107 */ SPV_OPERAND(_) },
  147. { false, false, /* ----------------------------- Invalid108 // 108 */ SPV_OPERAND(_) },
  148. { true, true, /* ConvertFToU, // 109 */ SPV_OPERAND(_) },
  149. { true, true, /* ConvertFToS, // 110 */ SPV_OPERAND(_) },
  150. { true, true, /* ConvertSToF, // 111 */ SPV_OPERAND(_) },
  151. { true, true, /* ConvertUToF, // 112 */ SPV_OPERAND(_) },
  152. { true, true, /* UConvert, // 113 */ SPV_OPERAND(Id) },
  153. { true, true, /* SConvert, // 114 */ SPV_OPERAND(Id) },
  154. { true, true, /* FConvert, // 115 */ SPV_OPERAND(Id) },
  155. { true, true, /* QuantizeToF16, // 116 */ SPV_OPERAND(_) },
  156. { true, true, /* ConvertPtrToU, // 117 */ SPV_OPERAND(_) },
  157. { true, true, /* SatConvertSToU, // 118 */ SPV_OPERAND(_) },
  158. { true, true, /* SatConvertUToS, // 119 */ SPV_OPERAND(_) },
  159. { true, true, /* ConvertUToPtr, // 120 */ SPV_OPERAND(_) },
  160. { true, true, /* PtrCastToGeneric, // 121 */ SPV_OPERAND(_) },
  161. { true, true, /* GenericCastToPtr, // 122 */ SPV_OPERAND(_) },
  162. { true, true, /* GenericCastToPtrExplicit, // 123 */ SPV_OPERAND(_) },
  163. { true, true, /* Bitcast, // 124 */ SPV_OPERAND(_) },
  164. { false, false, /* ----------------------------- Invalid125 // 125 */ SPV_OPERAND(_) },
  165. { true, true, /* SNegate, // 126 */ SPV_OPERAND(Id) },
  166. { true, true, /* FNegate, // 127 */ SPV_OPERAND(Id) },
  167. { true, true, /* IAdd, // 128 */ SPV_OPERAND(Id, Id) },
  168. { true, true, /* FAdd, // 129 */ SPV_OPERAND(Id, Id) },
  169. { true, true, /* ISub, // 130 */ SPV_OPERAND(Id, Id) },
  170. { true, true, /* FSub, // 131 */ SPV_OPERAND(Id, Id) },
  171. { true, true, /* IMul, // 132 */ SPV_OPERAND(Id, Id) },
  172. { true, true, /* FMul, // 133 */ SPV_OPERAND(Id, Id) },
  173. { true, true, /* UDiv, // 134 */ SPV_OPERAND(Id, Id) },
  174. { true, true, /* SDiv, // 135 */ SPV_OPERAND(Id, Id) },
  175. { true, true, /* FDiv, // 136 */ SPV_OPERAND(Id, Id) },
  176. { true, true, /* UMod, // 137 */ SPV_OPERAND(Id, Id) },
  177. { true, true, /* SRem, // 138 */ SPV_OPERAND(Id, Id) },
  178. { true, true, /* SMod, // 139 */ SPV_OPERAND(Id, Id) },
  179. { true, true, /* FRem, // 140 */ SPV_OPERAND(Id, Id) },
  180. { true, true, /* FMod, // 141 */ SPV_OPERAND(Id, Id) },
  181. { true, true, /* VectorTimesScalar, // 142 */ SPV_OPERAND(Vector, Scalar) },
  182. { true, true, /* MatrixTimesScalar, // 143 */ SPV_OPERAND(Matrix, Scalar) },
  183. { true, true, /* VectorTimesMatrix, // 144 */ SPV_OPERAND(Vector, Matrix) },
  184. { true, true, /* MatrixTimesVector, // 145 */ SPV_OPERAND(Matrix, Vector) },
  185. { true, true, /* MatrixTimesMatrix, // 146 */ SPV_OPERAND(Matrix, Matrix) },
  186. { true, true, /* OuterProduct, // 147 */ SPV_OPERAND(Vector, Vector) },
  187. { true, true, /* Dot, // 148 */ SPV_OPERAND(Vector, Vector) },
  188. { true, true, /* IAddCarry, // 149 */ SPV_OPERAND(Id, Id) },
  189. { true, true, /* ISubBorrow, // 150 */ SPV_OPERAND(Id, Id) },
  190. { true, true, /* UMulExtended, // 151 */ SPV_OPERAND(Id, Id) },
  191. { true, true, /* SMulExtended, // 152 */ SPV_OPERAND(Id, Id) },
  192. { false, false, /* ----------------------------- Invalid153 // 153 */ SPV_OPERAND(_) },
  193. { true, true, /* Any, // 154 */ SPV_OPERAND(Vector) },
  194. { true, true, /* All, // 155 */ SPV_OPERAND(Vector) },
  195. { true, true, /* IsNan, // 156 */ SPV_OPERAND(Id) },
  196. { true, true, /* IsInf, // 157 */ SPV_OPERAND(Id) },
  197. { true, true, /* IsFinite, // 158 */ SPV_OPERAND(Id) },
  198. { true, true, /* IsNormal, // 159 */ SPV_OPERAND(Id) },
  199. { true, true, /* SignBitSet, // 160 */ SPV_OPERAND(Id) },
  200. { true, true, /* LessOrGreater, // 161 */ SPV_OPERAND(Id, Id) },
  201. { true, true, /* Ordered, // 162 */ SPV_OPERAND(Id, Id) },
  202. { true, true, /* Unordered, // 163 */ SPV_OPERAND(_) },
  203. { true, true, /* LogicalEqual, // 164 */ SPV_OPERAND(_) },
  204. { true, true, /* LogicalNotEqual, // 165 */ SPV_OPERAND(_) },
  205. { true, true, /* LogicalOr, // 166 */ SPV_OPERAND(_) },
  206. { true, true, /* LogicalAnd, // 167 */ SPV_OPERAND(_) },
  207. { true, true, /* LogicalNot, // 168 */ SPV_OPERAND(_) },
  208. { true, true, /* Select, // 169 */ SPV_OPERAND(Condition, Id, Id) },
  209. { true, true, /* IEqual, // 170 */ SPV_OPERAND(_) },
  210. { true, true, /* INotEqual, // 171 */ SPV_OPERAND(_) },
  211. { true, true, /* UGreaterThan, // 172 */ SPV_OPERAND(_) },
  212. { true, true, /* SGreaterThan, // 173 */ SPV_OPERAND(_) },
  213. { true, true, /* UGreaterThanEqual, // 174 */ SPV_OPERAND(_) },
  214. { true, true, /* SGreaterThanEqual, // 175 */ SPV_OPERAND(_) },
  215. { true, true, /* ULessThan, // 176 */ SPV_OPERAND(_) },
  216. { true, true, /* SLessThan, // 177 */ SPV_OPERAND(_) },
  217. { true, true, /* ULessThanEqual, // 178 */ SPV_OPERAND(_) },
  218. { true, true, /* SLessThanEqual, // 179 */ SPV_OPERAND(_) },
  219. { true, true, /* FOrdEqual, // 180 */ SPV_OPERAND(_) },
  220. { true, true, /* FUnordEqual, // 181 */ SPV_OPERAND(_) },
  221. { true, true, /* FOrdNotEqual, // 182 */ SPV_OPERAND(_) },
  222. { true, true, /* FUnordNotEqual, // 183 */ SPV_OPERAND(_) },
  223. { true, true, /* FOrdLessThan, // 184 */ SPV_OPERAND(_) },
  224. { true, true, /* FUnordLessThan, // 185 */ SPV_OPERAND(_) },
  225. { true, true, /* FOrdGreaterThan, // 186 */ SPV_OPERAND(_) },
  226. { true, true, /* FUnordGreaterThan, // 187 */ SPV_OPERAND(_) },
  227. { true, true, /* FOrdLessThanEqual, // 188 */ SPV_OPERAND(_) },
  228. { true, true, /* FUnordLessThanEqual, // 189 */ SPV_OPERAND(_) },
  229. { true, true, /* FOrdGreaterThanEqual, // 190 */ SPV_OPERAND(_) },
  230. { true, true, /* FUnordGreaterThanEqual, // 191 */ SPV_OPERAND(_) },
  231. { false, false, /* ----------------------------- Invalid192 // 192 */ SPV_OPERAND(_) },
  232. { false, false, /* ----------------------------- Invalid193 // 193 */ SPV_OPERAND(_) },
  233. { true, true, /* ShiftRightLogical, // 194 */ SPV_OPERAND(_) },
  234. { true, true, /* ShiftRightArithmetic, // 195 */ SPV_OPERAND(_) },
  235. { true, true, /* ShiftLeftLogical, // 196 */ SPV_OPERAND(_) },
  236. { true, true, /* BitwiseOr, // 197 */ SPV_OPERAND(_) },
  237. { true, true, /* BitwiseXor, // 198 */ SPV_OPERAND(_) },
  238. { true, true, /* BitwiseAnd, // 199 */ SPV_OPERAND(_) },
  239. { true, true, /* Not, // 200 */ SPV_OPERAND(_) },
  240. { true, true, /* BitFieldInsert, // 201 */ SPV_OPERAND(_) },
  241. { true, true, /* BitFieldSExtract, // 202 */ SPV_OPERAND(_) },
  242. { true, true, /* BitFieldUExtract, // 203 */ SPV_OPERAND(_) },
  243. { true, true, /* BitReverse, // 204 */ SPV_OPERAND(_) },
  244. { true, true, /* BitCount, // 205 */ SPV_OPERAND(_) },
  245. { false, false, /* ----------------------------- Invalid206 // 206 */ SPV_OPERAND(_) },
  246. { true, true, /* DPdx, // 207 */ SPV_OPERAND(_) },
  247. { true, true, /* DPdy, // 208 */ SPV_OPERAND(_) },
  248. { true, true, /* Fwidth, // 209 */ SPV_OPERAND(_) },
  249. { true, true, /* DPdxFine, // 210 */ SPV_OPERAND(_) },
  250. { true, true, /* DPdyFine, // 211 */ SPV_OPERAND(_) },
  251. { true, true, /* FwidthFine, // 212 */ SPV_OPERAND(_) },
  252. { true, true, /* DPdxCoarse, // 213 */ SPV_OPERAND(_) },
  253. { true, true, /* DPdyCoarse, // 214 */ SPV_OPERAND(_) },
  254. { true, true, /* FwidthCoarse, // 215 */ SPV_OPERAND(_) },
  255. { false, false, /* ----------------------------- Invalid216 // 216 */ SPV_OPERAND(_) },
  256. { false, false, /* ----------------------------- Invalid217 // 217 */ SPV_OPERAND(_) },
  257. { false, false, /* EmitVertex, // 218 */ SPV_OPERAND(_) },
  258. { false, false, /* EndPrimitive, // 219 */ SPV_OPERAND(_) },
  259. { false, false, /* EmitStreamVertex, // 220 */ SPV_OPERAND(_) },
  260. { false, false, /* EndStreamPrimitive, // 221 */ SPV_OPERAND(_) },
  261. { false, false, /* ----------------------------- Invalid222 // 222 */ SPV_OPERAND(_) },
  262. { false, false, /* ----------------------------- Invalid223 // 223 */ SPV_OPERAND(_) },
  263. { false, false, /* ControlBarrier, // 224 */ SPV_OPERAND(_) },
  264. { false, false, /* MemoryBarrier, // 225 */ SPV_OPERAND(_) },
  265. { false, false, /* ----------------------------- Invalid226 // 226 */ SPV_OPERAND(_) },
  266. { true, true, /* AtomicLoad, // 227 */ SPV_OPERAND(_) },
  267. { false, false, /* AtomicStore, // 228 */ SPV_OPERAND(_) },
  268. { true, true, /* AtomicExchange, // 229 */ SPV_OPERAND(_) },
  269. { true, true, /* AtomicCompareExchange, // 230 */ SPV_OPERAND(_) },
  270. { true, true, /* AtomicCompareExchangeWeak, // 231 */ SPV_OPERAND(_) },
  271. { true, true, /* AtomicIIncrement, // 232 */ SPV_OPERAND(_) },
  272. { true, true, /* AtomicIDecrement, // 233 */ SPV_OPERAND(_) },
  273. { true, true, /* AtomicIAdd, // 234 */ SPV_OPERAND(_) },
  274. { true, true, /* AtomicISub, // 235 */ SPV_OPERAND(_) },
  275. { true, true, /* AtomicSMin, // 236 */ SPV_OPERAND(_) },
  276. { true, true, /* AtomicUMin, // 237 */ SPV_OPERAND(_) },
  277. { true, true, /* AtomicSMax, // 238 */ SPV_OPERAND(_) },
  278. { true, true, /* AtomicUMax, // 239 */ SPV_OPERAND(_) },
  279. { true, true, /* AtomicAnd, // 240 */ SPV_OPERAND(_) },
  280. { true, true, /* AtomicOr, // 241 */ SPV_OPERAND(_) },
  281. { true, true, /* AtomicXor, // 242 */ SPV_OPERAND(_) },
  282. { false, false, /* ----------------------------- Invalid243 // 243 */ SPV_OPERAND(_) },
  283. { false, false, /* ----------------------------- Invalid244 // 244 */ SPV_OPERAND(_) },
  284. { true, true, /* Phi, // 245 */ SPV_OPERAND(_) },
  285. { false, false, /* LoopMerge, // 246 */ SPV_OPERAND(_) },
  286. { false, false, /* SelectionMerge, // 247 */ SPV_OPERAND(_) },
  287. { false, true, /* Label, // 248 */ SPV_OPERAND(_) },
  288. { false, false, /* Branch, // 249 */ SPV_OPERAND(Id) },
  289. { false, false, /* BranchConditional, // 250 */ SPV_OPERAND(Condition, Id, Id, LiteralRep) },
  290. { false, false, /* Switch, // 251 */ SPV_OPERAND(_) },
  291. { false, false, /* Kill, // 252 */ SPV_OPERAND(_) },
  292. { false, false, /* Return, // 253 */ SPV_OPERAND(_) },
  293. { false, false, /* ReturnValue, // 254 */ SPV_OPERAND(Id) },
  294. { false, false, /* Unreachable, // 255 */ SPV_OPERAND(_) },
  295. { false, false, /* LifetimeStart, // 256 */ SPV_OPERAND(_) },
  296. { false, false, /* LifetimeStop, // 257 */ SPV_OPERAND(_) },
  297. { false, false, /* ----------------------------- Invalid258 // 258 */ SPV_OPERAND(_) },
  298. { true, true, /* GroupAsyncCopy, // 259 */ SPV_OPERAND(_) },
  299. { false, false, /* GroupWaitEvents, // 260 */ SPV_OPERAND(_) },
  300. { true, true, /* GroupAll, // 261 */ SPV_OPERAND(_) },
  301. { true, true, /* GroupAny, // 262 */ SPV_OPERAND(_) },
  302. { true, true, /* GroupBroadcast, // 263 */ SPV_OPERAND(_) },
  303. { true, true, /* GroupIAdd, // 264 */ SPV_OPERAND(_) },
  304. { true, true, /* GroupFAdd, // 265 */ SPV_OPERAND(_) },
  305. { true, true, /* GroupFMin, // 266 */ SPV_OPERAND(_) },
  306. { true, true, /* GroupUMin, // 267 */ SPV_OPERAND(_) },
  307. { true, true, /* GroupSMin, // 268 */ SPV_OPERAND(_) },
  308. { true, true, /* GroupFMax, // 269 */ SPV_OPERAND(_) },
  309. { true, true, /* GroupUMax, // 270 */ SPV_OPERAND(_) },
  310. { true, true, /* GroupSMax, // 271 */ SPV_OPERAND(_) },
  311. { false, false, /* ----------------------------- Invalid272 // 272 */ SPV_OPERAND(_) },
  312. { false, false, /* ----------------------------- Invalid273 // 273 */ SPV_OPERAND(_) },
  313. { true, true, /* ReadPipe, // 274 */ SPV_OPERAND(_) },
  314. { true, true, /* WritePipe, // 275 */ SPV_OPERAND(_) },
  315. { true, true, /* ReservedReadPipe, // 276 */ SPV_OPERAND(_) },
  316. { true, true, /* ReservedWritePipe, // 277 */ SPV_OPERAND(_) },
  317. { true, true, /* ReserveReadPipePackets, // 278 */ SPV_OPERAND(_) },
  318. { true, true, /* ReserveWritePipePackets, // 279 */ SPV_OPERAND(_) },
  319. { false, false, /* CommitReadPipe, // 280 */ SPV_OPERAND(_) },
  320. { false, false, /* CommitWritePipe, // 281 */ SPV_OPERAND(_) },
  321. { true, true, /* IsValidReserveId, // 282 */ SPV_OPERAND(_) },
  322. { true, true, /* GetNumPipePackets, // 283 */ SPV_OPERAND(_) },
  323. { true, true, /* GetMaxPipePackets, // 284 */ SPV_OPERAND(_) },
  324. { true, true, /* GroupReserveReadPipePackets, // 285 */ SPV_OPERAND(_) },
  325. { true, true, /* GroupReserveWritePipePackets, // 286 */ SPV_OPERAND(_) },
  326. { false, false, /* GroupCommitReadPipe, // 287 */ SPV_OPERAND(_) },
  327. { false, false, /* GroupCommitWritePipe, // 288 */ SPV_OPERAND(_) },
  328. { false, false, /* ----------------------------- Invalid289 // 289 */ SPV_OPERAND(_) },
  329. { false, false, /* ----------------------------- Invalid290 // 290 */ SPV_OPERAND(_) },
  330. { true, true, /* EnqueueMarker, // 291 */ SPV_OPERAND(_) },
  331. { true, true, /* EnqueueKernel, // 292 */ SPV_OPERAND(_) },
  332. { true, true, /* GetKernelNDrangeSubGroupCount, // 293 */ SPV_OPERAND(_) },
  333. { true, true, /* GetKernelNDrangeMaxSubGroupSize, // 294 */ SPV_OPERAND(_) },
  334. { true, true, /* GetKernelWorkGroupSize, // 295 */ SPV_OPERAND(_) },
  335. { true, true, /* GetKernelPreferredWorkGroupSizeMultiple, // 296 */ SPV_OPERAND(_) },
  336. { false, false, /* RetainEvent, // 297 */ SPV_OPERAND(_) },
  337. { false, false, /* ReleaseEvent, // 298 */ SPV_OPERAND(_) },
  338. { true, true, /* CreateUserEvent, // 299 */ SPV_OPERAND(_) },
  339. { true, true, /* IsValidEvent, // 300 */ SPV_OPERAND(_) },
  340. { false, false, /* SetUserEventStatus, // 301 */ SPV_OPERAND(_) },
  341. { false, false, /* CaptureEventProfilingInfo, // 302 */ SPV_OPERAND(_) },
  342. { true, true, /* GetDefaultQueue, // 303 */ SPV_OPERAND(_) },
  343. { true, true, /* BuildNDRange, // 304 */ SPV_OPERAND(_) },
  344. { true, true, /* ImageSparseSampleImplicitLod, // 305 */ SPV_OPERAND(_) },
  345. { true, true, /* ImageSparseSampleExplicitLod, // 306 */ SPV_OPERAND(_) },
  346. { true, true, /* ImageSparseSampleDrefImplicitLod, // 307 */ SPV_OPERAND(_) },
  347. { true, true, /* ImageSparseSampleDrefExplicitLod, // 308 */ SPV_OPERAND(_) },
  348. { true, true, /* ImageSparseSampleProjImplicitLod, // 309 */ SPV_OPERAND(_) },
  349. { true, true, /* ImageSparseSampleProjExplicitLod, // 310 */ SPV_OPERAND(_) },
  350. { true, true, /* ImageSparseSampleProjDrefImplicitLod, // 311 */ SPV_OPERAND(_) },
  351. { true, true, /* ImageSparseSampleProjDrefExplicitLod, // 312 */ SPV_OPERAND(_) },
  352. { true, true, /* ImageSparseFetch, // 313 */ SPV_OPERAND(_) },
  353. { true, true, /* ImageSparseGather, // 314 */ SPV_OPERAND(_) },
  354. { true, true, /* ImageSparseDrefGather, // 315 */ SPV_OPERAND(_) },
  355. { true, true, /* ImageSparseTexelsResident, // 316 */ SPV_OPERAND(_) },
  356. { false, false, /* NoLine, // 317 */ SPV_OPERAND(_) },
  357. { true, true, /* AtomicFlagTestAndSet, // 318 */ SPV_OPERAND(_) },
  358. { false, false, /* AtomicFlagClear, // 319 */ SPV_OPERAND(_) },
  359. { true, true, /* ImageSparseRead, // 320 */ SPV_OPERAND(_) },
  360. };
  361. BX_STATIC_ASSERT(BX_COUNTOF(s_spvOpcodeInfo) == SpvOpcode::Count);
  362. const char* s_spvOpcode[] =
  363. {
  364. "Nop",
  365. "Undef",
  366. "SourceContinued",
  367. "Source",
  368. "SourceExtension",
  369. "Name",
  370. "MemberName",
  371. "String",
  372. "Line",
  373. "Invalid9",
  374. "Extension",
  375. "ExtInstImport",
  376. "ExtInst",
  377. "Invalid13",
  378. "MemoryModel",
  379. "EntryPoint",
  380. "ExecutionMode",
  381. "Capability",
  382. "Invalid18",
  383. "TypeVoid",
  384. "TypeBool",
  385. "TypeInt",
  386. "TypeFloat",
  387. "TypeVector",
  388. "TypeMatrix",
  389. "TypeImage",
  390. "TypeSampler",
  391. "TypeSampledImage",
  392. "TypeArray",
  393. "TypeRuntimeArray",
  394. "TypeStruct",
  395. "TypeOpaque",
  396. "TypePointer",
  397. "TypeFunction",
  398. "TypeEvent",
  399. "TypeDeviceEvent",
  400. "TypeReserveId",
  401. "TypeQueue",
  402. "TypePipe",
  403. "TypeForwardPointer",
  404. "Invalid40",
  405. "ConstantTrue",
  406. "ConstantFalse",
  407. "Constant",
  408. "ConstantComposite",
  409. "ConstantSampler",
  410. "ConstantNull",
  411. "Invalid47",
  412. "SpecConstantTrue",
  413. "SpecConstantFalse",
  414. "SpecConstant",
  415. "SpecConstantComposite",
  416. "SpecConstantOp",
  417. "Invalid53",
  418. "Function",
  419. "FunctionParameter",
  420. "FunctionEnd",
  421. "FunctionCall",
  422. "Invalid58",
  423. "Variable",
  424. "ImageTexelPointer",
  425. "Load",
  426. "Store",
  427. "CopyMemory",
  428. "CopyMemorySized",
  429. "AccessChain",
  430. "InBoundsAccessChain",
  431. "PtrAccessChain",
  432. "ArrayLength",
  433. "GenericPtrMemSemantics",
  434. "InBoundsPtrAccessChain",
  435. "Decorate",
  436. "MemberDecorate",
  437. "DecorationGroup",
  438. "GroupDecorate",
  439. "GroupMemberDecorate",
  440. "Invalid76",
  441. "VectorExtractDynamic",
  442. "VectorInsertDynamic",
  443. "VectorShuffle",
  444. "CompositeConstruct",
  445. "CompositeExtract",
  446. "CompositeInsert",
  447. "CopyObject",
  448. "Transpose",
  449. "Invalid85",
  450. "SampledImage",
  451. "ImageSampleImplicitLod",
  452. "ImageSampleExplicitLod",
  453. "ImageSampleDrefImplicitLod",
  454. "ImageSampleDrefExplicitLod",
  455. "ImageSampleProjImplicitLod",
  456. "ImageSampleProjExplicitLod",
  457. "ImageSampleProjDrefImplicitLod",
  458. "ImageSampleProjDrefExplicitLod",
  459. "ImageFetch",
  460. "ImageGather",
  461. "ImageDrefGather",
  462. "ImageRead",
  463. "ImageWrite",
  464. "Image",
  465. "ImageQueryFormat",
  466. "ImageQueryOrder",
  467. "ImageQuerySizeLod",
  468. "ImageQuerySize",
  469. "ImageQueryLod",
  470. "ImageQueryLevels",
  471. "ImageQuerySamples",
  472. "Invalid108",
  473. "ConvertFToU",
  474. "ConvertFToS",
  475. "ConvertSToF",
  476. "ConvertUToF",
  477. "UConvert",
  478. "SConvert",
  479. "FConvert",
  480. "QuantizeToF16",
  481. "ConvertPtrToU",
  482. "SatConvertSToU",
  483. "SatConvertUToS",
  484. "ConvertUToPtr",
  485. "PtrCastToGeneric",
  486. "GenericCastToPtr",
  487. "GenericCastToPtrExplicit",
  488. "Bitcast",
  489. "Invalid125",
  490. "SNegate",
  491. "FNegate",
  492. "IAdd",
  493. "FAdd",
  494. "ISub",
  495. "FSub",
  496. "IMul",
  497. "FMul",
  498. "UDiv",
  499. "SDiv",
  500. "FDiv",
  501. "UMod",
  502. "SRem",
  503. "SMod",
  504. "FRem",
  505. "FMod",
  506. "VectorTimesScalar",
  507. "MatrixTimesScalar",
  508. "VectorTimesMatrix",
  509. "MatrixTimesVector",
  510. "MatrixTimesMatrix",
  511. "OuterProduct",
  512. "Dot",
  513. "IAddCarry",
  514. "ISubBorrow",
  515. "UMulExtended",
  516. "SMulExtended",
  517. "Invalid153",
  518. "Any",
  519. "All",
  520. "IsNan",
  521. "IsInf",
  522. "IsFinite",
  523. "IsNormal",
  524. "SignBitSet",
  525. "LessOrGreater",
  526. "Ordered",
  527. "Unordered",
  528. "LogicalEqual",
  529. "LogicalNotEqual",
  530. "LogicalOr",
  531. "LogicalAnd",
  532. "LogicalNot",
  533. "Select",
  534. "IEqual",
  535. "INotEqual",
  536. "UGreaterThan",
  537. "SGreaterThan",
  538. "UGreaterThanEqual",
  539. "SGreaterThanEqual",
  540. "ULessThan",
  541. "SLessThan",
  542. "ULessThanEqual",
  543. "SLessThanEqual",
  544. "FOrdEqual",
  545. "FUnordEqual",
  546. "FOrdNotEqual",
  547. "FUnordNotEqual",
  548. "FOrdLessThan",
  549. "FUnordLessThan",
  550. "FOrdGreaterThan",
  551. "FUnordGreaterThan",
  552. "FOrdLessThanEqual",
  553. "FUnordLessThanEqual",
  554. "FOrdGreaterThanEqual",
  555. "FUnordGreaterThanEqual",
  556. "Invalid192",
  557. "Invalid193",
  558. "ShiftRightLogical",
  559. "ShiftRightArithmetic",
  560. "ShiftLeftLogical",
  561. "BitwiseOr",
  562. "BitwiseXor",
  563. "BitwiseAnd",
  564. "Not",
  565. "BitFieldInsert",
  566. "BitFieldSExtract",
  567. "BitFieldUExtract",
  568. "BitReverse",
  569. "BitCount",
  570. "Invalid206",
  571. "DPdx",
  572. "DPdy",
  573. "Fwidth",
  574. "DPdxFine",
  575. "DPdyFine",
  576. "FwidthFine",
  577. "DPdxCoarse",
  578. "DPdyCoarse",
  579. "FwidthCoarse",
  580. "Invalid216",
  581. "Invalid217",
  582. "EmitVertex",
  583. "EndPrimitive",
  584. "EmitStreamVertex",
  585. "Invalid222",
  586. "Invalid223",
  587. "EndStreamPrimitive",
  588. "ControlBarrier",
  589. "MemoryBarrier",
  590. "Invalid226",
  591. "AtomicLoad",
  592. "AtomicStore",
  593. "AtomicExchange",
  594. "AtomicCompareExchange",
  595. "AtomicCompareExchangeWeak",
  596. "AtomicIIncrement",
  597. "AtomicIDecrement",
  598. "AtomicIAdd",
  599. "AtomicISub",
  600. "AtomicSMin",
  601. "AtomicUMin",
  602. "AtomicSMax",
  603. "AtomicUMax",
  604. "AtomicAnd",
  605. "AtomicOr",
  606. "AtomicXor",
  607. "Invalid243",
  608. "Invalid244",
  609. "Phi",
  610. "LoopMerge",
  611. "SelectionMerge",
  612. "Label",
  613. "Branch",
  614. "BranchConditional",
  615. "Switch",
  616. "Kill",
  617. "Return",
  618. "ReturnValue",
  619. "Unreachable",
  620. "LifetimeStart",
  621. "LifetimeStop",
  622. "Invalid258",
  623. "GroupAsyncCopy",
  624. "GroupWaitEvents",
  625. "GroupAll",
  626. "GroupAny",
  627. "GroupBroadcast",
  628. "GroupIAdd",
  629. "GroupFAdd",
  630. "GroupFMin",
  631. "GroupUMin",
  632. "GroupSMin",
  633. "GroupFMax",
  634. "GroupUMax",
  635. "GroupSMax",
  636. "Invalid272",
  637. "Invalid273",
  638. "ReadPipe",
  639. "WritePipe",
  640. "ReservedReadPipe",
  641. "ReservedWritePipe",
  642. "ReserveReadPipePackets",
  643. "ReserveWritePipePackets",
  644. "CommitReadPipe",
  645. "CommitWritePipe",
  646. "IsValidReserveId",
  647. "GetNumPipePackets",
  648. "GetMaxPipePackets",
  649. "GroupReserveReadPipePackets",
  650. "GroupReserveWritePipePackets",
  651. "GroupCommitReadPipe",
  652. "GroupCommitWritePipe",
  653. "Invalid289",
  654. "Invalid290",
  655. "EnqueueMarker",
  656. "EnqueueKernel",
  657. "GetKernelNDrangeSubGroupCount",
  658. "GetKernelNDrangeMaxSubGroupSize",
  659. "GetKernelWorkGroupSize",
  660. "GetKernelPreferredWorkGroupSizeMultiple",
  661. "RetainEvent",
  662. "ReleaseEvent",
  663. "CreateUserEvent",
  664. "IsValidEvent",
  665. "SetUserEventStatus",
  666. "CaptureEventProfilingInfo",
  667. "GetDefaultQueue",
  668. "BuildNDRange",
  669. "ImageSparseSampleImplicitLod",
  670. "ImageSparseSampleExplicitLod",
  671. "ImageSparseSampleDrefImplicitLod",
  672. "ImageSparseSampleDrefExplicitLod",
  673. "ImageSparseSampleProjImplicitLod",
  674. "ImageSparseSampleProjExplicitLod",
  675. "ImageSparseSampleProjDrefImplicitLod",
  676. "ImageSparseSampleProjDrefExplicitLod",
  677. "ImageSparseFetch",
  678. "ImageSparseGather",
  679. "ImageSparseDrefGather",
  680. "ImageSparseTexelsResident",
  681. "NoLine",
  682. "AtomicFlagTestAndSet",
  683. "AtomicFlagClear",
  684. "ImageSparseRead",
  685. "",
  686. };
  687. BX_STATIC_ASSERT(BX_COUNTOF(s_spvOpcode)-1 == SpvOpcode::Count);
  688. const char* getName(SpvOpcode::Enum _opcode)
  689. {
  690. BX_WARN(_opcode <= SpvOpcode::Count, "Unknown opcode id %d.", _opcode);
  691. return _opcode <= SpvOpcode::Count
  692. ? s_spvOpcode[_opcode]
  693. : "?SpvOpcode?"
  694. ;
  695. }
  696. struct SpvDecorationInfo
  697. {
  698. SpvOperand::Enum operands[2];
  699. };
  700. static const SpvDecorationInfo s_spvDecorationInfo[] =
  701. {
  702. { /* RelaxedPrecision */ SPV_OPERAND(_) },
  703. { /* SpecId */ SPV_OPERAND(LiteralNumber) },
  704. { /* Block */ SPV_OPERAND(_) },
  705. { /* BufferBlock */ SPV_OPERAND(_) },
  706. { /* RowMajor */ SPV_OPERAND(_) },
  707. { /* ColMajor */ SPV_OPERAND(_) },
  708. { /* ArrayStride */ SPV_OPERAND(LiteralNumber) },
  709. { /* MatrixStride */ SPV_OPERAND(LiteralNumber) },
  710. { /* GLSLShared */ SPV_OPERAND(_) },
  711. { /* GLSLPacked */ SPV_OPERAND(_) },
  712. { /* CPacked */ SPV_OPERAND(_) },
  713. { /* BuiltIn */ SPV_OPERAND(LiteralNumber) },
  714. { /* Unknown12 */ SPV_OPERAND(_) },
  715. { /* NoPerspective */ SPV_OPERAND(_) },
  716. { /* Flat */ SPV_OPERAND(_) },
  717. { /* Patch */ SPV_OPERAND(_) },
  718. { /* Centroid */ SPV_OPERAND(_) },
  719. { /* Sample */ SPV_OPERAND(_) },
  720. { /* Invariant */ SPV_OPERAND(_) },
  721. { /* Restrict */ SPV_OPERAND(_) },
  722. { /* Aliased */ SPV_OPERAND(_) },
  723. { /* Volatile */ SPV_OPERAND(_) },
  724. { /* Constant */ SPV_OPERAND(_) },
  725. { /* Coherent */ SPV_OPERAND(_) },
  726. { /* NonWritable */ SPV_OPERAND(_) },
  727. { /* NonReadable */ SPV_OPERAND(_) },
  728. { /* Uniform */ SPV_OPERAND(_) },
  729. { /* Unknown27 */ SPV_OPERAND(_) },
  730. { /* SaturatedConversion */ SPV_OPERAND(_) },
  731. { /* Stream */ SPV_OPERAND(LiteralNumber) },
  732. { /* Location */ SPV_OPERAND(LiteralNumber) },
  733. { /* Component */ SPV_OPERAND(LiteralNumber) },
  734. { /* Index */ SPV_OPERAND(LiteralNumber) },
  735. { /* Binding */ SPV_OPERAND(LiteralNumber) },
  736. { /* DescriptorSet */ SPV_OPERAND(LiteralNumber) },
  737. { /* Offset */ SPV_OPERAND(LiteralNumber) },
  738. { /* XfbBuffer */ SPV_OPERAND(LiteralNumber) },
  739. { /* XfbStride */ SPV_OPERAND(LiteralNumber) },
  740. { /* FuncParamAttr */ SPV_OPERAND(_) },
  741. { /* FPRoundingMode */ SPV_OPERAND(_) },
  742. { /* FPFastMathMode */ SPV_OPERAND(_) },
  743. { /* LinkageAttributes */ SPV_OPERAND(LiteralString, LinkageType) },
  744. { /* NoContraction */ SPV_OPERAND(_) },
  745. { /* InputAttachmentIndex */ SPV_OPERAND(LiteralNumber) },
  746. { /* Alignment */ SPV_OPERAND(LiteralNumber) },
  747. };
  748. static const char* s_spvDecoration[] =
  749. {
  750. "RelaxedPrecision",
  751. "SpecId",
  752. "Block",
  753. "BufferBlock",
  754. "RowMajor",
  755. "ColMajor",
  756. "ArrayStride",
  757. "MatrixStride",
  758. "GLSLShared",
  759. "GLSLPacked",
  760. "CPacked",
  761. "BuiltIn",
  762. "Unknown12",
  763. "NoPerspective",
  764. "Flat",
  765. "Patch",
  766. "Centroid",
  767. "Sample",
  768. "Invariant",
  769. "Restrict",
  770. "Aliased",
  771. "Volatile",
  772. "Constant",
  773. "Coherent",
  774. "NonWritable",
  775. "NonReadable",
  776. "Uniform",
  777. "Unknown27",
  778. "SaturatedConversion",
  779. "Stream",
  780. "Location",
  781. "Component",
  782. "Index",
  783. "Binding",
  784. "DescriptorSet",
  785. "Offset",
  786. "XfbBuffer",
  787. "XfbStride",
  788. "FuncParamAttr",
  789. "FPRoundingMode",
  790. "FPFastMathMode",
  791. "LinkageAttributes",
  792. "NoContraction",
  793. "InputAttachmentIndex",
  794. "Alignment",
  795. ""
  796. };
  797. BX_STATIC_ASSERT(BX_COUNTOF(s_spvDecoration)-1 == SpvDecoration::Count);
  798. const char* getName(SpvDecoration::Enum _enum)
  799. {
  800. BX_UNUSED(s_spvDecorationInfo);
  801. BX_ASSERT(_enum <= SpvDecoration::Count, "Unknown decoration id %d.", _enum);
  802. return _enum <= SpvDecoration::Count
  803. ? s_spvDecoration[_enum]
  804. : "?SpvDecoration?"
  805. ;
  806. }
  807. #undef _
  808. #undef SPV_OPERAND
  809. static const char* s_spvStorageClass[] =
  810. {
  811. "UniformConstant",
  812. "Input",
  813. "Uniform",
  814. "Output",
  815. "Workgroup",
  816. "CrossWorkgroup",
  817. "Private",
  818. "Function",
  819. "Generic",
  820. "PushConstant",
  821. "AtomicCounter",
  822. "Image",
  823. ""
  824. };
  825. BX_STATIC_ASSERT(BX_COUNTOF(s_spvStorageClass)-1 == SpvStorageClass::Count);
  826. const char* getName(SpvStorageClass::Enum _enum)
  827. {
  828. BX_ASSERT(_enum <= SpvStorageClass::Count, "Unknown storage class id %d.", _enum);
  829. return _enum <= SpvStorageClass::Count
  830. ? s_spvStorageClass[_enum]
  831. : "?SpvStorageClass?"
  832. ;
  833. }
  834. static const char* s_spvBuiltin[] =
  835. {
  836. "Position",
  837. "PointSize",
  838. "ClipDistance",
  839. "CullDistance",
  840. "VertexId",
  841. "InstanceId",
  842. "PrimitiveId",
  843. "InvocationId",
  844. "Layer",
  845. "ViewportIndex",
  846. "TessLevelOuter",
  847. "TessLevelInner",
  848. "TessCoord",
  849. "PatchVertices",
  850. "FragCoord",
  851. "PointCoord",
  852. "FrontFacing",
  853. "SampleId",
  854. "SamplePosition",
  855. "SampleMask",
  856. "FragDepth",
  857. "HelperInvocation",
  858. "NumWorkgroups",
  859. "WorkgroupSize",
  860. "WorkgroupId",
  861. "LocalInvocationId",
  862. "GlobalInvocationId",
  863. "LocalInvocationIndex",
  864. "WorkDim",
  865. "GlobalSize",
  866. "EnqueuedWorkgroupSize",
  867. "GlobalOffset",
  868. "GlobalLinearId",
  869. "SubgroupSize",
  870. "SubgroupMaxSize",
  871. "NumSubgroups",
  872. "NumEnqueuedSubgroups",
  873. "SubgroupId",
  874. "SubgroupLocalInvocationId",
  875. "VertexIndex",
  876. "InstanceIndex",
  877. "",
  878. };
  879. BX_STATIC_ASSERT(BX_COUNTOF(s_spvBuiltin)-1 == SpvBuiltin::Count);
  880. const char* getName(SpvBuiltin::Enum _enum)
  881. {
  882. BX_ASSERT(_enum <= SpvBuiltin::Count, "Unknown builtin id %d.", _enum);
  883. return _enum <= SpvBuiltin::Count
  884. ? s_spvBuiltin[_enum]
  885. : "?SpvBuiltin?"
  886. ;
  887. }
  888. int32_t read(bx::ReaderI* _reader, SpvOperand& _operand, bx::Error* _err)
  889. {
  890. int32_t size = 0;
  891. uint32_t token;
  892. _operand.literalString = "";
  893. switch (_operand.type)
  894. {
  895. case SpvOperand::LiteralString:
  896. do
  897. {
  898. size += bx::read(_reader, token, _err);
  899. _operand.literalString.append( (char*)&token, (char*)&token + sizeof(token) );
  900. }
  901. while (0 != (token & 0xff000000) && _err->isOk() );
  902. break;
  903. default:
  904. size += bx::read(_reader, _operand.data, _err);
  905. break;
  906. }
  907. return size;
  908. }
  909. int32_t read(bx::ReaderI* _reader, SpvInstruction& _instruction, bx::Error* _err)
  910. {
  911. int32_t size = 0;
  912. uint32_t token;
  913. size += bx::read(_reader, token, _err);
  914. _instruction.opcode = SpvOpcode::Enum( (token & UINT32_C(0x0000ffff) ) );
  915. _instruction.length = uint16_t( (token & UINT32_C(0xffff0000) ) >> 16);
  916. if (_instruction.opcode >= SpvOpcode::Count)
  917. {
  918. BX_ERROR_SET(_err, BGFX_SHADER_SPIRV_INVALID_INSTRUCTION, "SPIR-V: Invalid instruction.");
  919. return size;
  920. }
  921. if (0 == _instruction.length)
  922. {
  923. return size;
  924. }
  925. const SpvOpcodeInfo& info = s_spvOpcodeInfo[_instruction.opcode];
  926. _instruction.hasType = info.hasType;
  927. _instruction.hasResult = info.hasResult;
  928. if (info.hasType)
  929. {
  930. size += read(_reader, _instruction.type, _err);
  931. }
  932. else
  933. {
  934. _instruction.type = UINT32_MAX;
  935. }
  936. if (info.hasResult)
  937. {
  938. size += read(_reader, _instruction.result, _err);
  939. }
  940. else
  941. {
  942. _instruction.result = UINT32_MAX;
  943. }
  944. uint16_t currOp = 0;
  945. switch (_instruction.opcode)
  946. {
  947. case SpvOpcode::EntryPoint:
  948. _instruction.operand[currOp].type = info.operands[currOp];
  949. size += read(_reader, _instruction.operand[currOp++], _err);
  950. _instruction.operand[currOp].type = info.operands[currOp];
  951. size += read(_reader, _instruction.operand[currOp++], _err);
  952. _instruction.operand[currOp].type = info.operands[currOp];
  953. size += read(_reader, _instruction.operand[currOp++], _err);
  954. _instruction.operand[currOp].type = SpvOperand::Id;
  955. for (uint32_t ii = 0, num = _instruction.length - size/4; ii < num; ++ii)
  956. {
  957. size += read(_reader, _instruction.operand[currOp], _err);
  958. }
  959. break;
  960. default:
  961. for (
  962. ; size/4 != _instruction.length
  963. && _err->isOk()
  964. && currOp < BX_COUNTOF(_instruction.operand)
  965. ; ++currOp)
  966. {
  967. _instruction.operand[currOp].type = info.operands[currOp];
  968. size += read(_reader, _instruction.operand[currOp], _err);
  969. }
  970. break;
  971. }
  972. _instruction.numOperands = currOp;
  973. return size;
  974. }
  975. int32_t write(bx::WriterI* _writer, const SpvInstruction& _instruction, bx::Error* _err)
  976. {
  977. int32_t size = 0;
  978. BX_UNUSED(_writer, _instruction, _err);
  979. return size;
  980. }
  981. int32_t toString(char* _out, int32_t _size, const SpvInstruction& _instruction)
  982. {
  983. int32_t size = 0;
  984. if (_instruction.hasResult)
  985. {
  986. if (_instruction.hasType)
  987. {
  988. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  989. , " r%d.t%d = "
  990. , _instruction.result
  991. , _instruction.type
  992. );
  993. }
  994. else
  995. {
  996. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  997. , " r%d = "
  998. , _instruction.result
  999. );
  1000. }
  1001. }
  1002. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1003. , "%s"
  1004. , getName(_instruction.opcode)
  1005. );
  1006. for (uint32_t ii = 0, num = _instruction.numOperands; ii < num; ++ii)
  1007. {
  1008. const SpvOperand& operand = _instruction.operand[ii];
  1009. switch (operand.type)
  1010. {
  1011. case SpvOperand::AddressingModel:
  1012. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1013. , "%sAddressingModel(%d)"
  1014. , 0 == ii ? " " : ", "
  1015. , operand.data
  1016. );
  1017. break;
  1018. case SpvOperand::Decoration:
  1019. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1020. , "%s%s"
  1021. , 0 == ii ? " " : ", "
  1022. , getName(SpvDecoration::Enum(operand.data) )
  1023. );
  1024. break;
  1025. case SpvOperand::FunctionControl:
  1026. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1027. , "%s0x%08x"
  1028. , 0 == ii ? " " : ", "
  1029. , operand.data
  1030. );
  1031. break;
  1032. case SpvOperand::LiteralNumber:
  1033. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1034. , "%s%d"
  1035. , 0 == ii ? " " : ", "
  1036. , operand.data
  1037. );
  1038. break;
  1039. case SpvOperand::LiteralString:
  1040. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1041. , "%s%s"
  1042. , 0 == ii ? " " : ", "
  1043. , operand.literalString.c_str()
  1044. );
  1045. break;
  1046. case SpvOperand::MemoryModel:
  1047. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1048. , "%sMemoryModel(%d)"
  1049. , 0 == ii ? " " : ", "
  1050. , operand.data
  1051. );
  1052. break;
  1053. case SpvOperand::StorageClass:
  1054. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1055. , "%s%s"
  1056. , 0 == ii ? " " : ", "
  1057. , getName(SpvStorageClass::Enum(operand.data) )
  1058. );
  1059. break;
  1060. case SpvOperand::Count:
  1061. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1062. , "%s__%d__"
  1063. , 0 == ii ? " " : ", "
  1064. , operand.data
  1065. );
  1066. break;
  1067. default:
  1068. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1069. , "%sr%d"
  1070. , 0 == ii ? " " : ", "
  1071. , operand.data
  1072. );
  1073. break;
  1074. }
  1075. }
  1076. return size;
  1077. }
  1078. int32_t read(bx::ReaderSeekerI* _reader, SpvShader& _shader, bx::Error* _err)
  1079. {
  1080. int32_t size = 0;
  1081. uint32_t numBytes = uint32_t(bx::getSize(_reader) - bx::seek(_reader) );
  1082. _shader.byteCode.resize(numBytes);
  1083. size += bx::read(_reader, _shader.byteCode.data(), numBytes, _err);
  1084. return size;
  1085. }
  1086. int32_t write(bx::WriterI* _writer, const SpvShader& _shader, bx::Error* _err)
  1087. {
  1088. int32_t size = 0;
  1089. BX_UNUSED(_writer, _shader, _err);
  1090. return size;
  1091. }
  1092. #define SPIRV_MAGIC 0x07230203
  1093. int32_t read(bx::ReaderSeekerI* _reader, SpirV& _spirv, bx::Error* _err)
  1094. {
  1095. BX_ERROR_SCOPE(_err);
  1096. int32_t size = 0;
  1097. size += bx::read(_reader, _spirv.header, _err);
  1098. if (!_err->isOk()
  1099. || size != sizeof(SpirV::Header)
  1100. || _spirv.header.magic != SPIRV_MAGIC
  1101. )
  1102. {
  1103. BX_ERROR_SET(_err, BGFX_SHADER_SPIRV_INVALID_HEADER, "SPIR-V: Invalid header.");
  1104. return size;
  1105. }
  1106. size += read(_reader, _spirv.shader, _err);
  1107. return size;
  1108. }
  1109. int32_t write(bx::WriterSeekerI* _writer, const SpirV& _spirv, bx::Error* _err)
  1110. {
  1111. int32_t size = 0;
  1112. BX_UNUSED(_writer, _spirv, _err);
  1113. return size;
  1114. }
  1115. void parse(const SpvShader& _src, SpvParseFn _fn, void* _userData, bx::Error* _err)
  1116. {
  1117. BX_ERROR_SCOPE(_err);
  1118. uint32_t numBytes = uint32_t(_src.byteCode.size() );
  1119. bx::MemoryReader reader(_src.byteCode.data(), numBytes);
  1120. for (uint32_t token = 0, numTokens = uint32_t(_src.byteCode.size() / sizeof(uint32_t) ); token < numTokens;)
  1121. {
  1122. SpvInstruction instruction;
  1123. uint32_t size = read(&reader, instruction, _err);
  1124. if (!_err->isOk() )
  1125. {
  1126. return;
  1127. }
  1128. if (size/4 != instruction.length)
  1129. {
  1130. BX_TRACE("read %d, expected %d, %s"
  1131. , size/4
  1132. , instruction.length
  1133. , getName(instruction.opcode)
  1134. );
  1135. BX_ERROR_SET(_err, BGFX_SHADER_SPIRV_INVALID_INSTRUCTION, "SPIR-V: Invalid instruction.");
  1136. return;
  1137. }
  1138. bool cont = _fn(token * sizeof(uint32_t), instruction, _userData);
  1139. if (!cont)
  1140. {
  1141. return;
  1142. }
  1143. token += instruction.length;
  1144. }
  1145. }
  1146. } // namespace bgfx