shader_dxbc.cpp 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262
  1. /*
  2. * Copyright 2011-2023 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
  4. */
  5. #include "bgfx_p.h"
  6. #include "shader_dxbc.h"
  7. namespace bgfx
  8. {
  9. struct DxbcOpcodeInfo
  10. {
  11. uint8_t numOperands;
  12. uint8_t numValues;
  13. };
  14. static const DxbcOpcodeInfo s_dxbcOpcodeInfo[] =
  15. {
  16. { 3, 0 }, // ADD
  17. { 3, 0 }, // AND
  18. { 0, 0 }, // BREAK
  19. { 1, 0 }, // BREAKC
  20. { 0, 0 }, // CALL
  21. { 0, 0 }, // CALLC
  22. { 1, 0 }, // CASE
  23. { 0, 0 }, // CONTINUE
  24. { 1, 0 }, // CONTINUEC
  25. { 0, 0 }, // CUT
  26. { 0, 0 }, // DEFAULT
  27. { 2, 0 }, // DERIV_RTX
  28. { 2, 0 }, // DERIV_RTY
  29. { 1, 0 }, // DISCARD
  30. { 3, 0 }, // DIV
  31. { 3, 0 }, // DP2
  32. { 3, 0 }, // DP3
  33. { 3, 0 }, // DP4
  34. { 0, 0 }, // ELSE
  35. { 0, 0 }, // EMIT
  36. { 0, 0 }, // EMITTHENCUT
  37. { 0, 0 }, // ENDIF
  38. { 0, 0 }, // ENDLOOP
  39. { 0, 0 }, // ENDSWITCH
  40. { 3, 0 }, // EQ
  41. { 2, 0 }, // EXP
  42. { 2, 0 }, // FRC
  43. { 2, 0 }, // FTOI
  44. { 2, 0 }, // FTOU
  45. { 3, 0 }, // GE
  46. { 3, 0 }, // IADD
  47. { 1, 0 }, // IF
  48. { 3, 0 }, // IEQ
  49. { 3, 0 }, // IGE
  50. { 3, 0 }, // ILT
  51. { 4, 0 }, // IMAD
  52. { 3, 0 }, // IMAX
  53. { 3, 0 }, // IMIN
  54. { 4, 0 }, // IMUL
  55. { 3, 0 }, // INE
  56. { 2, 0 }, // INEG
  57. { 3, 0 }, // ISHL
  58. { 3, 0 }, // ISHR
  59. { 2, 0 }, // ITOF
  60. { 0, 0 }, // LABEL
  61. { 3, 0 }, // LD
  62. { 4, 0 }, // LD_MS
  63. { 2, 0 }, // LOG
  64. { 0, 0 }, // LOOP
  65. { 3, 0 }, // LT
  66. { 4, 0 }, // MAD
  67. { 3, 0 }, // MIN
  68. { 3, 0 }, // MAX
  69. { 0, 1 }, // CUSTOMDATA
  70. { 2, 0 }, // MOV
  71. { 4, 0 }, // MOVC
  72. { 3, 0 }, // MUL
  73. { 3, 0 }, // NE
  74. { 0, 0 }, // NOP
  75. { 2, 0 }, // NOT
  76. { 3, 0 }, // OR
  77. { 3, 0 }, // RESINFO
  78. { 0, 0 }, // RET
  79. { 1, 0 }, // RETC
  80. { 2, 0 }, // ROUND_NE
  81. { 2, 0 }, // ROUND_NI
  82. { 2, 0 }, // ROUND_PI
  83. { 2, 0 }, // ROUND_Z
  84. { 2, 0 }, // RSQ
  85. { 4, 0 }, // SAMPLE
  86. { 5, 0 }, // SAMPLE_C
  87. { 5, 0 }, // SAMPLE_C_LZ
  88. { 5, 0 }, // SAMPLE_L
  89. { 6, 0 }, // SAMPLE_D
  90. { 5, 0 }, // SAMPLE_B
  91. { 2, 0 }, // SQRT
  92. { 1, 0 }, // SWITCH
  93. { 3, 0 }, // SINCOS
  94. { 4, 0 }, // UDIV
  95. { 3, 0 }, // ULT
  96. { 3, 0 }, // UGE
  97. { 4, 0 }, // UMUL
  98. { 4, 0 }, // UMAD
  99. { 3, 0 }, // UMAX
  100. { 3, 0 }, // UMIN
  101. { 3, 0 }, // USHR
  102. { 2, 0 }, // UTOF
  103. { 3, 0 }, // XOR
  104. { 1, 1 }, // DCL_RESOURCE
  105. { 1, 0 }, // DCL_CONSTANT_BUFFER
  106. { 1, 0 }, // DCL_SAMPLER
  107. { 1, 1 }, // DCL_INDEX_RANGE
  108. { 0, 0 }, // DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY
  109. { 0, 0 }, // DCL_GS_INPUT_PRIMITIVE
  110. { 0, 1 }, // DCL_MAX_OUTPUT_VERTEX_COUNT
  111. { 1, 0 }, // DCL_INPUT
  112. { 1, 1 }, // DCL_INPUT_SGV
  113. { 1, 1 }, // DCL_INPUT_SIV
  114. { 1, 0 }, // DCL_INPUT_PS
  115. { 1, 1 }, // DCL_INPUT_PS_SGV
  116. { 1, 1 }, // DCL_INPUT_PS_SIV
  117. { 1, 0 }, // DCL_OUTPUT
  118. { 1, 1 }, // DCL_OUTPUT_SGV
  119. { 1, 1 }, // DCL_OUTPUT_SIV
  120. { 0, 1 }, // DCL_TEMPS
  121. { 0, 3 }, // DCL_INDEXABLE_TEMP
  122. { 0, 0 }, // DCL_GLOBAL_FLAGS
  123. { 0, 0 }, // InstrD3D10
  124. { 4, 0 }, // LOD
  125. { 4, 0 }, // GATHER4
  126. { 0, 0 }, // SAMPLE_POS
  127. { 0, 0 }, // SAMPLE_INFO
  128. { 0, 0 }, // InstrD3D10_1
  129. { 0, 0 }, // HS_DECLS
  130. { 0, 0 }, // HS_CONTROL_POINT_PHASE
  131. { 0, 0 }, // HS_FORK_PHASE
  132. { 0, 0 }, // HS_JOIN_PHASE
  133. { 1, 0 }, // EMIT_STREAM
  134. { 1, 0 }, // CUT_STREAM
  135. { 1, 0 }, // EMITTHENCUT_STREAM
  136. { 1, 0 }, // INTERFACE_CALL
  137. { 0, 0 }, // BUFINFO
  138. { 2, 0 }, // DERIV_RTX_COARSE
  139. { 2, 0 }, // DERIV_RTX_FINE
  140. { 2, 0 }, // DERIV_RTY_COARSE
  141. { 2, 0 }, // DERIV_RTY_FINE
  142. { 5, 0 }, // GATHER4_C
  143. { 5, 0 }, // GATHER4_PO
  144. { 0, 0 }, // GATHER4_PO_C
  145. { 2, 0 }, // RCP
  146. { 0, 0 }, // F32TOF16
  147. { 0, 0 }, // F16TOF32
  148. { 0, 0 }, // UADDC
  149. { 0, 0 }, // USUBB
  150. { 0, 0 }, // COUNTBITS
  151. { 0, 0 }, // FIRSTBIT_HI
  152. { 0, 0 }, // FIRSTBIT_LO
  153. { 0, 0 }, // FIRSTBIT_SHI
  154. { 4, 0 }, // UBFE
  155. { 4, 0 }, // IBFE
  156. { 5, 0 }, // BFI
  157. { 0, 0 }, // BFREV
  158. { 5, 0 }, // SWAPC
  159. { 1, 0 }, // DCL_STREAM
  160. { 1, 0 }, // DCL_FUNCTION_BODY
  161. { 0, 0 }, // DCL_FUNCTION_TABLE
  162. { 0, 0 }, // DCL_INTERFACE
  163. { 0, 0 }, // DCL_INPUT_CONTROL_POINT_COUNT
  164. { 0, 0 }, // DCL_OUTPUT_CONTROL_POINT_COUNT
  165. { 0, 0 }, // DCL_TESS_DOMAIN
  166. { 0, 0 }, // DCL_TESS_PARTITIONING
  167. { 0, 0 }, // DCL_TESS_OUTPUT_PRIMITIVE
  168. { 0, 0 }, // DCL_HS_MAX_TESSFACTOR
  169. { 0, 0 }, // DCL_HS_FORK_PHASE_INSTANCE_COUNT
  170. { 0, 0 }, // DCL_HS_JOIN_PHASE_INSTANCE_COUNT
  171. { 0, 3 }, // DCL_THREAD_GROUP
  172. { 1, 1 }, // DCL_UNORDERED_ACCESS_VIEW_TYPED
  173. { 1, 0 }, // DCL_UNORDERED_ACCESS_VIEW_RAW
  174. { 1, 1 }, // DCL_UNORDERED_ACCESS_VIEW_STRUCTURED
  175. { 1, 1 }, // DCL_THREAD_GROUP_SHARED_MEMORY_RAW
  176. { 1, 2 }, // DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED
  177. { 1, 0 }, // DCL_RESOURCE_RAW
  178. { 1, 1 }, // DCL_RESOURCE_STRUCTURED
  179. { 3, 0 }, // LD_UAV_TYPED
  180. { 3, 0 }, // STORE_UAV_TYPED
  181. { 3, 0 }, // LD_RAW
  182. { 3, 0 }, // STORE_RAW
  183. { 4, 0 }, // LD_STRUCTURED
  184. { 4, 0 }, // STORE_STRUCTURED
  185. { 3, 0 }, // ATOMIC_AND
  186. { 3, 0 }, // ATOMIC_OR
  187. { 3, 0 }, // ATOMIC_XOR
  188. { 3, 0 }, // ATOMIC_CMP_STORE
  189. { 3, 0 }, // ATOMIC_IADD
  190. { 3, 0 }, // ATOMIC_IMAX
  191. { 3, 0 }, // ATOMIC_IMIN
  192. { 3, 0 }, // ATOMIC_UMAX
  193. { 3, 0 }, // ATOMIC_UMIN
  194. { 2, 0 }, // IMM_ATOMIC_ALLOC
  195. { 2, 0 }, // IMM_ATOMIC_CONSUME
  196. { 0, 0 }, // IMM_ATOMIC_IADD
  197. { 0, 0 }, // IMM_ATOMIC_AND
  198. { 0, 0 }, // IMM_ATOMIC_OR
  199. { 0, 0 }, // IMM_ATOMIC_XOR
  200. { 0, 0 }, // IMM_ATOMIC_EXCH
  201. { 0, 0 }, // IMM_ATOMIC_CMP_EXCH
  202. { 0, 0 }, // IMM_ATOMIC_IMAX
  203. { 0, 0 }, // IMM_ATOMIC_IMIN
  204. { 0, 0 }, // IMM_ATOMIC_UMAX
  205. { 0, 0 }, // IMM_ATOMIC_UMIN
  206. { 0, 0 }, // SYNC
  207. { 3, 0 }, // DADD
  208. { 3, 0 }, // DMAX
  209. { 3, 0 }, // DMIN
  210. { 3, 0 }, // DMUL
  211. { 3, 0 }, // DEQ
  212. { 3, 0 }, // DGE
  213. { 3, 0 }, // DLT
  214. { 3, 0 }, // DNE
  215. { 2, 0 }, // DMOV
  216. { 4, 0 }, // DMOVC
  217. { 0, 0 }, // DTOF
  218. { 0, 0 }, // FTOD
  219. { 3, 0 }, // EVAL_SNAPPED
  220. { 3, 0 }, // EVAL_SAMPLE_INDEX
  221. { 2, 0 }, // EVAL_CENTROID
  222. { 0, 1 }, // DCL_GS_INSTANCE_COUNT
  223. { 0, 0 }, // ABORT
  224. { 0, 0 }, // DEBUG_BREAK
  225. { 0, 0 }, // InstrD3D11
  226. { 0, 0 }, // DDIV
  227. { 0, 0 }, // DFMA
  228. { 0, 0 }, // DRCP
  229. { 0, 0 }, // MSAD
  230. { 0, 0 }, // DTOI
  231. { 0, 0 }, // DTOU
  232. { 0, 0 }, // ITOD
  233. { 0, 0 }, // UTOD
  234. };
  235. BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcOpcodeInfo) == DxbcOpcode::Count);
  236. static const char* s_dxbcOpcode[] =
  237. {
  238. "add",
  239. "and",
  240. "break",
  241. "breakc",
  242. "call",
  243. "callc",
  244. "case",
  245. "continue",
  246. "continuec",
  247. "cut",
  248. "default",
  249. "deriv_rtx",
  250. "deriv_rty",
  251. "discard",
  252. "div",
  253. "dp2",
  254. "dp3",
  255. "dp4",
  256. "else",
  257. "emit",
  258. "emitthencut",
  259. "endif",
  260. "endloop",
  261. "endswitch",
  262. "eq",
  263. "exp",
  264. "frc",
  265. "ftoi",
  266. "ftou",
  267. "ge",
  268. "iadd",
  269. "if",
  270. "ieq",
  271. "ige",
  272. "ilt",
  273. "imad",
  274. "imax",
  275. "imin",
  276. "imul",
  277. "ine",
  278. "ineg",
  279. "ishl",
  280. "ishr",
  281. "itof",
  282. "label",
  283. "ld",
  284. "ld_ms",
  285. "log",
  286. "loop",
  287. "lt",
  288. "mad",
  289. "min",
  290. "max",
  291. "customdata",
  292. "mov",
  293. "movc",
  294. "mul",
  295. "ne",
  296. "nop",
  297. "not",
  298. "or",
  299. "resinfo",
  300. "ret",
  301. "retc",
  302. "round_ne",
  303. "round_ni",
  304. "round_pi",
  305. "round_z",
  306. "rsq",
  307. "sample",
  308. "sample_c",
  309. "sample_c_lz",
  310. "sample_l",
  311. "sample_d",
  312. "sample_b",
  313. "sqrt",
  314. "switch",
  315. "sincos",
  316. "udiv",
  317. "ult",
  318. "uge",
  319. "umul",
  320. "umad",
  321. "umax",
  322. "umin",
  323. "ushr",
  324. "utof",
  325. "xor",
  326. "dcl_resource",
  327. "dcl_constantbuffer",
  328. "dcl_sampler",
  329. "dcl_index_range",
  330. "dcl_gs_output_primitive_topology",
  331. "dcl_gs_input_primitive",
  332. "dcl_max_output_vertex_count",
  333. "dcl_input",
  334. "dcl_input_sgv",
  335. "dcl_input_siv",
  336. "dcl_input_ps",
  337. "dcl_input_ps_sgv",
  338. "dcl_input_ps_siv",
  339. "dcl_output",
  340. "dcl_output_sgv",
  341. "dcl_output_siv",
  342. "dcl_temps",
  343. "dcl_indexable_temp",
  344. "dcl_global_flags",
  345. NULL,
  346. "lod",
  347. "gather4",
  348. "sample_pos",
  349. "sample_info",
  350. NULL,
  351. "hs_decls",
  352. "hs_control_point_phase",
  353. "hs_fork_phase",
  354. "hs_join_phase",
  355. "emit_stream",
  356. "cut_stream",
  357. "emitthencut_stream",
  358. "interface_call",
  359. "bufinfo",
  360. "deriv_rtx_coarse",
  361. "deriv_rtx_fine",
  362. "deriv_rty_coarse",
  363. "deriv_rty_fine",
  364. "gather4_c",
  365. "gather4_po",
  366. "gather4_po_c",
  367. "rcp",
  368. "f32tof16",
  369. "f16tof32",
  370. "uaddc",
  371. "usubb",
  372. "countbits",
  373. "firstbit_hi",
  374. "firstbit_lo",
  375. "firstbit_shi",
  376. "ubfe",
  377. "ibfe",
  378. "bfi",
  379. "bfrev",
  380. "swapc",
  381. "dcl_stream",
  382. "dcl_function_body",
  383. "dcl_function_table",
  384. "dcl_interface",
  385. "dcl_input_control_point_count",
  386. "dcl_output_control_point_count",
  387. "dcl_tess_domain",
  388. "dcl_tess_partitioning",
  389. "dcl_tess_output_primitive",
  390. "dcl_hs_max_tessfactor",
  391. "dcl_hs_fork_phase_instance_count",
  392. "dcl_hs_join_phase_instance_count",
  393. "dcl_thread_group",
  394. "dcl_unordered_access_view_typed",
  395. "dcl_unordered_access_view_raw",
  396. "dcl_unordered_access_view_structured",
  397. "dcl_thread_group_shared_memory_raw",
  398. "dcl_thread_group_shared_memory_structured",
  399. "dcl_resource_raw",
  400. "dcl_resource_structured",
  401. "ld_uav_typed",
  402. "store_uav_typed",
  403. "ld_raw",
  404. "store_raw",
  405. "ld_structured",
  406. "store_structured",
  407. "atomic_and",
  408. "atomic_or",
  409. "atomic_xor",
  410. "atomic_cmp_store",
  411. "atomic_iadd",
  412. "atomic_imax",
  413. "atomic_imin",
  414. "atomic_umax",
  415. "atomic_umin",
  416. "imm_atomic_alloc",
  417. "imm_atomic_consume",
  418. "imm_atomic_iadd",
  419. "imm_atomic_and",
  420. "imm_atomic_or",
  421. "imm_atomic_xor",
  422. "imm_atomic_exch",
  423. "imm_atomic_cmp_exch",
  424. "imm_atomic_imax",
  425. "imm_atomic_imin",
  426. "imm_atomic_umax",
  427. "imm_atomic_umin",
  428. "sync",
  429. "dadd",
  430. "dmax",
  431. "dmin",
  432. "dmul",
  433. "deq",
  434. "dge",
  435. "dlt",
  436. "dne",
  437. "dmov",
  438. "dmovc",
  439. "dtof",
  440. "ftod",
  441. "eval_snapped",
  442. "eval_sample_index",
  443. "eval_centroid",
  444. "dcl_gs_instance_count",
  445. "abort",
  446. "debug_break",
  447. NULL,
  448. "ddiv",
  449. "dfma",
  450. "drcp",
  451. "msad",
  452. "dtoi",
  453. "dtou",
  454. "itod",
  455. "utod",
  456. };
  457. BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcOpcode) == DxbcOpcode::Count);
  458. const char* getName(DxbcOpcode::Enum _opcode)
  459. {
  460. BX_ASSERT(_opcode < DxbcOpcode::Count, "Unknown opcode id %d.", _opcode);
  461. return s_dxbcOpcode[_opcode];
  462. }
  463. static const char* s_dxbcSrvType[] =
  464. {
  465. "", // Unknown
  466. "Buffer", // Buffer
  467. "Texture1D", // Texture1D
  468. "Texture2D", // Texture2D
  469. "Texture2DMS", // Texture2DMS
  470. "Texture3D", // Texture3D
  471. "TextureCube", // TextureCube
  472. "Texture1DArray", // Texture1DArray
  473. "Texture2DArray", // Texture2DArray
  474. "Texture2DMSArray", // Texture2DMSArray
  475. "TextureCubearray", // TextureCubearray
  476. "RawBuffer", // RawBuffer
  477. "StructuredBuffer", // StructuredBuffer
  478. };
  479. BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcSrvType) == DxbcResourceDim::Count);
  480. const char* s_dxbcInterpolationName[] =
  481. {
  482. "",
  483. "constant",
  484. "linear",
  485. "linear centroid",
  486. "linear noperspective",
  487. "linear noperspective centroid",
  488. "linear sample",
  489. "linear noperspective sample",
  490. };
  491. BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcInterpolationName) == DxbcInterpolation::Count);
  492. const char *s_dxbcPrimitiveTopologyName[] =
  493. {
  494. "",
  495. "PointList",
  496. "LineList",
  497. "LineStrip",
  498. "TriangleList",
  499. "TriangleStrip",
  500. "",
  501. "",
  502. "",
  503. "",
  504. "LineListAdj",
  505. "LineStripAdj",
  506. "TriangleListAdj",
  507. "TriangleStripAdj",
  508. };
  509. BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcPrimitiveTopologyName) == DxbcPrimitiveTopology::Count);
  510. const char *s_dxbcPrimitiveName[] = {
  511. "",
  512. "Point",
  513. "Line",
  514. "Triangle",
  515. "",
  516. "",
  517. "LineAdj",
  518. "TriangleAdj",
  519. "_1ControlPointPatch",
  520. "_2ControlPointPatch",
  521. "_3ControlPointPatch",
  522. "_4ControlPointPatch",
  523. "_5ControlPointPatch",
  524. "_6ControlPointPatch",
  525. "_7ControlPointPatch",
  526. "_8ControlPointPatch",
  527. "_9ControlPointPatch",
  528. "_10ControlPointPatch",
  529. "_11ControlPointPatch",
  530. "_12ControlPointPatch",
  531. "_13ControlPointPatch",
  532. "_14ControlPointPatch",
  533. "_15ControlPointPatch",
  534. "_16ControlPointPatch",
  535. "_17ControlPointPatch",
  536. "_18ControlPointPatch",
  537. "_19ControlPointPatch",
  538. "_20ControlPointPatch",
  539. "_21ControlPointPatch",
  540. "_22ControlPointPatch",
  541. "_23ControlPointPatch",
  542. "_24ControlPointPatch",
  543. "_25ControlPointPatch",
  544. "_26ControlPointPatch",
  545. "_27ControlPointPatch",
  546. "_28ControlPointPatch",
  547. "_29ControlPointPatch",
  548. "_30ControlPointPatch",
  549. "_31ControlPointPatch",
  550. "_32ControlPointPatch",
  551. };
  552. BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcPrimitiveName) == DxbcPrimitive::Count);
  553. // mesa/src/gallium/state_trackers/d3d1x/d3d1xshader/defs/shortfiles.txt
  554. static const char* s_dxbcOperandType[] =
  555. {
  556. "r", // Temp
  557. "v", // Input
  558. "o", // Output
  559. "x", // TempArray
  560. "l", // Imm32
  561. "d", // Imm64
  562. "s", // Sampler
  563. "t", // Resource
  564. "cb", // ConstantBuffer
  565. "icb", // ImmConstantBuffer
  566. "label", // Label
  567. "vPrim", // PrimitiveID
  568. "oDepth", // OutputDepth
  569. "null", // Null
  570. "rasterizer", // Rasterizer
  571. "oMask", // CoverageMask
  572. "stream", // Stream
  573. "function_body", // FunctionBody
  574. "function_table", // FunctionTable
  575. "interface", // Interface
  576. "function_input", // FunctionInput
  577. "function_output", // FunctionOutput
  578. "vOutputControlPointID", // OutputControlPointId
  579. "vForkInstanceID", // InputForkInstanceId
  580. "vJoinInstanceID", // InputJoinInstanceId
  581. "vicp", // InputControlPoint
  582. "vocp", // OutputControlPoint
  583. "vpc", // InputPatchConstant
  584. "vDomain", // InputDomainPoint
  585. "this", // ThisPointer
  586. "u", // UnorderedAccessView
  587. "g", // ThreadGroupSharedMemory
  588. "vThreadID", // InputThreadId
  589. "vThreadGrouID", // InputThreadGroupId
  590. "vThreadIDInGroup", // InputThreadIdInGroup
  591. "vCoverage", // InputCoverageMask
  592. "vThreadIDInGroupFlattened", // InputThreadIdInGroupFlattened
  593. "vGSInstanceID", // InputGsInstanceId
  594. "oDepthGE", // OutputDepthGreaterEqual
  595. "oDepthLE", // OutputDepthLessEqual
  596. "vCycleCounter", // CycleCounter
  597. };
  598. BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcOperandType) == DxbcOperandType::Count);
  599. static const char* s_dxbcCustomDataClass[] =
  600. {
  601. "Comment",
  602. "DebugInfo",
  603. "Opaque",
  604. "dcl_immediateConstantBuffer",
  605. "ShaderMessage",
  606. "ClipPlaneConstantMappingsForDx9",
  607. };
  608. BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcCustomDataClass) == DxbcCustomDataClass::Count);
  609. #define DXBC_MAX_NAME_STRING 512
  610. int32_t readString(bx::ReaderSeekerI* _reader, int64_t _offset, char* _out, uint32_t _max, bx::Error* _err)
  611. {
  612. int64_t oldOffset = bx::seek(_reader);
  613. bx::seek(_reader, _offset, bx::Whence::Begin);
  614. int32_t size = 0;
  615. for (uint32_t ii = 0; ii < _max-1; ++ii)
  616. {
  617. char ch;
  618. size += bx::read(_reader, ch, _err);
  619. *_out++ = ch;
  620. if ('\0' == ch)
  621. {
  622. break;
  623. }
  624. }
  625. *_out = '\0';
  626. bx::seek(_reader, oldOffset, bx::Whence::Begin);
  627. return size;
  628. }
  629. inline uint32_t dxbcMixF(uint32_t _b, uint32_t _c, uint32_t _d)
  630. {
  631. const uint32_t tmp0 = bx::uint32_xor(_c, _d);
  632. const uint32_t tmp1 = bx::uint32_and(_b, tmp0);
  633. const uint32_t result = bx::uint32_xor(_d, tmp1);
  634. return result;
  635. }
  636. inline uint32_t dxbcMixG(uint32_t _b, uint32_t _c, uint32_t _d)
  637. {
  638. return dxbcMixF(_d, _b, _c);
  639. }
  640. inline uint32_t dxbcMixH(uint32_t _b, uint32_t _c, uint32_t _d)
  641. {
  642. const uint32_t tmp0 = bx::uint32_xor(_b, _c);
  643. const uint32_t result = bx::uint32_xor(_d, tmp0);
  644. return result;
  645. }
  646. inline uint32_t dxbcMixI(uint32_t _b, uint32_t _c, uint32_t _d)
  647. {
  648. const uint32_t tmp0 = bx::uint32_orc(_b, _d);
  649. const uint32_t result = bx::uint32_xor(_c, tmp0);
  650. return result;
  651. }
  652. void dxbcHashBlock(const uint32_t* data, uint32_t* hash)
  653. {
  654. const uint32_t d0 = data[ 0];
  655. const uint32_t d1 = data[ 1];
  656. const uint32_t d2 = data[ 2];
  657. const uint32_t d3 = data[ 3];
  658. const uint32_t d4 = data[ 4];
  659. const uint32_t d5 = data[ 5];
  660. const uint32_t d6 = data[ 6];
  661. const uint32_t d7 = data[ 7];
  662. const uint32_t d8 = data[ 8];
  663. const uint32_t d9 = data[ 9];
  664. const uint32_t d10 = data[10];
  665. const uint32_t d11 = data[11];
  666. const uint32_t d12 = data[12];
  667. const uint32_t d13 = data[13];
  668. const uint32_t d14 = data[14];
  669. const uint32_t d15 = data[15];
  670. uint32_t aa = hash[0];
  671. uint32_t bb = hash[1];
  672. uint32_t cc = hash[2];
  673. uint32_t dd = hash[3];
  674. aa = bb + bx::uint32_rol(aa + dxbcMixF(bb, cc, dd) + d0 + 0xd76aa478, 7);
  675. dd = aa + bx::uint32_rol(dd + dxbcMixF(aa, bb, cc) + d1 + 0xe8c7b756, 12);
  676. cc = dd + bx::uint32_ror(cc + dxbcMixF(dd, aa, bb) + d2 + 0x242070db, 15);
  677. bb = cc + bx::uint32_ror(bb + dxbcMixF(cc, dd, aa) + d3 + 0xc1bdceee, 10);
  678. aa = bb + bx::uint32_rol(aa + dxbcMixF(bb, cc, dd) + d4 + 0xf57c0faf, 7);
  679. dd = aa + bx::uint32_rol(dd + dxbcMixF(aa, bb, cc) + d5 + 0x4787c62a, 12);
  680. cc = dd + bx::uint32_ror(cc + dxbcMixF(dd, aa, bb) + d6 + 0xa8304613, 15);
  681. bb = cc + bx::uint32_ror(bb + dxbcMixF(cc, dd, aa) + d7 + 0xfd469501, 10);
  682. aa = bb + bx::uint32_rol(aa + dxbcMixF(bb, cc, dd) + d8 + 0x698098d8, 7);
  683. dd = aa + bx::uint32_rol(dd + dxbcMixF(aa, bb, cc) + d9 + 0x8b44f7af, 12);
  684. cc = dd + bx::uint32_ror(cc + dxbcMixF(dd, aa, bb) + d10 + 0xffff5bb1, 15);
  685. bb = cc + bx::uint32_ror(bb + dxbcMixF(cc, dd, aa) + d11 + 0x895cd7be, 10);
  686. aa = bb + bx::uint32_rol(aa + dxbcMixF(bb, cc, dd) + d12 + 0x6b901122, 7);
  687. dd = aa + bx::uint32_rol(dd + dxbcMixF(aa, bb, cc) + d13 + 0xfd987193, 12);
  688. cc = dd + bx::uint32_ror(cc + dxbcMixF(dd, aa, bb) + d14 + 0xa679438e, 15);
  689. bb = cc + bx::uint32_ror(bb + dxbcMixF(cc, dd, aa) + d15 + 0x49b40821, 10);
  690. aa = bb + bx::uint32_rol(aa + dxbcMixG(bb, cc, dd) + d1 + 0xf61e2562, 5);
  691. dd = aa + bx::uint32_rol(dd + dxbcMixG(aa, bb, cc) + d6 + 0xc040b340, 9);
  692. cc = dd + bx::uint32_rol(cc + dxbcMixG(dd, aa, bb) + d11 + 0x265e5a51, 14);
  693. bb = cc + bx::uint32_ror(bb + dxbcMixG(cc, dd, aa) + d0 + 0xe9b6c7aa, 12);
  694. aa = bb + bx::uint32_rol(aa + dxbcMixG(bb, cc, dd) + d5 + 0xd62f105d, 5);
  695. dd = aa + bx::uint32_rol(dd + dxbcMixG(aa, bb, cc) + d10 + 0x02441453, 9);
  696. cc = dd + bx::uint32_rol(cc + dxbcMixG(dd, aa, bb) + d15 + 0xd8a1e681, 14);
  697. bb = cc + bx::uint32_ror(bb + dxbcMixG(cc, dd, aa) + d4 + 0xe7d3fbc8, 12);
  698. aa = bb + bx::uint32_rol(aa + dxbcMixG(bb, cc, dd) + d9 + 0x21e1cde6, 5);
  699. dd = aa + bx::uint32_rol(dd + dxbcMixG(aa, bb, cc) + d14 + 0xc33707d6, 9);
  700. cc = dd + bx::uint32_rol(cc + dxbcMixG(dd, aa, bb) + d3 + 0xf4d50d87, 14);
  701. bb = cc + bx::uint32_ror(bb + dxbcMixG(cc, dd, aa) + d8 + 0x455a14ed, 12);
  702. aa = bb + bx::uint32_rol(aa + dxbcMixG(bb, cc, dd) + d13 + 0xa9e3e905, 5);
  703. dd = aa + bx::uint32_rol(dd + dxbcMixG(aa, bb, cc) + d2 + 0xfcefa3f8, 9);
  704. cc = dd + bx::uint32_rol(cc + dxbcMixG(dd, aa, bb) + d7 + 0x676f02d9, 14);
  705. bb = cc + bx::uint32_ror(bb + dxbcMixG(cc, dd, aa) + d12 + 0x8d2a4c8a, 12);
  706. aa = bb + bx::uint32_rol(aa + dxbcMixH(bb, cc, dd) + d5 + 0xfffa3942, 4);
  707. dd = aa + bx::uint32_rol(dd + dxbcMixH(aa, bb, cc) + d8 + 0x8771f681, 11);
  708. cc = dd + bx::uint32_rol(cc + dxbcMixH(dd, aa, bb) + d11 + 0x6d9d6122, 16);
  709. bb = cc + bx::uint32_ror(bb + dxbcMixH(cc, dd, aa) + d14 + 0xfde5380c, 9);
  710. aa = bb + bx::uint32_rol(aa + dxbcMixH(bb, cc, dd) + d1 + 0xa4beea44, 4);
  711. dd = aa + bx::uint32_rol(dd + dxbcMixH(aa, bb, cc) + d4 + 0x4bdecfa9, 11);
  712. cc = dd + bx::uint32_rol(cc + dxbcMixH(dd, aa, bb) + d7 + 0xf6bb4b60, 16);
  713. bb = cc + bx::uint32_ror(bb + dxbcMixH(cc, dd, aa) + d10 + 0xbebfbc70, 9);
  714. aa = bb + bx::uint32_rol(aa + dxbcMixH(bb, cc, dd) + d13 + 0x289b7ec6, 4);
  715. dd = aa + bx::uint32_rol(dd + dxbcMixH(aa, bb, cc) + d0 + 0xeaa127fa, 11);
  716. cc = dd + bx::uint32_rol(cc + dxbcMixH(dd, aa, bb) + d3 + 0xd4ef3085, 16);
  717. bb = cc + bx::uint32_ror(bb + dxbcMixH(cc, dd, aa) + d6 + 0x04881d05, 9);
  718. aa = bb + bx::uint32_rol(aa + dxbcMixH(bb, cc, dd) + d9 + 0xd9d4d039, 4);
  719. dd = aa + bx::uint32_rol(dd + dxbcMixH(aa, bb, cc) + d12 + 0xe6db99e5, 11);
  720. cc = dd + bx::uint32_rol(cc + dxbcMixH(dd, aa, bb) + d15 + 0x1fa27cf8, 16);
  721. bb = cc + bx::uint32_ror(bb + dxbcMixH(cc, dd, aa) + d2 + 0xc4ac5665, 9);
  722. aa = bb + bx::uint32_rol(aa + dxbcMixI(bb, cc, dd) + d0 + 0xf4292244, 6);
  723. dd = aa + bx::uint32_rol(dd + dxbcMixI(aa, bb, cc) + d7 + 0x432aff97, 10);
  724. cc = dd + bx::uint32_rol(cc + dxbcMixI(dd, aa, bb) + d14 + 0xab9423a7, 15);
  725. bb = cc + bx::uint32_ror(bb + dxbcMixI(cc, dd, aa) + d5 + 0xfc93a039, 11);
  726. aa = bb + bx::uint32_rol(aa + dxbcMixI(bb, cc, dd) + d12 + 0x655b59c3, 6);
  727. dd = aa + bx::uint32_rol(dd + dxbcMixI(aa, bb, cc) + d3 + 0x8f0ccc92, 10);
  728. cc = dd + bx::uint32_rol(cc + dxbcMixI(dd, aa, bb) + d10 + 0xffeff47d, 15);
  729. bb = cc + bx::uint32_ror(bb + dxbcMixI(cc, dd, aa) + d1 + 0x85845dd1, 11);
  730. aa = bb + bx::uint32_rol(aa + dxbcMixI(bb, cc, dd) + d8 + 0x6fa87e4f, 6);
  731. dd = aa + bx::uint32_rol(dd + dxbcMixI(aa, bb, cc) + d15 + 0xfe2ce6e0, 10);
  732. cc = dd + bx::uint32_rol(cc + dxbcMixI(dd, aa, bb) + d6 + 0xa3014314, 15);
  733. bb = cc + bx::uint32_ror(bb + dxbcMixI(cc, dd, aa) + d13 + 0x4e0811a1, 11);
  734. aa = bb + bx::uint32_rol(aa + dxbcMixI(bb, cc, dd) + d4 + 0xf7537e82, 6);
  735. dd = aa + bx::uint32_rol(dd + dxbcMixI(aa, bb, cc) + d11 + 0xbd3af235, 10);
  736. cc = dd + bx::uint32_rol(cc + dxbcMixI(dd, aa, bb) + d2 + 0x2ad7d2bb, 15);
  737. bb = cc + bx::uint32_ror(bb + dxbcMixI(cc, dd, aa) + d9 + 0xeb86d391, 11);
  738. hash[0] += aa;
  739. hash[1] += bb;
  740. hash[2] += cc;
  741. hash[3] += dd;
  742. }
  743. // dxbc hash function is slightly modified version of MD5 hash.
  744. // https://web.archive.org/web/20190207230524/https://tools.ietf.org/html/rfc1321
  745. // https://web.archive.org/web/20190207230538/http://www.efgh.com/software/md5.txt
  746. //
  747. // Assumption is that data pointer, size are both 4-byte aligned,
  748. // and little endian.
  749. //
  750. void dxbcHash(const void* _data, uint32_t _size, void* _digest)
  751. {
  752. uint32_t hash[4] =
  753. {
  754. 0x67452301,
  755. 0xefcdab89,
  756. 0x98badcfe,
  757. 0x10325476,
  758. };
  759. const uint32_t* data = (const uint32_t*)_data;
  760. for (uint32_t ii = 0, num = _size/64; ii < num; ++ii)
  761. {
  762. dxbcHashBlock(data, hash);
  763. data += 16;
  764. }
  765. uint32_t last[16];
  766. bx::memSet(last, 0, sizeof(last) );
  767. const uint32_t remaining = _size & 0x3f;
  768. if (remaining >= 56)
  769. {
  770. bx::memCopy(&last[0], data, remaining);
  771. last[remaining/4] = 0x80;
  772. dxbcHashBlock(last, hash);
  773. bx::memSet(&last[1], 0, 56);
  774. }
  775. else
  776. {
  777. bx::memCopy(&last[1], data, remaining);
  778. last[1 + remaining/4] = 0x80;
  779. }
  780. last[ 0] = _size * 8;
  781. last[15] = _size * 2 + 1;
  782. dxbcHashBlock(last, hash);
  783. bx::memCopy(_digest, hash, 16);
  784. }
  785. int32_t read(bx::ReaderI* _reader, DxbcSubOperand& _subOperand, bx::Error* _err)
  786. {
  787. uint32_t token;
  788. int32_t size = 0;
  789. // 0 1 2 3
  790. // 76543210765432107654321076543210
  791. // e222111000nnttttttttssssssssmmoo
  792. // ^^ ^ ^ ^ ^ ^ ^ ^-- number of operands
  793. // || | | | | | +---- operand mode
  794. // || | | | | +------------ operand mode bits
  795. // || | | | +-------------------- type
  796. // || | | +---------------------- number of addressing modes
  797. // || | +------------------------- addressing mode 0
  798. // || +---------------------------- addressing mode 1
  799. // |+------------------------------- addressing mode 2
  800. // +-------------------------------- extended
  801. size += bx::read(_reader, token, _err);
  802. _subOperand.type = DxbcOperandType::Enum( (token & UINT32_C(0x000ff000) ) >> 12);
  803. _subOperand.numAddrModes = uint8_t( (token & UINT32_C(0x00300000) ) >> 20);
  804. _subOperand.addrMode = uint8_t( (token & UINT32_C(0x01c00000) ) >> 22);
  805. _subOperand.mode = DxbcOperandMode::Enum( (token & UINT32_C(0x0000000c) ) >> 2);
  806. _subOperand.modeBits = uint8_t( (token & UINT32_C(0x00000ff0) ) >> 4) & "\x0f\xff\x03\x00"[_subOperand.mode];
  807. _subOperand.num = uint8_t( (token & UINT32_C(0x00000003) ) );
  808. switch (_subOperand.addrMode)
  809. {
  810. case DxbcOperandAddrMode::Imm32:
  811. size += bx::read(_reader, _subOperand.regIndex, _err);
  812. break;
  813. case DxbcOperandAddrMode::Reg:
  814. {
  815. DxbcSubOperand subOperand;
  816. size += read(_reader, subOperand, _err);
  817. }
  818. break;
  819. case DxbcOperandAddrMode::RegImm32:
  820. {
  821. size += bx::read(_reader, _subOperand.regIndex, _err);
  822. DxbcSubOperand subOperand;
  823. size += read(_reader, subOperand, _err);
  824. }
  825. break;
  826. case DxbcOperandAddrMode::RegImm64:
  827. {
  828. size += bx::read(_reader, _subOperand.regIndex, _err);
  829. size += bx::read(_reader, _subOperand.regIndex, _err);
  830. DxbcSubOperand subOperand;
  831. size += read(_reader, subOperand, _err);
  832. }
  833. break;
  834. default:
  835. BX_ASSERT(false, "sub operand addressing mode %d", _subOperand.addrMode);
  836. break;
  837. }
  838. return size;
  839. }
  840. int32_t write(bx::WriterI* _writer, const DxbcSubOperand& _subOperand, bx::Error* _err)
  841. {
  842. int32_t size = 0;
  843. uint32_t token = 0;
  844. token |= (_subOperand.type << 12) & UINT32_C(0x000ff000);
  845. token |= (_subOperand.numAddrModes << 20) & UINT32_C(0x00300000);
  846. token |= (_subOperand.addrMode << 22) & UINT32_C(0x01c00000);
  847. token |= (_subOperand.mode << 2) & UINT32_C(0x0000000c);
  848. token |= (_subOperand.modeBits << 4) & UINT32_C(0x00000ff0);
  849. token |= _subOperand.num & UINT32_C(0x00000003);
  850. size += bx::write(_writer, token, _err);
  851. switch (_subOperand.addrMode)
  852. {
  853. case DxbcOperandAddrMode::Imm32:
  854. size += bx::write(_writer, _subOperand.regIndex, _err);
  855. break;
  856. case DxbcOperandAddrMode::Reg:
  857. {
  858. DxbcSubOperand subOperand;
  859. size += write(_writer, subOperand, _err);
  860. }
  861. break;
  862. case DxbcOperandAddrMode::RegImm32:
  863. {
  864. size += bx::write(_writer, _subOperand.regIndex, _err);
  865. DxbcSubOperand subOperand;
  866. size += write(_writer, subOperand, _err);
  867. }
  868. break;
  869. case DxbcOperandAddrMode::RegImm64:
  870. {
  871. size += bx::write(_writer, _subOperand.regIndex, _err);
  872. size += bx::write(_writer, _subOperand.regIndex, _err);
  873. DxbcSubOperand subOperand;
  874. size += write(_writer, subOperand, _err);
  875. }
  876. break;
  877. default:
  878. BX_ASSERT(false, "sub operand addressing mode %d", _subOperand.addrMode);
  879. break;
  880. }
  881. return size;
  882. }
  883. int32_t read(bx::ReaderI* _reader, DxbcOperand& _operand, bx::Error* _err)
  884. {
  885. int32_t size = 0;
  886. uint32_t token;
  887. size += bx::read(_reader, token, _err);
  888. // 0 1 2 3
  889. // 76543210765432107654321076543210
  890. // e222111000nnttttttttssssssssmmoo
  891. // ^^ ^ ^ ^ ^ ^ ^ ^-- number of operands
  892. // || | | | | | +---- operand mode
  893. // || | | | | +------------ operand mode bits
  894. // || | | | +-------------------- type
  895. // || | | +---------------------- number of addressing modes
  896. // || | +------------------------- addressing mode 0
  897. // || +---------------------------- addressing mode 1
  898. // |+------------------------------- addressing mode 2
  899. // +-------------------------------- extended
  900. _operand.numAddrModes = uint8_t( (token & UINT32_C(0x00300000) ) >> 20);
  901. _operand.addrMode[0] = uint8_t( (token & UINT32_C(0x01c00000) ) >> 22);
  902. _operand.addrMode[1] = uint8_t( (token & UINT32_C(0x0e000000) ) >> 25);
  903. _operand.addrMode[2] = uint8_t( (token & UINT32_C(0x70000000) ) >> 28);
  904. _operand.type = DxbcOperandType::Enum( (token & UINT32_C(0x000ff000) ) >> 12);
  905. _operand.mode = DxbcOperandMode::Enum( (token & UINT32_C(0x0000000c) ) >> 2);
  906. _operand.modeBits = uint8_t( (token & UINT32_C(0x00000ff0) ) >> 4) & "\x0f\xff\x03\x00"[_operand.mode];
  907. _operand.num = uint8_t( (token & UINT32_C(0x00000003) ) );
  908. const bool extended = 0 != (token & UINT32_C(0x80000000) );
  909. if (extended)
  910. {
  911. uint32_t extBits = 0;
  912. size += bx::read(_reader, extBits, _err);
  913. _operand.modifier = DxbcOperandModifier::Enum( (extBits & UINT32_C(0x00003fc0) ) >> 6);
  914. }
  915. else
  916. {
  917. _operand.modifier = DxbcOperandModifier::None;
  918. }
  919. switch (_operand.type)
  920. {
  921. case DxbcOperandType::Imm32:
  922. _operand.num = 2 == _operand.num ? 4 : _operand.num;
  923. for (uint32_t ii = 0; ii < _operand.num; ++ii)
  924. {
  925. size += bx::read(_reader, _operand.un.imm32[ii], _err);
  926. }
  927. break;
  928. case DxbcOperandType::Imm64:
  929. _operand.num = 2 == _operand.num ? 4 : _operand.num;
  930. for (uint32_t ii = 0; ii < _operand.num; ++ii)
  931. {
  932. size += bx::read(_reader, _operand.un.imm64[ii], _err);
  933. }
  934. break;
  935. default:
  936. break;
  937. }
  938. for (uint32_t ii = 0; ii < _operand.numAddrModes; ++ii)
  939. {
  940. switch (_operand.addrMode[ii])
  941. {
  942. case DxbcOperandAddrMode::Imm32:
  943. size += bx::read(_reader, _operand.regIndex[ii], _err);
  944. break;
  945. case DxbcOperandAddrMode::Reg:
  946. size += read(_reader, _operand.subOperand[ii], _err);
  947. break;
  948. case DxbcOperandAddrMode::RegImm32:
  949. size += bx::read(_reader, _operand.regIndex[ii], _err);
  950. size += read(_reader, _operand.subOperand[ii], _err);
  951. break;
  952. default:
  953. BX_ASSERT(false, "operand %d addressing mode %d", ii, _operand.addrMode[ii]);
  954. break;
  955. }
  956. }
  957. return size;
  958. }
  959. int32_t write(bx::WriterI* _writer, const DxbcOperand& _operand, bx::Error* _err)
  960. {
  961. int32_t size = 0;
  962. const bool extended = _operand.modifier != DxbcOperandModifier::None;
  963. uint32_t token = 0;
  964. token |= extended ? UINT32_C(0x80000000) : 0;
  965. token |= (_operand.numAddrModes << 20) & UINT32_C(0x00300000);
  966. token |= (_operand.addrMode[0] << 22) & UINT32_C(0x01c00000);
  967. token |= (_operand.addrMode[1] << 25) & UINT32_C(0x0e000000);
  968. token |= (_operand.addrMode[2] << 28) & UINT32_C(0x70000000);
  969. token |= (_operand.type << 12) & UINT32_C(0x000ff000);
  970. token |= (_operand.mode << 2) & UINT32_C(0x0000000c);
  971. token |= (4 == _operand.num ? 2 : _operand.num) & UINT32_C(0x00000003);
  972. token |= ( (_operand.modeBits & "\x0f\xff\x03\x00"[_operand.mode]) << 4) & UINT32_C(0x00000ff0);
  973. size += bx::write(_writer, token, _err);
  974. if (extended)
  975. {
  976. uint32_t extBits = 0
  977. | ( (_operand.modifier << 6) & UINT32_C(0x00003fc0) )
  978. | 1 /* 1 == has extended operand modifier */
  979. ;
  980. size += bx::write(_writer, extBits, _err);
  981. }
  982. switch (_operand.type)
  983. {
  984. case DxbcOperandType::Imm32:
  985. for (uint32_t ii = 0; ii < _operand.num; ++ii)
  986. {
  987. size += bx::write(_writer, _operand.un.imm32[ii], _err);
  988. }
  989. break;
  990. case DxbcOperandType::Imm64:
  991. for (uint32_t ii = 0; ii < _operand.num; ++ii)
  992. {
  993. size += bx::write(_writer, _operand.un.imm64[ii], _err);
  994. }
  995. break;
  996. default:
  997. break;
  998. }
  999. for (uint32_t ii = 0, num = bx::uint32_min(_operand.numAddrModes, BX_COUNTOF(_operand.addrMode) ); ii < num; ++ii)
  1000. {
  1001. switch (_operand.addrMode[ii])
  1002. {
  1003. case DxbcOperandAddrMode::Imm32:
  1004. size += bx::write(_writer, _operand.regIndex[ii], _err);
  1005. break;
  1006. case DxbcOperandAddrMode::Reg:
  1007. size += write(_writer, _operand.subOperand[ii], _err);
  1008. break;
  1009. case DxbcOperandAddrMode::RegImm32:
  1010. size += bx::write(_writer, _operand.regIndex[ii], _err);
  1011. size += write(_writer, _operand.subOperand[ii], _err);
  1012. break;
  1013. default:
  1014. BX_ASSERT(false, "operand %d addressing mode %d", ii, _operand.addrMode[ii]);
  1015. break;
  1016. }
  1017. }
  1018. return size;
  1019. }
  1020. int32_t read(bx::ReaderI* _reader, DxbcInstruction& _instruction, bx::Error* _err)
  1021. {
  1022. int32_t size = 0;
  1023. uint32_t token;
  1024. size += bx::read(_reader, token, _err);
  1025. // 0 1 2 3
  1026. // 76543210765432107654321076543210
  1027. // elllllll.............ooooooooooo
  1028. // ^^ ^----------- opcode
  1029. // |+------------------------------- length
  1030. // +-------------------------------- extended
  1031. _instruction.opcode = DxbcOpcode::Enum( (token & UINT32_C(0x000007ff) ) );
  1032. BX_ASSERT(_instruction.opcode < DxbcOpcode::Enum::Count, "unknown opcode");
  1033. _instruction.length = uint8_t( (token & UINT32_C(0x7f000000) ) >> 24);
  1034. bool extended = 0 != (token & UINT32_C(0x80000000) );
  1035. _instruction.srv = DxbcResourceDim::Unknown;
  1036. _instruction.samples = 0;
  1037. _instruction.shadow = false;
  1038. _instruction.mono = false;
  1039. _instruction.allowRefactoring = false;
  1040. _instruction.fp64 = false;
  1041. _instruction.earlyDepth = false;
  1042. _instruction.enableBuffers = false;
  1043. _instruction.skipOptimization = false;
  1044. _instruction.enableMinPrecision = false;
  1045. _instruction.enableDoubleExtensions = false;
  1046. _instruction.enableShaderExtensions = false;
  1047. _instruction.threadsInGroup = false;
  1048. _instruction.sharedMemory = false;
  1049. _instruction.uavGroup = false;
  1050. _instruction.uavGlobal = false;
  1051. _instruction.saturate = false;
  1052. _instruction.testNZ = false;
  1053. _instruction.retType = DxbcResourceReturnType::Unused;
  1054. _instruction.customDataClass = DxbcCustomDataClass::Comment;
  1055. _instruction.customData.clear();
  1056. switch (_instruction.opcode)
  1057. {
  1058. case DxbcOpcode::CUSTOMDATA:
  1059. {
  1060. _instruction.customDataClass = DxbcCustomDataClass::Enum( (token & UINT32_C(0xfffff800) ) >> 11);
  1061. _instruction.numOperands = 0;
  1062. size += bx::read(_reader, _instruction.length, _err);
  1063. for (uint32_t ii = 0, num = (_instruction.length-2); ii < num && _err->isOk(); ++ii)
  1064. {
  1065. uint32_t temp;
  1066. size += bx::read(_reader, temp, _err);
  1067. if (_err->isOk() )
  1068. {
  1069. _instruction.customData.push_back(temp);
  1070. }
  1071. }
  1072. }
  1073. return size;
  1074. case DxbcOpcode::DCL_CONSTANT_BUFFER:
  1075. // 0 1 2 3
  1076. // 76543210765432107654321076543210
  1077. // ........ a...........
  1078. // ^------------ Allow refactoring
  1079. _instruction.allowRefactoring = 0 != (token & UINT32_C(0x00000800) );
  1080. break;
  1081. case DxbcOpcode::DCL_GLOBAL_FLAGS:
  1082. // 0 1 2 3
  1083. // 76543210765432107654321076543210
  1084. // ........ sxmoudfa...........
  1085. // ^^^^^^^^------------ Allow refactoring
  1086. // ||||||+------------- FP64
  1087. // |||||+-------------- Force early depth/stencil
  1088. // ||||+--------------- Enable raw and structured buffers
  1089. // |||+---------------- Skip optimizations
  1090. // ||+----------------- Enable minimum precision
  1091. // |+------------------ Enable double extension
  1092. // +------------------- Enable shader extension
  1093. _instruction.allowRefactoring = 0 != (token & UINT32_C(0x00000800) );
  1094. _instruction.fp64 = 0 != (token & UINT32_C(0x00001000) );
  1095. _instruction.earlyDepth = 0 != (token & UINT32_C(0x00002000) );
  1096. _instruction.enableBuffers = 0 != (token & UINT32_C(0x00004000) );
  1097. _instruction.skipOptimization = 0 != (token & UINT32_C(0x00008000) );
  1098. _instruction.enableMinPrecision = 0 != (token & UINT32_C(0x00010000) );
  1099. _instruction.enableDoubleExtensions = 0 != (token & UINT32_C(0x00020000) );
  1100. _instruction.enableShaderExtensions = 0 != (token & UINT32_C(0x00040000) );
  1101. break;
  1102. case DxbcOpcode::DCL_GS_INPUT_PRIMITIVE:
  1103. // 0 1 2 3
  1104. // 76543210765432107654321076543210
  1105. // ........ pppppp...........
  1106. // ^----------------- Primitive
  1107. _instruction.primitive = DxbcPrimitive::Enum( (token & UINT32_C(0x0001f800) ) >> 11);
  1108. break;
  1109. case DxbcOpcode::DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY:
  1110. // 0 1 2 3
  1111. // 76543210765432107654321076543210
  1112. // ........ pppppp...........
  1113. // ^----------------- Primitive Topology
  1114. _instruction.primitiveTopology = DxbcPrimitiveTopology::Enum( (token & UINT32_C(0x0001f800) ) >> 11);
  1115. break;
  1116. case DxbcOpcode::DCL_INPUT_PS: [[fallthrough]];
  1117. case DxbcOpcode::DCL_INPUT_PS_SIV:
  1118. // 0 1 2 3
  1119. // 76543210765432107654321076543210
  1120. // ........ iiiii...........
  1121. // ^---------------- Interpolation
  1122. _instruction.interpolation = DxbcInterpolation::Enum( (token & UINT32_C(0x0000f800) ) >> 11);
  1123. break;
  1124. case DxbcOpcode::DCL_RESOURCE:
  1125. // 0 1 2 3
  1126. // 76543210765432107654321076543210
  1127. // ........ sssssssrrrrr...........
  1128. // ^ ^---------------- SRV
  1129. // +----------------------- MSAA samples
  1130. _instruction.srv = DxbcResourceDim::Enum( (token & UINT32_C(0x0000f800) ) >> 11);
  1131. _instruction.samples = uint8_t( (token & UINT32_C(0x007f0000) ) >> 16);
  1132. break;
  1133. case DxbcOpcode::DCL_SAMPLER:
  1134. // 0 1 2 3
  1135. // 76543210765432107654321076543210
  1136. // ........ ms...........
  1137. // ^^------------ Shadow sampler
  1138. // +------------- Mono
  1139. _instruction.shadow = 0 != (token & UINT32_C(0x00000800) );
  1140. _instruction.mono = 0 != (token & UINT32_C(0x00001000) );
  1141. break;
  1142. case DxbcOpcode::SYNC:
  1143. // 0 1 2 3
  1144. // 76543210765432107654321076543210
  1145. // ........ gust...........
  1146. // ^^^^------------ Threads in group
  1147. // ||+------------- Shared memory
  1148. // |+-------------- UAV group
  1149. // +--------------- UAV global
  1150. _instruction.threadsInGroup = 0 != (token & UINT32_C(0x00000800) );
  1151. _instruction.sharedMemory = 0 != (token & UINT32_C(0x00001000) );
  1152. _instruction.uavGroup = 0 != (token & UINT32_C(0x00002000) );
  1153. _instruction.uavGlobal = 0 != (token & UINT32_C(0x00004000) );
  1154. break;
  1155. default:
  1156. // 0 1 2 3
  1157. // 76543210765432107654321076543210
  1158. // ........ ppppn stt...........
  1159. // ^ ^ ^^------------- Resource info return type
  1160. // | | +-------------- Saturate
  1161. // | +------------------- Test not zero
  1162. // +----------------------- Precise mask
  1163. _instruction.retType = DxbcResourceReturnType::Enum( (token & UINT32_C(0x00001800) ) >> 11);
  1164. _instruction.saturate = 0 != (token & UINT32_C(0x00002000) );
  1165. _instruction.testNZ = 0 != (token & UINT32_C(0x00040000) );
  1166. // _instruction.precise = uint8_t( (token & UINT32_C(0x00780000) ) >> 19);
  1167. break;
  1168. }
  1169. _instruction.extended[0] = DxbcInstruction::ExtendedType::Count;
  1170. for (uint32_t ii = 0; extended; ++ii)
  1171. {
  1172. // 0 1 2 3
  1173. // 76543210765432107654321076543210
  1174. // e..........................ttttt
  1175. // ^ ^
  1176. // | +----- type
  1177. // +-------------------------------- extended
  1178. uint32_t extBits;
  1179. size += bx::read(_reader, extBits, _err);
  1180. extended = 0 != (extBits & UINT32_C(0x80000000) );
  1181. _instruction.extended[ii ] = DxbcInstruction::ExtendedType::Enum(extBits & UINT32_C(0x0000001f) );
  1182. _instruction.extended[ii+1] = DxbcInstruction::ExtendedType::Count;
  1183. switch (_instruction.extended[ii])
  1184. {
  1185. case DxbcInstruction::ExtendedType::SampleControls:
  1186. // 0 1 2 3
  1187. // 76543210765432107654321076543210
  1188. // . zzzzyyyyxxxx .....
  1189. // ^ ^ ^
  1190. // | | +------------- x
  1191. // | +----------------- y
  1192. // +--------------------- z
  1193. _instruction.sampleOffsets[0] = uint8_t( (extBits & UINT32_C(0x00001e00) ) >> 9);
  1194. _instruction.sampleOffsets[1] = uint8_t( (extBits & UINT32_C(0x0001e000) ) >> 13);
  1195. _instruction.sampleOffsets[2] = uint8_t( (extBits & UINT32_C(0x001e0000) ) >> 17);
  1196. break;
  1197. case DxbcInstruction::ExtendedType::ResourceDim:
  1198. // 0 1 2 3
  1199. // 76543210765432107654321076543210
  1200. // . .....
  1201. //
  1202. _instruction.resourceTarget = uint8_t( (extBits & UINT32_C(0x000003e0) ) >> 6);
  1203. _instruction.resourceStride = uint8_t( (extBits & UINT32_C(0x0000f800) ) >> 11);
  1204. break;
  1205. case DxbcInstruction::ExtendedType::ResourceReturnType:
  1206. // 0 1 2 3
  1207. // 76543210765432107654321076543210
  1208. // . 3333222211110000.....
  1209. // ^ ^ ^
  1210. // | | +------------- x
  1211. // | +----------------- y
  1212. // +--------------------- z
  1213. _instruction.resourceReturnTypes[0] = DxbcResourceReturnType::Enum( (extBits & UINT32_C(0x000001e0) ) >> 6);
  1214. _instruction.resourceReturnTypes[1] = DxbcResourceReturnType::Enum( (extBits & UINT32_C(0x00001e00) ) >> 9);
  1215. _instruction.resourceReturnTypes[2] = DxbcResourceReturnType::Enum( (extBits & UINT32_C(0x0001e000) ) >> 13);
  1216. _instruction.resourceReturnTypes[3] = DxbcResourceReturnType::Enum( (extBits & UINT32_C(0x001e0000) ) >> 17);
  1217. break;
  1218. default:
  1219. break;
  1220. }
  1221. }
  1222. switch (_instruction.opcode)
  1223. {
  1224. case DxbcOpcode::DCL_FUNCTION_TABLE:
  1225. {
  1226. uint32_t tableId;
  1227. size += read(_reader, tableId, _err);
  1228. uint32_t num;
  1229. size += read(_reader, num, _err);
  1230. for (uint32_t ii = 0; ii < num; ++ii)
  1231. {
  1232. uint32_t bodyId;
  1233. size += read(_reader, bodyId, _err);
  1234. }
  1235. }
  1236. break;
  1237. case DxbcOpcode::DCL_INTERFACE:
  1238. {
  1239. uint32_t interfaceId;
  1240. size += read(_reader, interfaceId, _err);
  1241. uint32_t num;
  1242. size += read(_reader, num, _err);
  1243. BX_ASSERT(false, "not implemented.");
  1244. }
  1245. break;
  1246. default:
  1247. break;
  1248. };
  1249. uint32_t currOp = 0;
  1250. const DxbcOpcodeInfo& info = s_dxbcOpcodeInfo[_instruction.opcode];
  1251. _instruction.numOperands = info.numOperands;
  1252. switch (info.numOperands)
  1253. {
  1254. case 6: size += read(_reader, _instruction.operand[currOp++], _err); [[fallthrough]];
  1255. case 5: size += read(_reader, _instruction.operand[currOp++], _err); [[fallthrough]];
  1256. case 4: size += read(_reader, _instruction.operand[currOp++], _err); [[fallthrough]];
  1257. case 3: size += read(_reader, _instruction.operand[currOp++], _err); [[fallthrough]];
  1258. case 2: size += read(_reader, _instruction.operand[currOp++], _err); [[fallthrough]];
  1259. case 1: size += read(_reader, _instruction.operand[currOp++], _err); [[fallthrough]];
  1260. case 0:
  1261. if (0 < info.numValues)
  1262. {
  1263. size += read(_reader, _instruction.value, info.numValues*sizeof(uint32_t), _err);
  1264. }
  1265. break;
  1266. default:
  1267. BX_ASSERT(false, "Instruction %s with invalid number of operands %d (numValues %d)."
  1268. , getName(_instruction.opcode)
  1269. , info.numOperands
  1270. , info.numValues
  1271. );
  1272. break;
  1273. }
  1274. return size;
  1275. }
  1276. int32_t write(bx::WriterI* _writer, const DxbcInstruction& _instruction, bx::Error* _err)
  1277. {
  1278. uint32_t token = 0;
  1279. token |= (_instruction.opcode ) & UINT32_C(0x000007ff);
  1280. token |= (_instruction.length << 24) & UINT32_C(0x7f000000);
  1281. token |= DxbcInstruction::ExtendedType::Count != _instruction.extended[0]
  1282. ? UINT32_C(0x80000000)
  1283. : 0
  1284. ;
  1285. int32_t size =0;
  1286. switch (_instruction.opcode)
  1287. {
  1288. case DxbcOpcode::CUSTOMDATA:
  1289. {
  1290. token &= UINT32_C(0x000007ff);
  1291. token |= _instruction.customDataClass << 11;
  1292. size += bx::write(_writer, token, _err);
  1293. uint32_t len = uint32_t(_instruction.customData.size()*sizeof(uint32_t) );
  1294. size += bx::write(_writer, len/4+2, _err);
  1295. size += bx::write(_writer, _instruction.customData.data(), len, _err);
  1296. }
  1297. return size;
  1298. case DxbcOpcode::DCL_CONSTANT_BUFFER:
  1299. token |= _instruction.allowRefactoring ? UINT32_C(0x00000800) : 0;
  1300. break;
  1301. case DxbcOpcode::DCL_GLOBAL_FLAGS:
  1302. token |= _instruction.allowRefactoring ? UINT32_C(0x00000800) : 0;
  1303. token |= _instruction.fp64 ? UINT32_C(0x00001000) : 0;
  1304. token |= _instruction.earlyDepth ? UINT32_C(0x00002000) : 0;
  1305. token |= _instruction.enableBuffers ? UINT32_C(0x00004000) : 0;
  1306. token |= _instruction.skipOptimization ? UINT32_C(0x00008000) : 0;
  1307. token |= _instruction.enableMinPrecision ? UINT32_C(0x00010000) : 0;
  1308. token |= _instruction.enableDoubleExtensions ? UINT32_C(0x00020000) : 0;
  1309. token |= _instruction.enableShaderExtensions ? UINT32_C(0x00040000) : 0;
  1310. break;
  1311. case DxbcOpcode::DCL_GS_INPUT_PRIMITIVE:
  1312. token |= (_instruction.primitive << 11) & UINT32_C(0x0001f800);
  1313. break;
  1314. case DxbcOpcode::DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY:
  1315. token |= (_instruction.primitiveTopology << 11) & UINT32_C(0x0001f800);
  1316. break;
  1317. case DxbcOpcode::DCL_INPUT_PS: [[fallthrough]];
  1318. case DxbcOpcode::DCL_INPUT_PS_SIV:
  1319. token |= (_instruction.interpolation << 11) & UINT32_C(0x0000f800);
  1320. break;
  1321. case DxbcOpcode::DCL_RESOURCE:
  1322. token |= (_instruction.srv << 11) & UINT32_C(0x0000f800);
  1323. token |= (_instruction.samples << 16) & UINT32_C(0x007f0000);
  1324. break;
  1325. case DxbcOpcode::DCL_SAMPLER:
  1326. token |= _instruction.shadow ? (0x00000800) : 0;
  1327. token |= _instruction.mono ? (0x00001000) : 0;
  1328. break;
  1329. case DxbcOpcode::SYNC:
  1330. token |= _instruction.threadsInGroup ? UINT32_C(0x00000800) : 0;
  1331. token |= _instruction.sharedMemory ? UINT32_C(0x00001000) : 0;
  1332. token |= _instruction.uavGroup ? UINT32_C(0x00002000) : 0;
  1333. token |= _instruction.uavGlobal ? UINT32_C(0x00004000) : 0;
  1334. break;
  1335. default:
  1336. token |= (_instruction.retType << 11) & UINT32_C(0x00001800);
  1337. token |= _instruction.saturate ? UINT32_C(0x00002000) : 0;
  1338. token |= _instruction.testNZ ? UINT32_C(0x00040000) : 0;
  1339. // _instruction.precise = uint8_t( (token & UINT32_C(0x00780000) ) >> 19);
  1340. break;
  1341. }
  1342. size += bx::write(_writer, token, _err);
  1343. for (uint32_t ii = 0; _instruction.extended[ii] != DxbcInstruction::ExtendedType::Count; ++ii)
  1344. {
  1345. // 0 1 2 3
  1346. // 76543210765432107654321076543210
  1347. // e..........................ttttt
  1348. // ^ ^
  1349. // | +----- type
  1350. // +-------------------------------- extended
  1351. token = _instruction.extended[ii+1] == DxbcInstruction::ExtendedType::Count
  1352. ? 0
  1353. : UINT32_C(0x80000000)
  1354. ;
  1355. token |= uint8_t(_instruction.extended[ii]);
  1356. switch (_instruction.extended[ii])
  1357. {
  1358. case DxbcInstruction::ExtendedType::SampleControls:
  1359. // 0 1 2 3
  1360. // 76543210765432107654321076543210
  1361. // . zzzzyyyyxxxx .....
  1362. // ^ ^ ^
  1363. // | | +------------- x
  1364. // | +----------------- y
  1365. // +--------------------- z
  1366. token |= (uint32_t(_instruction.sampleOffsets[0]) << 9) & UINT32_C(0x00001e00);
  1367. token |= (uint32_t(_instruction.sampleOffsets[1]) << 13) & UINT32_C(0x0001e000);
  1368. token |= (uint32_t(_instruction.sampleOffsets[2]) << 17) & UINT32_C(0x001e0000);
  1369. break;
  1370. case DxbcInstruction::ExtendedType::ResourceDim:
  1371. // 0 1 2 3
  1372. // 76543210765432107654321076543210
  1373. // . .....
  1374. //
  1375. token |= (uint32_t(_instruction.resourceTarget << 6) & UINT32_C(0x000003e0) );
  1376. token |= (uint32_t(_instruction.resourceStride << 11) & UINT32_C(0x0000f800) );
  1377. break;
  1378. case DxbcInstruction::ExtendedType::ResourceReturnType:
  1379. // 0 1 2 3
  1380. // 76543210765432107654321076543210
  1381. // . 3333222211110000.....
  1382. // ^ ^ ^
  1383. // | | +------------- x
  1384. // | +----------------- y
  1385. // +--------------------- z
  1386. token |= (uint32_t(_instruction.resourceReturnTypes[0]) << 6) & UINT32_C(0x000001e0);
  1387. token |= (uint32_t(_instruction.resourceReturnTypes[1]) << 9) & UINT32_C(0x00001e00);
  1388. token |= (uint32_t(_instruction.resourceReturnTypes[2]) << 13) & UINT32_C(0x0001e000);
  1389. token |= (uint32_t(_instruction.resourceReturnTypes[3]) << 17) & UINT32_C(0x001e0000);
  1390. break;
  1391. default:
  1392. break;
  1393. }
  1394. size += bx::write(_writer, token, _err);
  1395. }
  1396. for (uint32_t ii = 0; ii < _instruction.numOperands; ++ii)
  1397. {
  1398. size += write(_writer, _instruction.operand[ii], _err);
  1399. }
  1400. const DxbcOpcodeInfo& info = s_dxbcOpcodeInfo[_instruction.opcode];
  1401. if (0 < info.numValues)
  1402. {
  1403. size += bx::write(_writer, _instruction.value, info.numValues*sizeof(uint32_t), _err);
  1404. }
  1405. return size;
  1406. }
  1407. int32_t toString(char* _out, int32_t _size, DxbcOperandMode::Enum _mode, uint8_t _modeBits)
  1408. {
  1409. int32_t size = 0;
  1410. switch (_mode)
  1411. {
  1412. case DxbcOperandMode::Mask:
  1413. if (0xf > _modeBits
  1414. && 0 < _modeBits)
  1415. {
  1416. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1417. , ".%s%s%s%s"
  1418. , 0 == (_modeBits & 1) ? "" : "x"
  1419. , 0 == (_modeBits & 2) ? "" : "y"
  1420. , 0 == (_modeBits & 4) ? "" : "z"
  1421. , 0 == (_modeBits & 8) ? "" : "w"
  1422. );
  1423. }
  1424. break;
  1425. case DxbcOperandMode::Swizzle:
  1426. if (0xe4 != _modeBits)
  1427. {
  1428. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1429. , ".%c%c%c%c"
  1430. , "xyzw"[(_modeBits )&0x3]
  1431. , "xyzw"[(_modeBits>>2)&0x3]
  1432. , "xyzw"[(_modeBits>>4)&0x3]
  1433. , "xyzw"[(_modeBits>>6)&0x3]
  1434. );
  1435. }
  1436. break;
  1437. case DxbcOperandMode::Scalar:
  1438. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1439. , ".%c"
  1440. , "xyzw"[_modeBits]
  1441. );
  1442. break;
  1443. default:
  1444. break;
  1445. }
  1446. return size;
  1447. }
  1448. int32_t toString(char* _out, int32_t _size, const DxbcInstruction& _instruction)
  1449. {
  1450. int32_t size = 0;
  1451. switch (_instruction.opcode)
  1452. {
  1453. case DxbcOpcode::CUSTOMDATA:
  1454. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1455. , "%s"
  1456. , s_dxbcCustomDataClass[_instruction.customDataClass]
  1457. );
  1458. break;
  1459. case DxbcOpcode::DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY:
  1460. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1461. , "%s %s"
  1462. , getName(_instruction.opcode)
  1463. , s_dxbcPrimitiveTopologyName[_instruction.primitiveTopology]
  1464. );
  1465. break;
  1466. case DxbcOpcode::DCL_GS_INPUT_PRIMITIVE:
  1467. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1468. , "%s %s"
  1469. , getName(_instruction.opcode)
  1470. , s_dxbcPrimitiveName[_instruction.primitive]
  1471. );
  1472. break;
  1473. case DxbcOpcode::IF:
  1474. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1475. , "%s%s"
  1476. , getName(_instruction.opcode)
  1477. , _instruction.testNZ ? "_nz" : "_z"
  1478. );
  1479. break;
  1480. default:
  1481. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1482. , "%s%s%s"
  1483. , getName(_instruction.opcode)
  1484. , _instruction.saturate ? "_sat" : ""
  1485. , _instruction.testNZ ? "_nz" : ""
  1486. );
  1487. break;
  1488. }
  1489. if (DxbcResourceDim::Unknown != _instruction.srv)
  1490. {
  1491. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1492. , " %s<%x>"
  1493. , s_dxbcSrvType[_instruction.srv]
  1494. , _instruction.value[0]
  1495. );
  1496. }
  1497. else if (0 < s_dxbcOpcodeInfo[_instruction.opcode].numValues)
  1498. {
  1499. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1500. , " %d"
  1501. , _instruction.value[0]
  1502. );
  1503. }
  1504. for (uint32_t ii = 0; ii < _instruction.numOperands; ++ii)
  1505. {
  1506. const DxbcOperand& operand = _instruction.operand[ii];
  1507. const bool array = false
  1508. || 1 < operand.numAddrModes
  1509. || DxbcOperandAddrMode::Imm32 != operand.addrMode[0]
  1510. ;
  1511. const char* preOperand = "";
  1512. const char* postOperand = "";
  1513. switch (operand.modifier)
  1514. {
  1515. case DxbcOperandModifier::Neg: preOperand = "-"; postOperand = ""; break;
  1516. case DxbcOperandModifier::Abs: preOperand = "abs("; postOperand = ")"; break;
  1517. case DxbcOperandModifier::AbsNeg: preOperand = "-abs("; postOperand = ")"; break;
  1518. default: break;
  1519. }
  1520. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1521. , "%s%s%s"
  1522. , 0 == ii ? " " : ", "
  1523. , preOperand
  1524. , s_dxbcOperandType[operand.type]
  1525. );
  1526. switch (operand.type)
  1527. {
  1528. case DxbcOperandType::Imm32:
  1529. case DxbcOperandType::Imm64:
  1530. for (uint32_t jj = 0; jj < operand.num; ++jj)
  1531. {
  1532. union { uint32_t i; float f; } cast = { operand.un.imm32[jj] };
  1533. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1534. , "%s%f"
  1535. , 0 == jj ? "(" : ", "
  1536. , cast.f
  1537. );
  1538. }
  1539. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1540. , ")"
  1541. );
  1542. break;
  1543. default:
  1544. break;
  1545. }
  1546. const uint32_t first = false
  1547. || DxbcOperandType::ImmConstantBuffer == operand.type
  1548. || DxbcOperandAddrMode::RegImm32 == operand.addrMode[0]
  1549. ? 0 : 1
  1550. ;
  1551. if (0 == first)
  1552. {
  1553. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1554. , "["
  1555. );
  1556. }
  1557. else
  1558. {
  1559. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1560. , "%d%s"
  1561. , operand.regIndex[0]
  1562. , array ? "[" : ""
  1563. );
  1564. }
  1565. for (uint32_t jj = first, num = bx::uint32_min(operand.numAddrModes, BX_COUNTOF(operand.addrMode) ); jj < num; ++jj)
  1566. {
  1567. switch (operand.addrMode[jj])
  1568. {
  1569. case DxbcOperandAddrMode::Imm32:
  1570. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1571. , "%d"
  1572. , operand.regIndex[jj]
  1573. );
  1574. break;
  1575. case DxbcOperandAddrMode::Reg:
  1576. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1577. , "%s%d"
  1578. , s_dxbcOperandType[operand.subOperand[jj].type]
  1579. , operand.subOperand[jj].regIndex
  1580. );
  1581. size += toString(&_out[size], bx::uint32_imax(0, _size-size)
  1582. , DxbcOperandMode::Enum(operand.subOperand[jj].mode)
  1583. , operand.subOperand[jj].modeBits
  1584. );
  1585. break;
  1586. case DxbcOperandAddrMode::RegImm32:
  1587. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1588. , "%d + %s%d"
  1589. , operand.regIndex[jj]
  1590. , s_dxbcOperandType[operand.subOperand[jj].type]
  1591. , operand.subOperand[jj].regIndex
  1592. );
  1593. size += toString(&_out[size], bx::uint32_imax(0, _size-size)
  1594. , DxbcOperandMode::Enum(operand.subOperand[jj].mode)
  1595. , operand.subOperand[jj].modeBits
  1596. );
  1597. break;
  1598. default:
  1599. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size), "???");
  1600. break;
  1601. }
  1602. }
  1603. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1604. , "%s"
  1605. , array ? "]" : ""
  1606. );
  1607. size += toString(&_out[size], bx::uint32_imax(0, _size-size), operand.mode, operand.modeBits);
  1608. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1609. , "%s"
  1610. , postOperand
  1611. );
  1612. }
  1613. if (_instruction.opcode == DxbcOpcode::DCL_CONSTANT_BUFFER
  1614. && _instruction.allowRefactoring)
  1615. {
  1616. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1617. , ", dynamicIndexed"
  1618. );
  1619. }
  1620. return size;
  1621. }
  1622. int32_t read(bx::ReaderSeekerI* _reader, DxbcSignature& _signature, bx::Error* _err)
  1623. {
  1624. int32_t size = 0;
  1625. int64_t offset = bx::seek(_reader);
  1626. uint32_t num;
  1627. size += bx::read(_reader, num, _err);
  1628. size += bx::read(_reader, _signature.key, _err);
  1629. for (uint32_t ii = 0; ii < num; ++ii)
  1630. {
  1631. DxbcSignature::Element element;
  1632. uint32_t nameOffset;
  1633. size += bx::read(_reader, nameOffset, _err);
  1634. char name[DXBC_MAX_NAME_STRING];
  1635. readString(_reader, offset + nameOffset, name, DXBC_MAX_NAME_STRING, _err);
  1636. element.name = name;
  1637. size += bx::read(_reader, element.semanticIndex, _err);
  1638. size += bx::read(_reader, element.valueType, _err);
  1639. size += bx::read(_reader, element.componentType, _err);
  1640. size += bx::read(_reader, element.registerIndex, _err);
  1641. size += bx::read(_reader, element.mask, _err);
  1642. size += bx::read(_reader, element.readWriteMask, _err);
  1643. size += bx::read(_reader, element.stream, _err);
  1644. // padding
  1645. uint8_t padding;
  1646. size += bx::read(_reader, padding, _err);
  1647. _signature.elements.push_back(element);
  1648. }
  1649. return size;
  1650. }
  1651. int32_t write(bx::WriterI* _writer, const DxbcSignature& _signature, bx::Error* _err)
  1652. {
  1653. int32_t size = 0;
  1654. const uint32_t num = uint32_t(_signature.elements.size() );
  1655. size += bx::write(_writer, num, _err);
  1656. size += bx::write(_writer, _signature.key, _err);
  1657. typedef stl::unordered_map<stl::string, uint32_t> NameOffsetMap;
  1658. NameOffsetMap nom;
  1659. const uint8_t pad = 0;
  1660. uint32_t nameOffset = num * 24 + 8;
  1661. for (uint32_t ii = 0; ii < num; ++ii)
  1662. {
  1663. const DxbcSignature::Element& element = _signature.elements[ii];
  1664. NameOffsetMap::iterator it = nom.find(element.name);
  1665. if (it == nom.end() )
  1666. {
  1667. nom.insert(stl::make_pair(element.name, nameOffset) );
  1668. size += bx::write(_writer, nameOffset, _err);
  1669. nameOffset += uint32_t(element.name.size() + 1);
  1670. }
  1671. else
  1672. {
  1673. size += bx::write(_writer, it->second, _err);
  1674. }
  1675. size += bx::write(_writer, element.semanticIndex, _err);
  1676. size += bx::write(_writer, element.valueType, _err);
  1677. size += bx::write(_writer, element.componentType, _err);
  1678. size += bx::write(_writer, element.registerIndex, _err);
  1679. size += bx::write(_writer, element.mask, _err);
  1680. size += bx::write(_writer, element.readWriteMask, _err);
  1681. size += bx::write(_writer, element.stream, _err);
  1682. size += bx::write(_writer, pad, _err);
  1683. }
  1684. uint32_t len = 0;
  1685. for (uint32_t ii = 0; ii < num; ++ii)
  1686. {
  1687. const DxbcSignature::Element& element = _signature.elements[ii];
  1688. NameOffsetMap::iterator it = nom.find(element.name);
  1689. if (it != nom.end() )
  1690. {
  1691. nom.erase(it);
  1692. size += bx::write(_writer, element.name.c_str(), uint32_t(element.name.size() + 1), _err);
  1693. len += uint32_t(element.name.size() + 1);
  1694. }
  1695. }
  1696. // align 4 bytes
  1697. size += bx::writeRep(_writer, 0xab, (len+3)/4*4 - len, _err);
  1698. return size;
  1699. }
  1700. int32_t read(bx::ReaderSeekerI* _reader, DxbcShader& _shader, bx::Error* _err)
  1701. {
  1702. int32_t size = 0;
  1703. size += bx::read(_reader, _shader.version, _err);
  1704. uint32_t bcLength;
  1705. size += bx::read(_reader, bcLength, _err);
  1706. uint32_t len = (bcLength-2)*sizeof(uint32_t);
  1707. _shader.byteCode.resize(len);
  1708. size += bx::read(_reader, _shader.byteCode.data(), len, _err);
  1709. return size;
  1710. }
  1711. int32_t write(bx::WriterI* _writer, const DxbcShader& _shader, bx::Error* _err)
  1712. {
  1713. const uint32_t len = uint32_t(_shader.byteCode.size() );
  1714. const uint32_t bcLength = len / sizeof(uint32_t) + 2;
  1715. int32_t size = 0;
  1716. size += bx::write(_writer, _shader.version, _err);
  1717. size += bx::write(_writer, bcLength, _err);
  1718. size += bx::write(_writer, _shader.byteCode.data(), len, _err);
  1719. return size;
  1720. }
  1721. #define DXBC_CHUNK_SHADER BX_MAKEFOURCC('S', 'H', 'D', 'R')
  1722. #define DXBC_CHUNK_SHADER_EX BX_MAKEFOURCC('S', 'H', 'E', 'X')
  1723. #define DXBC_CHUNK_INPUT_SIGNATURE BX_MAKEFOURCC('I', 'S', 'G', 'N')
  1724. #define DXBC_CHUNK_OUTPUT_SIGNATURE BX_MAKEFOURCC('O', 'S', 'G', 'N')
  1725. #define DXBC_CHUNK_SFI0 BX_MAKEFOURCC('S', 'F', 'I', '0')
  1726. #define DXBC_CHUNK_SPDB BX_MAKEFOURCC('S', 'P', 'D', 'B')
  1727. #define DXBC_CHUNK_RDEF BX_MAKEFOURCC('R', 'D', 'E', 'F')
  1728. #define DXBC_CHUNK_STAT BX_MAKEFOURCC('S', 'T', 'A', 'T')
  1729. int32_t read(bx::ReaderSeekerI* _reader, DxbcContext& _dxbc, bx::Error* _err)
  1730. {
  1731. int32_t size = 0;
  1732. size += bx::read(_reader, _dxbc.header, _err);
  1733. _dxbc.shader.shex = false;
  1734. _dxbc.shader.aon9 = false;
  1735. for (uint32_t ii = 0; ii < _dxbc.header.numChunks; ++ii)
  1736. {
  1737. bx::seek(_reader, sizeof(DxbcContext::Header) + ii*sizeof(uint32_t), bx::Whence::Begin);
  1738. uint32_t chunkOffset;
  1739. size += bx::read(_reader, chunkOffset, _err);
  1740. bx::seek(_reader, chunkOffset, bx::Whence::Begin);
  1741. uint32_t fourcc;
  1742. size += bx::read(_reader, fourcc, _err);
  1743. _dxbc.chunksFourcc[ii] = fourcc;
  1744. uint32_t chunkSize;
  1745. size += bx::read(_reader, chunkSize, _err);
  1746. switch (fourcc)
  1747. {
  1748. case DXBC_CHUNK_SHADER_EX:
  1749. _dxbc.shader.shex = true;
  1750. [[fallthrough]];
  1751. case DXBC_CHUNK_SHADER:
  1752. size += read(_reader, _dxbc.shader, _err);
  1753. break;
  1754. case BX_MAKEFOURCC('I', 'S', 'G', '1'):
  1755. case DXBC_CHUNK_INPUT_SIGNATURE:
  1756. size += read(_reader, _dxbc.inputSignature, _err);
  1757. break;
  1758. case BX_MAKEFOURCC('O', 'S', 'G', '1'):
  1759. case BX_MAKEFOURCC('O', 'S', 'G', '5'):
  1760. case DXBC_CHUNK_OUTPUT_SIGNATURE:
  1761. size += read(_reader, _dxbc.outputSignature, _err);
  1762. break;
  1763. case BX_MAKEFOURCC('A', 'o', 'n', '9'): // Contains DX9BC for feature level 9.x (*s_4_0_level_9_*) shaders.
  1764. _dxbc.shader.aon9 = true;
  1765. break;
  1766. case DXBC_CHUNK_SFI0: // ?
  1767. BX_ASSERT(chunkSize == sizeof(_dxbc.sfi0.data),
  1768. "Unexpected size of SFI0 chunk");
  1769. size += bx::read(_reader, _dxbc.sfi0.data, _err);
  1770. break;
  1771. case DXBC_CHUNK_SPDB: // Shader debugging info (new).
  1772. _dxbc.spdb.debugCode.resize(chunkSize);
  1773. size += bx::read(_reader, _dxbc.spdb.debugCode.data(), chunkSize, _err);
  1774. break;
  1775. case DXBC_CHUNK_RDEF: // Resource definition.
  1776. _dxbc.rdef.rdefCode.resize(chunkSize);
  1777. size += bx::read(_reader, _dxbc.rdef.rdefCode.data(), chunkSize, _err);
  1778. break;
  1779. case DXBC_CHUNK_STAT: // Statistics.
  1780. _dxbc.stat.statCode.resize(chunkSize);
  1781. size += bx::read(_reader, _dxbc.stat.statCode.data(), chunkSize, _err);
  1782. break;
  1783. case BX_MAKEFOURCC('I', 'F', 'C', 'E'): // Interface.
  1784. case BX_MAKEFOURCC('S', 'D', 'G', 'B'): // Shader debugging info (old).
  1785. case BX_MAKEFOURCC('P', 'C', 'S', 'G'): // Patch constant signature.
  1786. case BX_MAKEFOURCC('P', 'S', 'O', '1'): // Pipeline State Object 1
  1787. case BX_MAKEFOURCC('P', 'S', 'O', '2'): // Pipeline State Object 2
  1788. case BX_MAKEFOURCC('X', 'N', 'A', 'P'): // ?
  1789. case BX_MAKEFOURCC('X', 'N', 'A', 'S'): // ?
  1790. size += chunkSize;
  1791. break;
  1792. default:
  1793. size += chunkSize;
  1794. BX_ASSERT(false, "UNKNOWN FOURCC %c%c%c%c %d"
  1795. , ( (char*)&fourcc)[0]
  1796. , ( (char*)&fourcc)[1]
  1797. , ( (char*)&fourcc)[2]
  1798. , ( (char*)&fourcc)[3]
  1799. , size
  1800. );
  1801. break;
  1802. }
  1803. }
  1804. return size;
  1805. }
  1806. int32_t write(bx::WriterSeekerI* _writer, const DxbcContext& _dxbc, bx::Error* _err)
  1807. {
  1808. int32_t size = 0;
  1809. uint32_t numSupportedChunks = 0;
  1810. for (uint32_t ii = 0; ii < _dxbc.header.numChunks; ++ii)
  1811. {
  1812. switch(_dxbc.chunksFourcc[ii])
  1813. {
  1814. case DXBC_CHUNK_SHADER_EX:
  1815. case DXBC_CHUNK_SHADER:
  1816. case BX_MAKEFOURCC('I', 'S', 'G', '1'):
  1817. case DXBC_CHUNK_INPUT_SIGNATURE:
  1818. case BX_MAKEFOURCC('O', 'S', 'G', '1'):
  1819. case BX_MAKEFOURCC('O', 'S', 'G', '5'):
  1820. case DXBC_CHUNK_OUTPUT_SIGNATURE:
  1821. case DXBC_CHUNK_SFI0:
  1822. case DXBC_CHUNK_SPDB:
  1823. case DXBC_CHUNK_RDEF:
  1824. case DXBC_CHUNK_STAT:
  1825. ++numSupportedChunks;
  1826. break;
  1827. default:
  1828. break;
  1829. }
  1830. }
  1831. int64_t dxbcOffset = bx::seek(_writer);
  1832. size += bx::write(_writer, DXBC_CHUNK_HEADER, _err);
  1833. size += bx::writeRep(_writer, 0, 16, _err);
  1834. size += bx::write(_writer, UINT32_C(1), _err);
  1835. int64_t sizeOffset = bx::seek(_writer);
  1836. size += bx::writeRep(_writer, 0, 4, _err);
  1837. size += bx::write(_writer, numSupportedChunks, _err);
  1838. int64_t chunksOffsets = bx::seek(_writer);
  1839. size += bx::writeRep(_writer, 0, numSupportedChunks*sizeof(uint32_t), _err);
  1840. uint32_t chunkOffset[DXBC_MAX_CHUNKS] = {};
  1841. uint32_t chunkSize[DXBC_MAX_CHUNKS] = {};
  1842. for (uint32_t ii = 0, idx = 0; ii < _dxbc.header.numChunks; ++ii)
  1843. {
  1844. switch (_dxbc.chunksFourcc[ii])
  1845. {
  1846. case DXBC_CHUNK_SHADER_EX:
  1847. case DXBC_CHUNK_SHADER:
  1848. chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset);
  1849. size += bx::write(_writer, _dxbc.shader.shex ? DXBC_CHUNK_SHADER_EX : DXBC_CHUNK_SHADER, _err);
  1850. size += bx::write(_writer, UINT32_C(0), _err);
  1851. chunkSize[idx] = write(_writer, _dxbc.shader, _err);
  1852. size += chunkSize[idx++];
  1853. break;
  1854. case BX_MAKEFOURCC('I', 'S', 'G', '1'):
  1855. case DXBC_CHUNK_INPUT_SIGNATURE:
  1856. chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset);
  1857. size += bx::write(_writer, DXBC_CHUNK_INPUT_SIGNATURE, _err);
  1858. size += bx::write(_writer, UINT32_C(0), _err);
  1859. chunkSize[idx] = write(_writer, _dxbc.inputSignature, _err);
  1860. size += chunkSize[idx++];
  1861. break;
  1862. case BX_MAKEFOURCC('O', 'S', 'G', '1'):
  1863. case BX_MAKEFOURCC('O', 'S', 'G', '5'):
  1864. case DXBC_CHUNK_OUTPUT_SIGNATURE:
  1865. chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset);
  1866. size += bx::write(_writer, DXBC_CHUNK_OUTPUT_SIGNATURE, _err);
  1867. size += bx::write(_writer, UINT32_C(0), _err);
  1868. chunkSize[idx] = write(_writer, _dxbc.outputSignature, _err);
  1869. size += chunkSize[idx++];
  1870. break;
  1871. case DXBC_CHUNK_SFI0:
  1872. chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset);
  1873. size += bx::write(_writer, DXBC_CHUNK_SFI0, _err);
  1874. size += bx::write(_writer, UINT32_C(0), _err);
  1875. chunkSize[idx] = bx::write(_writer, _dxbc.sfi0.data, _err);
  1876. size += chunkSize[idx++];
  1877. break;
  1878. case DXBC_CHUNK_SPDB: // Shader debugging info (new).
  1879. chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset);
  1880. size += bx::write(_writer, DXBC_CHUNK_SPDB, _err);
  1881. size += bx::write(_writer, UINT32_C(0), _err);
  1882. chunkSize[idx] = bx::write(_writer, _dxbc.spdb.debugCode.data(), int32_t(_dxbc.spdb.debugCode.size() ), _err);
  1883. size += chunkSize[idx++];
  1884. break;
  1885. case DXBC_CHUNK_RDEF: // Resource definition.
  1886. chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset);
  1887. size += bx::write(_writer, DXBC_CHUNK_RDEF, _err);
  1888. size += bx::write(_writer, uint32_t(_dxbc.rdef.rdefCode.size()), _err);
  1889. chunkSize[idx] = bx::write(_writer, _dxbc.rdef.rdefCode.data(), int32_t(_dxbc.rdef.rdefCode.size() ), _err);
  1890. size += chunkSize[idx++];
  1891. break;
  1892. case DXBC_CHUNK_STAT: // Statistics.
  1893. chunkOffset[idx] = uint32_t(bx::seek(_writer) - dxbcOffset);
  1894. size += bx::write(_writer, DXBC_CHUNK_STAT, _err);
  1895. size += bx::write(_writer, uint32_t(_dxbc.stat.statCode.size()), _err);
  1896. chunkSize[idx] = bx::write(_writer, _dxbc.stat.statCode.data(), int32_t(_dxbc.stat.statCode.size() ), _err);
  1897. size += chunkSize[idx++];
  1898. break;
  1899. case BX_MAKEFOURCC('A', 'o', 'n', '9'): // Contains DX9BC for feature level 9.x (*s_4_0_level_9_*) shaders.
  1900. case BX_MAKEFOURCC('I', 'F', 'C', 'E'): // Interface.
  1901. case BX_MAKEFOURCC('S', 'D', 'G', 'B'): // Shader debugging info (old).
  1902. case BX_MAKEFOURCC('P', 'C', 'S', 'G'): // Patch constant signature.
  1903. case BX_MAKEFOURCC('P', 'S', 'O', '1'): // Pipeline State Object 1
  1904. case BX_MAKEFOURCC('P', 'S', 'O', '2'): // Pipeline State Object 2
  1905. case BX_MAKEFOURCC('X', 'N', 'A', 'P'): // ?
  1906. case BX_MAKEFOURCC('X', 'N', 'A', 'S'): // ?
  1907. default:
  1908. BX_ASSERT(false, "Writing of DXBC %c%c%c%c chunk unsupported"
  1909. , ( (char*)&_dxbc.chunksFourcc[ii])[0]
  1910. , ( (char*)&_dxbc.chunksFourcc[ii])[1]
  1911. , ( (char*)&_dxbc.chunksFourcc[ii])[2]
  1912. , ( (char*)&_dxbc.chunksFourcc[ii])[3]
  1913. );
  1914. break;
  1915. }
  1916. }
  1917. int64_t eof = bx::seek(_writer);
  1918. bx::seek(_writer, sizeOffset, bx::Whence::Begin);
  1919. bx::write(_writer, size, _err);
  1920. bx::seek(_writer, chunksOffsets, bx::Whence::Begin);
  1921. bx::write(_writer, chunkOffset, numSupportedChunks*sizeof(chunkOffset[0]), _err);
  1922. for (uint32_t ii = 0; ii < numSupportedChunks; ++ii)
  1923. {
  1924. bx::seek(_writer, chunkOffset[ii]+4, bx::Whence::Begin);
  1925. bx::write(_writer, chunkSize[ii], _err);
  1926. }
  1927. bx::seek(_writer, eof, bx::Whence::Begin);
  1928. return size;
  1929. }
  1930. void parse(const DxbcShader& _src, DxbcParseFn _fn, void* _userData, bx::Error* _err)
  1931. {
  1932. BX_ERROR_SCOPE(_err);
  1933. bx::MemoryReader reader(_src.byteCode.data(), uint32_t(_src.byteCode.size() ) );
  1934. for (uint32_t token = 0, numTokens = uint32_t(_src.byteCode.size() / sizeof(uint32_t) ); token < numTokens;)
  1935. {
  1936. DxbcInstruction instruction;
  1937. uint32_t size = read(&reader, instruction, _err);
  1938. BX_ASSERT(size/4 == instruction.length, "read %d, expected %d", size/4, instruction.length); BX_UNUSED(size);
  1939. bool cont = _fn(token * sizeof(uint32_t), instruction, _userData);
  1940. if (!cont)
  1941. {
  1942. return;
  1943. }
  1944. token += instruction.length;
  1945. }
  1946. }
  1947. void filter(DxbcShader& _dst, const DxbcShader& _src, DxbcFilterFn _fn, void* _userData, bx::Error* _err)
  1948. {
  1949. BX_ERROR_SCOPE(_err);
  1950. bx::MemoryReader reader(_src.byteCode.data(), uint32_t(_src.byteCode.size() ) );
  1951. bx::MemoryBlock mb(g_allocator);
  1952. bx::MemoryWriter writer(&mb);
  1953. int32_t total = 0;
  1954. for (uint32_t token = 0, numTokens = uint32_t(_src.byteCode.size() / sizeof(uint32_t) ); token < numTokens;)
  1955. {
  1956. DxbcInstruction instruction;
  1957. uint32_t size = read(&reader, instruction, _err);
  1958. BX_ASSERT(size/4 == instruction.length, "read %d, expected %d", size/4, instruction.length); BX_UNUSED(size);
  1959. _fn(instruction, _userData);
  1960. bx::SizerWriter sw;
  1961. uint32_t length = instruction.length;
  1962. instruction.length = uint32_t(write(&sw, instruction, _err)/4);
  1963. total += write(&writer, instruction, _err);
  1964. token += length;
  1965. }
  1966. uint8_t* data = (uint8_t*)mb.more();
  1967. _dst.byteCode.resize(total);
  1968. bx::memCopy(_dst.byteCode.data(), data, total);
  1969. }
  1970. } // namespace bgfx