shader_dxbc.cpp 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924
  1. /*
  2. * Copyright 2011-2015 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  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. { 3, 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. { 1, 0 }, // DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY
  109. { 1, 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, 0 }, // 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, 0 }, // 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. { 0, 0 }, // EMIT_STREAM
  134. { 0, 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. { 0, 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. { 0, 0 }, // UBFE
  155. { 0, 0 }, // IBFE
  156. { 5, 0 }, // BFI
  157. { 0, 0 }, // BFREV
  158. { 5, 0 }, // SWAPC
  159. { 0, 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_CHECK(_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. // mesa/src/gallium/state_trackers/d3d1x/d3d1xshader/defs/shortfiles.txt
  493. static const char* s_dxbcOperandType[] =
  494. {
  495. "r", // Temp
  496. "v", // Input
  497. "o", // Output
  498. "x", // TempArray
  499. "l", // Imm32
  500. "d", // Imm64
  501. "s", // Sampler
  502. "t", // Resource
  503. "cb", // ConstantBuffer
  504. "icb", // ImmConstantBuffer
  505. "label", // Label
  506. "vPrim", // PrimitiveID
  507. "oDepth", // OutputDepth
  508. "null", // Null
  509. "rasterizer", // Rasterizer
  510. "oMask", // CoverageMask
  511. "stream", // Stream
  512. "function_body", // FunctionBody
  513. "function_table", // FunctionTable
  514. "interface", // Interface
  515. "function_input", // FunctionInput
  516. "function_output", // FunctionOutput
  517. "vOutputControlPointID", // OutputControlPointId
  518. "vForkInstanceID", // InputForkInstanceId
  519. "vJoinInstanceID", // InputJoinInstanceId
  520. "vicp", // InputControlPoint
  521. "vocp", // OutputControlPoint
  522. "vpc", // InputPatchConstant
  523. "vDomain", // InputDomainPoint
  524. "this", // ThisPointer
  525. "u", // UnorderedAccessView
  526. "g", // ThreadGroupSharedMemory
  527. "vThreadID", // InputThreadId
  528. "vThreadGrouID", // InputThreadGroupId
  529. "vThreadIDInGroup", // InputThreadIdInGroup
  530. "vCoverage", // InputCoverageMask
  531. "vThreadIDInGroupFlattened", // InputThreadIdInGroupFlattened
  532. "vGSInstanceID", // InputGsInstanceId
  533. "oDepthGE", // OutputDepthGreaterEqual
  534. "oDepthLE", // OutputDepthLessEqual
  535. "vCycleCounter", // CycleCounter
  536. };
  537. BX_STATIC_ASSERT(BX_COUNTOF(s_dxbcOperandType) == DxbcOperandType::Count);
  538. #define DXBC_MAX_NAME_STRING 512
  539. int32_t readString(bx::ReaderSeekerI* _reader, int64_t _offset, char* _out, uint32_t _max = DXBC_MAX_NAME_STRING)
  540. {
  541. int64_t oldOffset = bx::seek(_reader);
  542. bx::seek(_reader, _offset, bx::Whence::Begin);
  543. int32_t size = 0;
  544. for (uint32_t ii = 0; ii < _max-1; ++ii)
  545. {
  546. char ch;
  547. size += bx::read(_reader, ch);
  548. *_out++ = ch;
  549. if ('\0' == ch)
  550. {
  551. break;
  552. }
  553. }
  554. *_out = '\0';
  555. bx::seek(_reader, oldOffset, bx::Whence::Begin);
  556. return size;
  557. }
  558. inline uint32_t dxbcMixF(uint32_t _b, uint32_t _c, uint32_t _d)
  559. {
  560. const uint32_t tmp0 = bx::uint32_xor(_c, _d);
  561. const uint32_t tmp1 = bx::uint32_and(_b, tmp0);
  562. const uint32_t result = bx::uint32_xor(_d, tmp1);
  563. return result;
  564. }
  565. inline uint32_t dxbcMixG(uint32_t _b, uint32_t _c, uint32_t _d)
  566. {
  567. return dxbcMixF(_d, _b, _c);
  568. }
  569. inline uint32_t dxbcMixH(uint32_t _b, uint32_t _c, uint32_t _d)
  570. {
  571. const uint32_t tmp0 = bx::uint32_xor(_b, _c);
  572. const uint32_t result = bx::uint32_xor(_d, tmp0);
  573. return result;
  574. }
  575. inline uint32_t dxbcMixI(uint32_t _b, uint32_t _c, uint32_t _d)
  576. {
  577. const uint32_t tmp0 = bx::uint32_orc(_b, _d);
  578. const uint32_t result = bx::uint32_xor(_c, tmp0);
  579. return result;
  580. }
  581. void dxbcHashBlock(const uint32_t* data, uint32_t* hash)
  582. {
  583. const uint32_t d0 = data[ 0];
  584. const uint32_t d1 = data[ 1];
  585. const uint32_t d2 = data[ 2];
  586. const uint32_t d3 = data[ 3];
  587. const uint32_t d4 = data[ 4];
  588. const uint32_t d5 = data[ 5];
  589. const uint32_t d6 = data[ 6];
  590. const uint32_t d7 = data[ 7];
  591. const uint32_t d8 = data[ 8];
  592. const uint32_t d9 = data[ 9];
  593. const uint32_t d10 = data[10];
  594. const uint32_t d11 = data[11];
  595. const uint32_t d12 = data[12];
  596. const uint32_t d13 = data[13];
  597. const uint32_t d14 = data[14];
  598. const uint32_t d15 = data[15];
  599. uint32_t aa = hash[0];
  600. uint32_t bb = hash[1];
  601. uint32_t cc = hash[2];
  602. uint32_t dd = hash[3];
  603. aa = bb + bx::uint32_rol(aa + dxbcMixF(bb, cc, dd) + d0 + 0xd76aa478, 7);
  604. dd = aa + bx::uint32_rol(dd + dxbcMixF(aa, bb, cc) + d1 + 0xe8c7b756, 12);
  605. cc = dd + bx::uint32_ror(cc + dxbcMixF(dd, aa, bb) + d2 + 0x242070db, 15);
  606. bb = cc + bx::uint32_ror(bb + dxbcMixF(cc, dd, aa) + d3 + 0xc1bdceee, 10);
  607. aa = bb + bx::uint32_rol(aa + dxbcMixF(bb, cc, dd) + d4 + 0xf57c0faf, 7);
  608. dd = aa + bx::uint32_rol(dd + dxbcMixF(aa, bb, cc) + d5 + 0x4787c62a, 12);
  609. cc = dd + bx::uint32_ror(cc + dxbcMixF(dd, aa, bb) + d6 + 0xa8304613, 15);
  610. bb = cc + bx::uint32_ror(bb + dxbcMixF(cc, dd, aa) + d7 + 0xfd469501, 10);
  611. aa = bb + bx::uint32_rol(aa + dxbcMixF(bb, cc, dd) + d8 + 0x698098d8, 7);
  612. dd = aa + bx::uint32_rol(dd + dxbcMixF(aa, bb, cc) + d9 + 0x8b44f7af, 12);
  613. cc = dd + bx::uint32_ror(cc + dxbcMixF(dd, aa, bb) + d10 + 0xffff5bb1, 15);
  614. bb = cc + bx::uint32_ror(bb + dxbcMixF(cc, dd, aa) + d11 + 0x895cd7be, 10);
  615. aa = bb + bx::uint32_rol(aa + dxbcMixF(bb, cc, dd) + d12 + 0x6b901122, 7);
  616. dd = aa + bx::uint32_rol(dd + dxbcMixF(aa, bb, cc) + d13 + 0xfd987193, 12);
  617. cc = dd + bx::uint32_ror(cc + dxbcMixF(dd, aa, bb) + d14 + 0xa679438e, 15);
  618. bb = cc + bx::uint32_ror(bb + dxbcMixF(cc, dd, aa) + d15 + 0x49b40821, 10);
  619. aa = bb + bx::uint32_rol(aa + dxbcMixG(bb, cc, dd) + d1 + 0xf61e2562, 5);
  620. dd = aa + bx::uint32_rol(dd + dxbcMixG(aa, bb, cc) + d6 + 0xc040b340, 9);
  621. cc = dd + bx::uint32_rol(cc + dxbcMixG(dd, aa, bb) + d11 + 0x265e5a51, 14);
  622. bb = cc + bx::uint32_ror(bb + dxbcMixG(cc, dd, aa) + d0 + 0xe9b6c7aa, 12);
  623. aa = bb + bx::uint32_rol(aa + dxbcMixG(bb, cc, dd) + d5 + 0xd62f105d, 5);
  624. dd = aa + bx::uint32_rol(dd + dxbcMixG(aa, bb, cc) + d10 + 0x02441453, 9);
  625. cc = dd + bx::uint32_rol(cc + dxbcMixG(dd, aa, bb) + d15 + 0xd8a1e681, 14);
  626. bb = cc + bx::uint32_ror(bb + dxbcMixG(cc, dd, aa) + d4 + 0xe7d3fbc8, 12);
  627. aa = bb + bx::uint32_rol(aa + dxbcMixG(bb, cc, dd) + d9 + 0x21e1cde6, 5);
  628. dd = aa + bx::uint32_rol(dd + dxbcMixG(aa, bb, cc) + d14 + 0xc33707d6, 9);
  629. cc = dd + bx::uint32_rol(cc + dxbcMixG(dd, aa, bb) + d3 + 0xf4d50d87, 14);
  630. bb = cc + bx::uint32_ror(bb + dxbcMixG(cc, dd, aa) + d8 + 0x455a14ed, 12);
  631. aa = bb + bx::uint32_rol(aa + dxbcMixG(bb, cc, dd) + d13 + 0xa9e3e905, 5);
  632. dd = aa + bx::uint32_rol(dd + dxbcMixG(aa, bb, cc) + d2 + 0xfcefa3f8, 9);
  633. cc = dd + bx::uint32_rol(cc + dxbcMixG(dd, aa, bb) + d7 + 0x676f02d9, 14);
  634. bb = cc + bx::uint32_ror(bb + dxbcMixG(cc, dd, aa) + d12 + 0x8d2a4c8a, 12);
  635. aa = bb + bx::uint32_rol(aa + dxbcMixH(bb, cc, dd) + d5 + 0xfffa3942, 4);
  636. dd = aa + bx::uint32_rol(dd + dxbcMixH(aa, bb, cc) + d8 + 0x8771f681, 11);
  637. cc = dd + bx::uint32_rol(cc + dxbcMixH(dd, aa, bb) + d11 + 0x6d9d6122, 16);
  638. bb = cc + bx::uint32_ror(bb + dxbcMixH(cc, dd, aa) + d14 + 0xfde5380c, 9);
  639. aa = bb + bx::uint32_rol(aa + dxbcMixH(bb, cc, dd) + d1 + 0xa4beea44, 4);
  640. dd = aa + bx::uint32_rol(dd + dxbcMixH(aa, bb, cc) + d4 + 0x4bdecfa9, 11);
  641. cc = dd + bx::uint32_rol(cc + dxbcMixH(dd, aa, bb) + d7 + 0xf6bb4b60, 16);
  642. bb = cc + bx::uint32_ror(bb + dxbcMixH(cc, dd, aa) + d10 + 0xbebfbc70, 9);
  643. aa = bb + bx::uint32_rol(aa + dxbcMixH(bb, cc, dd) + d13 + 0x289b7ec6, 4);
  644. dd = aa + bx::uint32_rol(dd + dxbcMixH(aa, bb, cc) + d0 + 0xeaa127fa, 11);
  645. cc = dd + bx::uint32_rol(cc + dxbcMixH(dd, aa, bb) + d3 + 0xd4ef3085, 16);
  646. bb = cc + bx::uint32_ror(bb + dxbcMixH(cc, dd, aa) + d6 + 0x04881d05, 9);
  647. aa = bb + bx::uint32_rol(aa + dxbcMixH(bb, cc, dd) + d9 + 0xd9d4d039, 4);
  648. dd = aa + bx::uint32_rol(dd + dxbcMixH(aa, bb, cc) + d12 + 0xe6db99e5, 11);
  649. cc = dd + bx::uint32_rol(cc + dxbcMixH(dd, aa, bb) + d15 + 0x1fa27cf8, 16);
  650. bb = cc + bx::uint32_ror(bb + dxbcMixH(cc, dd, aa) + d2 + 0xc4ac5665, 9);
  651. aa = bb + bx::uint32_rol(aa + dxbcMixI(bb, cc, dd) + d0 + 0xf4292244, 6);
  652. dd = aa + bx::uint32_rol(dd + dxbcMixI(aa, bb, cc) + d7 + 0x432aff97, 10);
  653. cc = dd + bx::uint32_rol(cc + dxbcMixI(dd, aa, bb) + d14 + 0xab9423a7, 15);
  654. bb = cc + bx::uint32_ror(bb + dxbcMixI(cc, dd, aa) + d5 + 0xfc93a039, 11);
  655. aa = bb + bx::uint32_rol(aa + dxbcMixI(bb, cc, dd) + d12 + 0x655b59c3, 6);
  656. dd = aa + bx::uint32_rol(dd + dxbcMixI(aa, bb, cc) + d3 + 0x8f0ccc92, 10);
  657. cc = dd + bx::uint32_rol(cc + dxbcMixI(dd, aa, bb) + d10 + 0xffeff47d, 15);
  658. bb = cc + bx::uint32_ror(bb + dxbcMixI(cc, dd, aa) + d1 + 0x85845dd1, 11);
  659. aa = bb + bx::uint32_rol(aa + dxbcMixI(bb, cc, dd) + d8 + 0x6fa87e4f, 6);
  660. dd = aa + bx::uint32_rol(dd + dxbcMixI(aa, bb, cc) + d15 + 0xfe2ce6e0, 10);
  661. cc = dd + bx::uint32_rol(cc + dxbcMixI(dd, aa, bb) + d6 + 0xa3014314, 15);
  662. bb = cc + bx::uint32_ror(bb + dxbcMixI(cc, dd, aa) + d13 + 0x4e0811a1, 11);
  663. aa = bb + bx::uint32_rol(aa + dxbcMixI(bb, cc, dd) + d4 + 0xf7537e82, 6);
  664. dd = aa + bx::uint32_rol(dd + dxbcMixI(aa, bb, cc) + d11 + 0xbd3af235, 10);
  665. cc = dd + bx::uint32_rol(cc + dxbcMixI(dd, aa, bb) + d2 + 0x2ad7d2bb, 15);
  666. bb = cc + bx::uint32_ror(bb + dxbcMixI(cc, dd, aa) + d9 + 0xeb86d391, 11);
  667. hash[0] += aa;
  668. hash[1] += bb;
  669. hash[2] += cc;
  670. hash[3] += dd;
  671. }
  672. // dxbc hash function is slightly modified version of MD5 hash.
  673. // https://tools.ietf.org/html/rfc1321
  674. // http://www.efgh.com/software/md5.txt
  675. //
  676. // Assumption is that data pointer, size are both 4-byte aligned,
  677. // and little endian.
  678. //
  679. void dxbcHash(const void* _data, uint32_t _size, void* _digest)
  680. {
  681. uint32_t hash[4] =
  682. {
  683. 0x67452301,
  684. 0xefcdab89,
  685. 0x98badcfe,
  686. 0x10325476,
  687. };
  688. const uint32_t* data = (const uint32_t*)_data;
  689. for (uint32_t ii = 0, num = _size/64; ii < num; ++ii)
  690. {
  691. dxbcHashBlock(data, hash);
  692. data += 16;
  693. }
  694. uint32_t last[16];
  695. memset(last, 0, sizeof(last) );
  696. const uint32_t remaining = _size & 0x3f;
  697. if (remaining >= 56)
  698. {
  699. memcpy(&last[0], data, remaining);
  700. last[remaining/4] = 0x80;
  701. dxbcHashBlock(last, hash);
  702. memset(&last[1], 0, 56);
  703. }
  704. else
  705. {
  706. memcpy(&last[1], data, remaining);
  707. last[1 + remaining/4] = 0x80;
  708. }
  709. last[ 0] = _size * 8;
  710. last[15] = _size * 2 + 1;
  711. dxbcHashBlock(last, hash);
  712. memcpy(_digest, hash, 16);
  713. }
  714. int32_t read(bx::ReaderI* _reader, DxbcSubOperand& _subOperand)
  715. {
  716. uint32_t token;
  717. int32_t size = 0;
  718. // 0 1 2 3
  719. // 76543210765432107654321076543210
  720. // e222111000nnttttttttssssssssmmoo
  721. // ^^ ^ ^ ^ ^ ^ ^ ^-- number of operands
  722. // || | | | | | +---- operand mode
  723. // || | | | | +------------ operand mode bits
  724. // || | | | +-------------------- type
  725. // || | | +---------------------- number of addressing modes
  726. // || | +------------------------- addressing mode 0
  727. // || +---------------------------- addressing mode 1
  728. // |+------------------------------- addressing mode 2
  729. // +-------------------------------- extended
  730. size += bx::read(_reader, token);
  731. _subOperand.type = DxbcOperandType::Enum( (token & UINT32_C(0x000ff000) ) >> 12);
  732. _subOperand.numAddrModes = uint8_t( (token & UINT32_C(0x00300000) ) >> 20);
  733. _subOperand.addrMode = uint8_t( (token & UINT32_C(0x01c00000) ) >> 22);
  734. _subOperand.mode = DxbcOperandMode::Enum( (token & UINT32_C(0x0000000c) ) >> 2);
  735. _subOperand.modeBits = uint8_t( (token & UINT32_C(0x00000ff0) ) >> 4) & "\x0f\xff\x03\x00"[_subOperand.mode];
  736. _subOperand.num = uint8_t( (token & UINT32_C(0x00000003) ) );
  737. switch (_subOperand.addrMode)
  738. {
  739. case DxbcOperandAddrMode::Imm32:
  740. size += bx::read(_reader, _subOperand.regIndex);
  741. break;
  742. case DxbcOperandAddrMode::Reg:
  743. {
  744. DxbcSubOperand subOperand;
  745. size += read(_reader, subOperand);
  746. }
  747. break;
  748. case DxbcOperandAddrMode::RegImm32:
  749. {
  750. size += bx::read(_reader, _subOperand.regIndex);
  751. DxbcSubOperand subOperand;
  752. size += read(_reader, subOperand);
  753. }
  754. break;
  755. case DxbcOperandAddrMode::RegImm64:
  756. {
  757. size += bx::read(_reader, _subOperand.regIndex);
  758. size += bx::read(_reader, _subOperand.regIndex);
  759. DxbcSubOperand subOperand;
  760. size += read(_reader, subOperand);
  761. }
  762. break;
  763. default:
  764. BX_CHECK(false, "sub operand addressing mode %d", _subOperand.addrMode);
  765. break;
  766. }
  767. return size;
  768. }
  769. int32_t write(bx::WriterI* _writer, const DxbcSubOperand& _subOperand)
  770. {
  771. int32_t size = 0;
  772. uint32_t token = 0;
  773. token |= (_subOperand.type << 12) & UINT32_C(0x000ff000);
  774. token |= (_subOperand.numAddrModes << 20) & UINT32_C(0x00300000);
  775. token |= (_subOperand.addrMode << 22) & UINT32_C(0x01c00000);
  776. token |= (_subOperand.mode << 2) & UINT32_C(0x0000000c);
  777. token |= (_subOperand.modeBits << 4) & UINT32_C(0x00000ff0);
  778. token |= _subOperand.num & UINT32_C(0x00000003);
  779. size += bx::write(_writer, token);
  780. switch (_subOperand.addrMode)
  781. {
  782. case DxbcOperandAddrMode::Imm32:
  783. size += bx::write(_writer, _subOperand.regIndex);
  784. break;
  785. case DxbcOperandAddrMode::Reg:
  786. {
  787. DxbcSubOperand subOperand;
  788. size += write(_writer, subOperand);
  789. }
  790. break;
  791. case DxbcOperandAddrMode::RegImm32:
  792. {
  793. size += bx::write(_writer, _subOperand.regIndex);
  794. DxbcSubOperand subOperand;
  795. size += write(_writer, subOperand);
  796. }
  797. break;
  798. case DxbcOperandAddrMode::RegImm64:
  799. {
  800. size += bx::write(_writer, _subOperand.regIndex);
  801. size += bx::write(_writer, _subOperand.regIndex);
  802. DxbcSubOperand subOperand;
  803. size += write(_writer, subOperand);
  804. }
  805. break;
  806. default:
  807. BX_CHECK(false, "sub operand addressing mode %d", _subOperand.addrMode);
  808. break;
  809. }
  810. return size;
  811. }
  812. int32_t read(bx::ReaderI* _reader, DxbcOperand& _operand)
  813. {
  814. int32_t size = 0;
  815. uint32_t token;
  816. size += bx::read(_reader, token);
  817. // 0 1 2 3
  818. // 76543210765432107654321076543210
  819. // e222111000nnttttttttssssssssmmoo
  820. // ^^ ^ ^ ^ ^ ^ ^ ^-- number of operands
  821. // || | | | | | +---- operand mode
  822. // || | | | | +------------ operand mode bits
  823. // || | | | +-------------------- type
  824. // || | | +---------------------- number of addressing modes
  825. // || | +------------------------- addressing mode 0
  826. // || +---------------------------- addressing mode 1
  827. // |+------------------------------- addressing mode 2
  828. // +-------------------------------- extended
  829. _operand.extended = 0 != (token & UINT32_C(0x80000000) );
  830. _operand.numAddrModes = uint8_t( (token & UINT32_C(0x00300000) ) >> 20);
  831. _operand.addrMode[0] = uint8_t( (token & UINT32_C(0x01c00000) ) >> 22);
  832. _operand.addrMode[1] = uint8_t( (token & UINT32_C(0x0e000000) ) >> 25);
  833. _operand.addrMode[2] = uint8_t( (token & UINT32_C(0x70000000) ) >> 28);
  834. _operand.type = DxbcOperandType::Enum( (token & UINT32_C(0x000ff000) ) >> 12);
  835. _operand.mode = DxbcOperandMode::Enum( (token & UINT32_C(0x0000000c) ) >> 2);
  836. _operand.modeBits = uint8_t( (token & UINT32_C(0x00000ff0) ) >> 4) & "\x0f\xff\x03\x00"[_operand.mode];
  837. _operand.num = uint8_t( (token & UINT32_C(0x00000003) ) );
  838. if (_operand.extended)
  839. {
  840. size += bx::read(_reader, _operand.extBits);
  841. }
  842. switch (_operand.type)
  843. {
  844. case DxbcOperandType::Imm32:
  845. _operand.num = 2 == _operand.num ? 4 : _operand.num;
  846. for (uint32_t ii = 0; ii < _operand.num; ++ii)
  847. {
  848. size += bx::read(_reader, _operand.un.imm32[ii]);
  849. }
  850. break;
  851. case DxbcOperandType::Imm64:
  852. _operand.num = 2 == _operand.num ? 4 : _operand.num;
  853. for (uint32_t ii = 0; ii < _operand.num; ++ii)
  854. {
  855. size += bx::read(_reader, _operand.un.imm64[ii]);
  856. }
  857. break;
  858. default:
  859. break;
  860. }
  861. for (uint32_t ii = 0; ii < _operand.numAddrModes; ++ii)
  862. {
  863. switch (_operand.addrMode[ii])
  864. {
  865. case DxbcOperandAddrMode::Imm32:
  866. size += bx::read(_reader, _operand.regIndex[ii]);
  867. break;
  868. case DxbcOperandAddrMode::Reg:
  869. size += read(_reader, _operand.subOperand[ii]);
  870. break;
  871. case DxbcOperandAddrMode::RegImm32:
  872. size += bx::read(_reader, _operand.regIndex[ii]);
  873. size += read(_reader, _operand.subOperand[ii]);
  874. break;
  875. default:
  876. BX_CHECK(false, "operand %d addressing mode %d", ii, _operand.addrMode[ii]);
  877. break;
  878. }
  879. }
  880. return size;
  881. }
  882. int32_t write(bx::WriterI* _writer, const DxbcOperand& _operand)
  883. {
  884. int32_t size = 0;
  885. uint32_t token = 0;
  886. token |= _operand.extended ? UINT32_C(0x80000000) : 0;
  887. token |= (_operand.numAddrModes << 20) & UINT32_C(0x00300000);
  888. token |= (_operand.addrMode[0] << 22) & UINT32_C(0x01c00000);
  889. token |= (_operand.addrMode[1] << 25) & UINT32_C(0x0e000000);
  890. token |= (_operand.addrMode[2] << 28) & UINT32_C(0x70000000);
  891. token |= (_operand.type << 12) & UINT32_C(0x000ff000);
  892. token |= (_operand.mode << 2) & UINT32_C(0x0000000c);
  893. token |= (4 == _operand.num ? 2 : _operand.num) & UINT32_C(0x00000003);
  894. token |= ( (_operand.modeBits & "\x0f\xff\x03\x00"[_operand.mode]) << 4) & UINT32_C(0x00000ff0);
  895. size += bx::write(_writer, token);
  896. if (_operand.extended)
  897. {
  898. size += bx::write(_writer, _operand.extBits);
  899. }
  900. switch (_operand.type)
  901. {
  902. case DxbcOperandType::Imm32:
  903. for (uint32_t ii = 0; ii < _operand.num; ++ii)
  904. {
  905. size += bx::write(_writer, _operand.un.imm32[ii]);
  906. }
  907. break;
  908. case DxbcOperandType::Imm64:
  909. for (uint32_t ii = 0; ii < _operand.num; ++ii)
  910. {
  911. size += bx::write(_writer, _operand.un.imm64[ii]);
  912. }
  913. break;
  914. default:
  915. break;
  916. }
  917. for (uint32_t ii = 0; ii < _operand.numAddrModes; ++ii)
  918. {
  919. switch (_operand.addrMode[ii])
  920. {
  921. case DxbcOperandAddrMode::Imm32:
  922. size += bx::write(_writer, _operand.regIndex[ii]);
  923. break;
  924. case DxbcOperandAddrMode::Reg:
  925. size += write(_writer, _operand.subOperand[ii]);
  926. break;
  927. case DxbcOperandAddrMode::RegImm32:
  928. size += bx::write(_writer, _operand.regIndex[ii]);
  929. size += write(_writer, _operand.subOperand[ii]);
  930. break;
  931. default:
  932. BX_CHECK(false, "operand %d addressing mode %d", ii, _operand.addrMode[ii]);
  933. break;
  934. }
  935. }
  936. return size;
  937. }
  938. int32_t read(bx::ReaderI* _reader, DxbcInstruction& _instruction)
  939. {
  940. uint32_t size = 0;
  941. uint32_t token;
  942. size += bx::read(_reader, token);
  943. // 0 1 2 3
  944. // 76543210765432107654321076543210
  945. // elllllll.............ooooooooooo
  946. // ^^ ^----------- opcode
  947. // |+------------------------------- length
  948. // +-------------------------------- extended
  949. _instruction.opcode = DxbcOpcode::Enum( (token & UINT32_C(0x000007ff) ) );
  950. _instruction.length = uint8_t( (token & UINT32_C(0x7f000000) ) >> 24);
  951. bool extended = 0 != (token & UINT32_C(0x80000000) );
  952. _instruction.srv = DxbcResourceDim::Unknown;
  953. _instruction.samples = 0;
  954. _instruction.shadow = false;
  955. _instruction.mono = false;
  956. _instruction.allowRefactoring = false;
  957. _instruction.fp64 = false;
  958. _instruction.earlyDepth = false;
  959. _instruction.enableBuffers = false;
  960. _instruction.skipOptimization = false;
  961. _instruction.enableMinPrecision = false;
  962. _instruction.enableDoubleExtensions = false;
  963. _instruction.enableShaderExtensions = false;
  964. _instruction.threadsInGroup = false;
  965. _instruction.sharedMemory = false;
  966. _instruction.uavGroup = false;
  967. _instruction.uavGlobal = false;
  968. _instruction.saturate = false;
  969. _instruction.testNZ = false;
  970. _instruction.retType = DxbcResourceReturnType::Unused;
  971. switch (_instruction.opcode)
  972. {
  973. case DxbcOpcode::CUSTOMDATA:
  974. {
  975. // uint32_t dataClass;
  976. size += bx::read(_reader, _instruction.length);
  977. for (uint32_t ii = 0, num = (_instruction.length-2)/4; ii < num; ++ii)
  978. {
  979. char temp[16];
  980. size += bx::read(_reader, temp, 16);
  981. }
  982. }
  983. return size;
  984. case DxbcOpcode::DCL_CONSTANT_BUFFER:
  985. // 0 1 2 3
  986. // 76543210765432107654321076543210
  987. // ........ a...........
  988. // ^------------ Allow refactoring
  989. _instruction.allowRefactoring = 0 != (token & UINT32_C(0x00000800) );
  990. break;
  991. case DxbcOpcode::DCL_GLOBAL_FLAGS:
  992. // 0 1 2 3
  993. // 76543210765432107654321076543210
  994. // ........ sxmoudfa...........
  995. // ^^^^^^^^------------ Allow refactoring
  996. // ||||||+------------- FP64
  997. // |||||+-------------- Force early depth/stencil
  998. // ||||+--------------- Enable raw and structured buffers
  999. // |||+---------------- Skip optimizations
  1000. // ||+----------------- Enable minimum precision
  1001. // |+------------------ Enable double extension
  1002. // +------------------- Enable shader extension
  1003. _instruction.allowRefactoring = 0 != (token & UINT32_C(0x00000800) );
  1004. _instruction.fp64 = 0 != (token & UINT32_C(0x00001000) );
  1005. _instruction.earlyDepth = 0 != (token & UINT32_C(0x00002000) );
  1006. _instruction.enableBuffers = 0 != (token & UINT32_C(0x00004000) );
  1007. _instruction.skipOptimization = 0 != (token & UINT32_C(0x00008000) );
  1008. _instruction.enableMinPrecision = 0 != (token & UINT32_C(0x00010000) );
  1009. _instruction.enableDoubleExtensions = 0 != (token & UINT32_C(0x00020000) );
  1010. _instruction.enableShaderExtensions = 0 != (token & UINT32_C(0x00040000) );
  1011. break;
  1012. case DxbcOpcode::DCL_INPUT_PS:
  1013. // 0 1 2 3
  1014. // 76543210765432107654321076543210
  1015. // ........ iiiii...........
  1016. // ^---------------- Interploation
  1017. _instruction.interpolation = DxbcInterpolation::Enum( (token & UINT32_C(0x0000f800) ) >> 11);
  1018. break;
  1019. case DxbcOpcode::DCL_RESOURCE:
  1020. // 0 1 2 3
  1021. // 76543210765432107654321076543210
  1022. // ........ sssssssrrrrr...........
  1023. // ^ ^---------------- SRV
  1024. // +----------------------- MSAA samples
  1025. _instruction.srv = DxbcResourceDim::Enum( (token & UINT32_C(0x0000f800) ) >> 11);
  1026. _instruction.samples = uint8_t( (token & UINT32_C(0x007f0000) ) >> 16);
  1027. break;
  1028. case DxbcOpcode::DCL_SAMPLER:
  1029. // 0 1 2 3
  1030. // 76543210765432107654321076543210
  1031. // ........ ms...........
  1032. // ^^------------ Shadow sampler
  1033. // +------------- Mono
  1034. _instruction.shadow = 0 != (token & UINT32_C(0x00000800) );
  1035. _instruction.mono = 0 != (token & UINT32_C(0x00001000) );
  1036. break;
  1037. case DxbcOpcode::SYNC:
  1038. // 0 1 2 3
  1039. // 76543210765432107654321076543210
  1040. // ........ gust...........
  1041. // ^^^^------------ Threads in group
  1042. // ||+------------- Shared memory
  1043. // |+-------------- UAV group
  1044. // +--------------- UAV global
  1045. _instruction.threadsInGroup = 0 != (token & UINT32_C(0x00000800) );
  1046. _instruction.sharedMemory = 0 != (token & UINT32_C(0x00001000) );
  1047. _instruction.uavGroup = 0 != (token & UINT32_C(0x00002000) );
  1048. _instruction.uavGlobal = 0 != (token & UINT32_C(0x00004000) );
  1049. break;
  1050. default:
  1051. // 0 1 2 3
  1052. // 76543210765432107654321076543210
  1053. // ........ ppppn stt...........
  1054. // ^ ^ ^^------------- Resource info return type
  1055. // | | +-------------- Saturate
  1056. // | +------------------- Test not zero
  1057. // +----------------------- Precise mask
  1058. _instruction.retType = DxbcResourceReturnType::Enum( (token & UINT32_C(0x00001800) ) >> 11);
  1059. _instruction.saturate = 0 != (token & UINT32_C(0x00002000) );
  1060. _instruction.testNZ = 0 != (token & UINT32_C(0x00040000) );
  1061. // _instruction.precise = uint8_t( (token & UINT32_C(0x00780000) ) >> 19);
  1062. break;
  1063. }
  1064. _instruction.extended[0] = DxbcInstruction::ExtendedType::Count;
  1065. for (uint32_t ii = 0; extended; ++ii)
  1066. {
  1067. // 0 1 2 3
  1068. // 76543210765432107654321076543210
  1069. // e..........................ttttt
  1070. // ^ ^
  1071. // | +----- type
  1072. // +-------------------------------- extended
  1073. uint32_t extBits;
  1074. size += bx::read(_reader, extBits);
  1075. extended = 0 != (extBits & UINT32_C(0x80000000) );
  1076. _instruction.extended[ii] = DxbcInstruction::ExtendedType::Enum(extBits & UINT32_C(0x0000001f) );
  1077. _instruction.extended[ii+1] = DxbcInstruction::ExtendedType::Count;
  1078. switch (_instruction.extended[ii])
  1079. {
  1080. case DxbcInstruction::ExtendedType::SampleControls:
  1081. // 0 1 2 3
  1082. // 76543210765432107654321076543210
  1083. // . zzzzyyyyxxxx .....
  1084. // ^ ^ ^
  1085. // | | +------------- x
  1086. // | +----------------- y
  1087. // +--------------------- z
  1088. _instruction.sampleOffsets[0] = uint8_t( (extBits & UINT32_C(0x00001e00) ) >> 9);
  1089. _instruction.sampleOffsets[1] = uint8_t( (extBits & UINT32_C(0x0001e000) ) >> 13);
  1090. _instruction.sampleOffsets[2] = uint8_t( (extBits & UINT32_C(0x001e0000) ) >> 17);
  1091. break;
  1092. case DxbcInstruction::ExtendedType::ResourceDim:
  1093. // 0 1 2 3
  1094. // 76543210765432107654321076543210
  1095. // . .....
  1096. //
  1097. _instruction.resourceTarget = uint8_t( (extBits & UINT32_C(0x000003e0) ) >> 6);
  1098. _instruction.resourceStride = uint8_t( (extBits & UINT32_C(0x0000f800) ) >> 11);
  1099. break;
  1100. case DxbcInstruction::ExtendedType::ResourceReturnType:
  1101. // 0 1 2 3
  1102. // 76543210765432107654321076543210
  1103. // . 3333222211110000.....
  1104. // ^ ^ ^
  1105. // | | +------------- x
  1106. // | +----------------- y
  1107. // +--------------------- z
  1108. _instruction.resourceReturnTypes[0] = DxbcResourceReturnType::Enum( (extBits & UINT32_C(0x000001e0) ) >> 6);
  1109. _instruction.resourceReturnTypes[1] = DxbcResourceReturnType::Enum( (extBits & UINT32_C(0x00001e00) ) >> 9);
  1110. _instruction.resourceReturnTypes[2] = DxbcResourceReturnType::Enum( (extBits & UINT32_C(0x0001e000) ) >> 13);
  1111. _instruction.resourceReturnTypes[3] = DxbcResourceReturnType::Enum( (extBits & UINT32_C(0x001e0000) ) >> 17);
  1112. break;
  1113. default:
  1114. break;
  1115. }
  1116. }
  1117. switch (_instruction.opcode)
  1118. {
  1119. case DxbcOpcode::DCL_FUNCTION_TABLE:
  1120. {
  1121. uint32_t tableId;
  1122. size += read(_reader, tableId);
  1123. uint32_t num;
  1124. size += read(_reader, num);
  1125. for (uint32_t ii = 0; ii < num; ++ii)
  1126. {
  1127. uint32_t bodyId;
  1128. size += read(_reader, bodyId);
  1129. }
  1130. }
  1131. break;
  1132. case DxbcOpcode::DCL_INTERFACE:
  1133. {
  1134. uint32_t interfaceId;
  1135. size += read(_reader, interfaceId);
  1136. uint32_t num;
  1137. size += read(_reader, num);
  1138. BX_CHECK(false, "not implemented.");
  1139. }
  1140. break;
  1141. default:
  1142. break;
  1143. };
  1144. uint32_t currOp = 0;
  1145. const DxbcOpcodeInfo& info = s_dxbcOpcodeInfo[_instruction.opcode];
  1146. _instruction.numOperands = info.numOperands;
  1147. switch (info.numOperands)
  1148. {
  1149. case 6: size += read(_reader, _instruction.operand[currOp++]);
  1150. case 5: size += read(_reader, _instruction.operand[currOp++]);
  1151. case 4: size += read(_reader, _instruction.operand[currOp++]);
  1152. case 3: size += read(_reader, _instruction.operand[currOp++]);
  1153. case 2: size += read(_reader, _instruction.operand[currOp++]);
  1154. case 1: size += read(_reader, _instruction.operand[currOp++]);
  1155. case 0:
  1156. if (0 < info.numValues)
  1157. {
  1158. size += read(_reader, _instruction.value, info.numValues*sizeof(uint32_t) );
  1159. }
  1160. break;
  1161. default:
  1162. BX_CHECK(false, "Instruction %s with invalid number of operands %d (numValues %d)."
  1163. , getName(_instruction.opcode)
  1164. , info.numOperands
  1165. , info.numValues
  1166. );
  1167. break;
  1168. }
  1169. return size;
  1170. }
  1171. int32_t write(bx::WriterI* _writer, const DxbcInstruction& _instruction)
  1172. {
  1173. uint32_t token = 0;
  1174. token |= (_instruction.opcode ) & UINT32_C(0x000007ff);
  1175. token |= (_instruction.length << 24) & UINT32_C(0x7f000000);
  1176. token |= DxbcInstruction::ExtendedType::Count != _instruction.extended[0]
  1177. ? UINT32_C(0x80000000)
  1178. : 0
  1179. ;
  1180. switch (_instruction.opcode)
  1181. {
  1182. // case DxbcOpcode::CUSTOMDATA:
  1183. // return size;
  1184. case DxbcOpcode::DCL_CONSTANT_BUFFER:
  1185. token |= _instruction.allowRefactoring ? UINT32_C(0x00000800) : 0;
  1186. break;
  1187. case DxbcOpcode::DCL_GLOBAL_FLAGS:
  1188. token |= _instruction.allowRefactoring ? UINT32_C(0x00000800) : 0;
  1189. token |= _instruction.fp64 ? UINT32_C(0x00001000) : 0;
  1190. token |= _instruction.earlyDepth ? UINT32_C(0x00002000) : 0;
  1191. token |= _instruction.enableBuffers ? UINT32_C(0x00004000) : 0;
  1192. token |= _instruction.skipOptimization ? UINT32_C(0x00008000) : 0;
  1193. token |= _instruction.enableMinPrecision ? UINT32_C(0x00010000) : 0;
  1194. token |= _instruction.enableDoubleExtensions ? UINT32_C(0x00020000) : 0;
  1195. token |= _instruction.enableShaderExtensions ? UINT32_C(0x00040000) : 0;
  1196. break;
  1197. case DxbcOpcode::DCL_INPUT_PS:
  1198. token |= (_instruction.interpolation << 11) & UINT32_C(0x0000f800);
  1199. break;
  1200. case DxbcOpcode::DCL_RESOURCE:
  1201. token |= (_instruction.srv << 11) & UINT32_C(0x0000f800);
  1202. token |= (_instruction.samples << 16) & UINT32_C(0x007f0000);
  1203. break;
  1204. case DxbcOpcode::DCL_SAMPLER:
  1205. token |= _instruction.shadow ? (0x00000800) : 0;
  1206. token |= _instruction.mono ? (0x00001000) : 0;
  1207. break;
  1208. case DxbcOpcode::SYNC:
  1209. token |= _instruction.threadsInGroup ? UINT32_C(0x00000800) : 0;
  1210. token |= _instruction.sharedMemory ? UINT32_C(0x00001000) : 0;
  1211. token |= _instruction.uavGroup ? UINT32_C(0x00002000) : 0;
  1212. token |= _instruction.uavGlobal ? UINT32_C(0x00004000) : 0;
  1213. break;
  1214. default:
  1215. token |= (_instruction.retType << 11) & UINT32_C(0x00001800);
  1216. token |= _instruction.saturate ? UINT32_C(0x00002000) : 0;
  1217. token |= _instruction.testNZ ? UINT32_C(0x00040000) : 0;
  1218. // _instruction.precise = uint8_t( (token & UINT32_C(0x00780000) ) >> 19);
  1219. break;
  1220. }
  1221. uint32_t size =0;
  1222. size += bx::write(_writer, token);
  1223. ;
  1224. for (uint32_t ii = 0; _instruction.extended[ii] != DxbcInstruction::ExtendedType::Count; ++ii)
  1225. {
  1226. // 0 1 2 3
  1227. // 76543210765432107654321076543210
  1228. // e..........................ttttt
  1229. // ^ ^
  1230. // | +----- type
  1231. // +-------------------------------- extended
  1232. token = _instruction.extended[ii+1] == DxbcInstruction::ExtendedType::Count
  1233. ? 0
  1234. : UINT32_C(0x80000000)
  1235. ;
  1236. token |= uint8_t(_instruction.extended[ii]);
  1237. switch (_instruction.extended[ii])
  1238. {
  1239. case DxbcInstruction::ExtendedType::SampleControls:
  1240. // 0 1 2 3
  1241. // 76543210765432107654321076543210
  1242. // . zzzzyyyyxxxx .....
  1243. // ^ ^ ^
  1244. // | | +------------- x
  1245. // | +----------------- y
  1246. // +--------------------- z
  1247. token |= (uint32_t(_instruction.sampleOffsets[0]) << 9) & UINT32_C(0x00001e00);
  1248. token |= (uint32_t(_instruction.sampleOffsets[1]) << 13) & UINT32_C(0x0001e000);
  1249. token |= (uint32_t(_instruction.sampleOffsets[2]) << 17) & UINT32_C(0x001e0000);
  1250. break;
  1251. case DxbcInstruction::ExtendedType::ResourceDim:
  1252. // 0 1 2 3
  1253. // 76543210765432107654321076543210
  1254. // . .....
  1255. //
  1256. token |= (uint32_t(_instruction.resourceTarget << 6) & UINT32_C(0x000003e0) );
  1257. token |= (uint32_t(_instruction.resourceStride << 11) & UINT32_C(0x0000f800) );
  1258. break;
  1259. case DxbcInstruction::ExtendedType::ResourceReturnType:
  1260. // 0 1 2 3
  1261. // 76543210765432107654321076543210
  1262. // . 3333222211110000.....
  1263. // ^ ^ ^
  1264. // | | +------------- x
  1265. // | +----------------- y
  1266. // +--------------------- z
  1267. token |= (uint32_t(_instruction.resourceReturnTypes[0]) << 6) & UINT32_C(0x000001e0);
  1268. token |= (uint32_t(_instruction.resourceReturnTypes[1]) << 9) & UINT32_C(0x00001e00);
  1269. token |= (uint32_t(_instruction.resourceReturnTypes[2]) << 13) & UINT32_C(0x0001e000);
  1270. token |= (uint32_t(_instruction.resourceReturnTypes[3]) << 17) & UINT32_C(0x001e0000);
  1271. break;
  1272. default:
  1273. break;
  1274. }
  1275. size += bx::write(_writer, token);
  1276. }
  1277. for (uint32_t ii = 0; ii < _instruction.numOperands; ++ii)
  1278. {
  1279. size += write(_writer, _instruction.operand[ii]);
  1280. }
  1281. const DxbcOpcodeInfo& info = s_dxbcOpcodeInfo[_instruction.opcode];
  1282. if (0 < info.numValues)
  1283. {
  1284. size += bx::write(_writer, _instruction.value, info.numValues*sizeof(uint32_t) );
  1285. }
  1286. return size;
  1287. }
  1288. int32_t toString(char* _out, int32_t _size, const DxbcInstruction& _instruction)
  1289. {
  1290. int32_t size = 0;
  1291. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1292. , "%s%s%s"
  1293. , getName(_instruction.opcode)
  1294. , _instruction.saturate ? "_sat" : ""
  1295. , _instruction.testNZ ? "_nz" : ""
  1296. );
  1297. if (DxbcResourceDim::Unknown != _instruction.srv)
  1298. {
  1299. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1300. , " %s<%x>"
  1301. , s_dxbcSrvType[_instruction.srv]
  1302. , _instruction.value[0]
  1303. );
  1304. }
  1305. else if (0 < s_dxbcOpcodeInfo[_instruction.opcode].numValues)
  1306. {
  1307. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1308. , " %d"
  1309. , _instruction.value[0]
  1310. );
  1311. }
  1312. for (uint32_t ii = 0; ii < _instruction.numOperands; ++ii)
  1313. {
  1314. const DxbcOperand& operand = _instruction.operand[ii];
  1315. const bool array = false
  1316. || 1 < operand.numAddrModes
  1317. || DxbcOperandAddrMode::Imm32 != operand.addrMode[0]
  1318. ;
  1319. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1320. , "%s%s%s"
  1321. , 0 == ii ? " " : ", "
  1322. , operand.extended ? "*" : ""
  1323. , s_dxbcOperandType[operand.type]
  1324. );
  1325. switch (operand.type)
  1326. {
  1327. case DxbcOperandType::Imm32:
  1328. case DxbcOperandType::Imm64:
  1329. for (uint32_t jj = 0; jj < operand.num; ++jj)
  1330. {
  1331. union { uint32_t i; float f; } cast = { operand.un.imm32[jj] };
  1332. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1333. , "%s%f"
  1334. , 0 == jj ? "(" : ", "
  1335. , cast.f
  1336. );
  1337. }
  1338. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1339. , ")"
  1340. );
  1341. break;
  1342. default:
  1343. break;
  1344. }
  1345. const uint32_t first = DxbcOperandAddrMode::RegImm32 == operand.addrMode[0] ? 0 : 1;
  1346. if (0 == first)
  1347. {
  1348. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1349. , "["
  1350. );
  1351. }
  1352. else
  1353. {
  1354. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1355. , "%d%s"
  1356. , operand.regIndex[0]
  1357. , array ? "[" : ""
  1358. );
  1359. }
  1360. for (uint32_t jj = first; jj < operand.numAddrModes; ++jj)
  1361. {
  1362. switch (operand.addrMode[jj])
  1363. {
  1364. case DxbcOperandAddrMode::Imm32:
  1365. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1366. , "%d"
  1367. , operand.regIndex[jj]
  1368. );
  1369. break;
  1370. case DxbcOperandAddrMode::Reg:
  1371. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1372. , "%s%d"
  1373. , s_dxbcOperandType[operand.subOperand[jj].type]
  1374. , operand.regIndex[jj]
  1375. );
  1376. break;
  1377. case DxbcOperandAddrMode::RegImm32:
  1378. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1379. , "%d + %s%d"
  1380. , operand.regIndex[jj]
  1381. , s_dxbcOperandType[operand.subOperand[jj].type]
  1382. , operand.regIndex[jj]
  1383. );
  1384. break;
  1385. default:
  1386. break;
  1387. }
  1388. }
  1389. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1390. , "%s"
  1391. , array ? "]" : ""
  1392. );
  1393. switch (operand.mode)
  1394. {
  1395. case DxbcOperandMode::Mask:
  1396. if (0xf > operand.modeBits
  1397. && 0 < operand.modeBits)
  1398. {
  1399. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1400. , ".%s%s%s%s"
  1401. , 0 == (operand.modeBits & 1) ? "" : "x"
  1402. , 0 == (operand.modeBits & 2) ? "" : "y"
  1403. , 0 == (operand.modeBits & 4) ? "" : "z"
  1404. , 0 == (operand.modeBits & 8) ? "" : "w"
  1405. );
  1406. }
  1407. break;
  1408. case DxbcOperandMode::Swizzle:
  1409. if (0xe4 != operand.modeBits)
  1410. {
  1411. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1412. , ".%c%c%c%c"
  1413. , "xyzw"[(operand.modeBits )&0x3]
  1414. , "xyzw"[(operand.modeBits>>2)&0x3]
  1415. , "xyzw"[(operand.modeBits>>4)&0x3]
  1416. , "xyzw"[(operand.modeBits>>6)&0x3]
  1417. );
  1418. }
  1419. break;
  1420. case DxbcOperandMode::Scalar:
  1421. size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
  1422. , ".%c"
  1423. , "xyzw"[operand.modeBits]
  1424. );
  1425. break;
  1426. default:
  1427. break;
  1428. }
  1429. }
  1430. return size;
  1431. }
  1432. int32_t read(bx::ReaderSeekerI* _reader, DxbcSignature& _signature)
  1433. {
  1434. int32_t size = 0;
  1435. int64_t offset = bx::seek(_reader);
  1436. uint32_t num;
  1437. size += bx::read(_reader, num);
  1438. size += bx::read(_reader, _signature.key);
  1439. for (uint32_t ii = 0; ii < num; ++ii)
  1440. {
  1441. DxbcSignature::Element element;
  1442. uint32_t nameOffset;
  1443. size += bx::read(_reader, nameOffset);
  1444. char name[DXBC_MAX_NAME_STRING];
  1445. readString(_reader, offset + nameOffset, name);
  1446. element.name = name;
  1447. size += bx::read(_reader, element.semanticIndex);
  1448. size += bx::read(_reader, element.valueType);
  1449. size += bx::read(_reader, element.componentType);
  1450. size += bx::read(_reader, element.registerIndex);
  1451. size += bx::read(_reader, element.mask);
  1452. size += bx::read(_reader, element.readWriteMask);
  1453. size += bx::read(_reader, element.stream);
  1454. // padding
  1455. uint8_t padding;
  1456. size += bx::read(_reader, padding);
  1457. _signature.elements.push_back(element);
  1458. }
  1459. return size;
  1460. }
  1461. int32_t write(bx::WriterI* _writer, const DxbcSignature& _signature)
  1462. {
  1463. int32_t size = 0;
  1464. const uint32_t num = uint32_t(_signature.elements.size() );
  1465. size += bx::write(_writer, num);
  1466. size += bx::write(_writer, _signature.key);
  1467. typedef stl::unordered_map<stl::string, uint32_t> NameOffsetMap;
  1468. NameOffsetMap nom;
  1469. const uint8_t pad = 0;
  1470. uint32_t nameOffset = num * 24 + 8;
  1471. for (uint32_t ii = 0; ii < num; ++ii)
  1472. {
  1473. const DxbcSignature::Element& element = _signature.elements[ii];
  1474. NameOffsetMap::iterator it = nom.find(element.name);
  1475. if (it == nom.end() )
  1476. {
  1477. nom.insert(stl::make_pair(element.name, nameOffset) );
  1478. size += bx::write(_writer, nameOffset);
  1479. nameOffset += uint32_t(element.name.size() + 1);
  1480. }
  1481. else
  1482. {
  1483. size += bx::write(_writer, it->second);
  1484. }
  1485. size += bx::write(_writer, element.semanticIndex);
  1486. size += bx::write(_writer, element.valueType);
  1487. size += bx::write(_writer, element.componentType);
  1488. size += bx::write(_writer, element.registerIndex);
  1489. size += bx::write(_writer, element.mask);
  1490. size += bx::write(_writer, element.readWriteMask);
  1491. size += bx::write(_writer, element.stream);
  1492. size += bx::write(_writer, pad);
  1493. }
  1494. uint32_t len = 0;
  1495. for (uint32_t ii = 0; ii < num; ++ii)
  1496. {
  1497. const DxbcSignature::Element& element = _signature.elements[ii];
  1498. NameOffsetMap::iterator it = nom.find(element.name);
  1499. if (it != nom.end() )
  1500. {
  1501. nom.erase(it);
  1502. size += bx::write(_writer, element.name.c_str(), uint32_t(element.name.size() + 1) );
  1503. len += uint32_t(element.name.size() + 1);
  1504. }
  1505. }
  1506. // align 4 bytes
  1507. size += bx::writeRep(_writer, 0xab, (len+3)/4*4 - len);
  1508. return size;
  1509. }
  1510. int32_t read(bx::ReaderSeekerI* _reader, DxbcShader& _shader)
  1511. {
  1512. int32_t size = 0;
  1513. size += bx::read(_reader, _shader.version);
  1514. uint32_t bcLength;
  1515. size += bx::read(_reader, bcLength);
  1516. uint32_t len = (bcLength-2)*sizeof(uint32_t);
  1517. _shader.byteCode.resize(len);
  1518. size += bx::read(_reader, _shader.byteCode.data(), len);
  1519. return size;
  1520. }
  1521. int32_t write(bx::WriterI* _writer, const DxbcShader& _shader)
  1522. {
  1523. const uint32_t len = uint32_t(_shader.byteCode.size() );
  1524. const uint32_t bcLength = len / sizeof(uint32_t) + 2;
  1525. int32_t size = 0;
  1526. size += bx::write(_writer, _shader.version);
  1527. size += bx::write(_writer, bcLength);
  1528. size += bx::write(_writer, _shader.byteCode.data(), len);
  1529. return size;
  1530. }
  1531. #define DXBC_CHUNK_HEADER BX_MAKEFOURCC('D', 'X', 'B', 'C')
  1532. #define DXBC_CHUNK_SHADER BX_MAKEFOURCC('S', 'H', 'D', 'R')
  1533. #define DXBC_CHUNK_SHADER_EX BX_MAKEFOURCC('S', 'H', 'E', 'X')
  1534. #define DXBC_CHUNK_INPUT_SIGNATURE BX_MAKEFOURCC('I', 'S', 'G', 'N')
  1535. #define DXBC_CHUNK_OUTPUT_SIGNATURE BX_MAKEFOURCC('O', 'S', 'G', 'N')
  1536. int32_t read(bx::ReaderSeekerI* _reader, DxbcContext& _dxbc)
  1537. {
  1538. int32_t size = 0;
  1539. size += bx::read(_reader, _dxbc.header);
  1540. _dxbc.shader.shex = false;
  1541. for (uint32_t ii = 0; ii < _dxbc.header.numChunks; ++ii)
  1542. {
  1543. bx::seek(_reader, sizeof(DxbcContext::Header) + ii*sizeof(uint32_t), bx::Whence::Begin);
  1544. uint32_t chunkOffset;
  1545. size += bx::read(_reader, chunkOffset);
  1546. bx::seek(_reader, chunkOffset, bx::Whence::Begin);
  1547. uint32_t fourcc;
  1548. size += bx::read(_reader, fourcc);
  1549. uint32_t chunkSize;
  1550. size += bx::read(_reader, chunkSize);
  1551. switch (fourcc)
  1552. {
  1553. case DXBC_CHUNK_SHADER_EX:
  1554. _dxbc.shader.shex = true;
  1555. // fallthrough
  1556. case DXBC_CHUNK_SHADER:
  1557. size += read(_reader, _dxbc.shader);
  1558. break;
  1559. case BX_MAKEFOURCC('I', 'S', 'G', '1'):
  1560. case DXBC_CHUNK_INPUT_SIGNATURE:
  1561. size += read(_reader, _dxbc.inputSignature);
  1562. break;
  1563. case BX_MAKEFOURCC('O', 'S', 'G', '1'):
  1564. case BX_MAKEFOURCC('O', 'S', 'G', '5'):
  1565. case DXBC_CHUNK_OUTPUT_SIGNATURE:
  1566. size += read(_reader, _dxbc.outputSignature);
  1567. break;
  1568. case BX_MAKEFOURCC('R', 'D', 'E', 'F'):
  1569. case BX_MAKEFOURCC('I', 'F', 'C', 'E'):
  1570. case BX_MAKEFOURCC('P', 'C', 'S', 'G'):
  1571. case BX_MAKEFOURCC('S', 'T', 'A', 'T'):
  1572. case BX_MAKEFOURCC('S', 'F', 'I', '0'):
  1573. case BX_MAKEFOURCC('P', 'S', 'O', '1'):
  1574. case BX_MAKEFOURCC('P', 'S', 'O', '2'):
  1575. size += chunkSize;
  1576. break;
  1577. default:
  1578. size += chunkSize;
  1579. BX_CHECK(false, "UNKNOWN FOURCC %c%c%c%c %d"
  1580. , ( (char*)&fourcc)[0]
  1581. , ( (char*)&fourcc)[1]
  1582. , ( (char*)&fourcc)[2]
  1583. , ( (char*)&fourcc)[3]
  1584. , size
  1585. );
  1586. break;
  1587. }
  1588. }
  1589. return size;
  1590. }
  1591. int32_t write(bx::WriterSeekerI* _writer, const DxbcContext& _dxbc)
  1592. {
  1593. int32_t size = 0;
  1594. int64_t dxbcOffset = bx::seek(_writer);
  1595. size += bx::write(_writer, DXBC_CHUNK_HEADER);
  1596. size += bx::writeRep(_writer, 0, 16);
  1597. size += bx::write(_writer, UINT32_C(1) );
  1598. int64_t sizeOffset = bx::seek(_writer);
  1599. size += bx::writeRep(_writer, 0, 4);
  1600. uint32_t numChunks = 3;
  1601. size += bx::write(_writer, numChunks);
  1602. int64_t chunksOffsets = bx::seek(_writer);
  1603. size += bx::writeRep(_writer, 0, numChunks*sizeof(uint32_t) );
  1604. uint32_t chunkOffset[3];
  1605. uint32_t chunkSize[3];
  1606. chunkOffset[0] = uint32_t(bx::seek(_writer) - dxbcOffset);
  1607. size += write(_writer, DXBC_CHUNK_INPUT_SIGNATURE);
  1608. size += write(_writer, UINT32_C(0) );
  1609. chunkSize[0] = write(_writer, _dxbc.inputSignature);
  1610. chunkOffset[1] = uint32_t(bx::seek(_writer) - dxbcOffset);
  1611. size += write(_writer, DXBC_CHUNK_OUTPUT_SIGNATURE);
  1612. size += write(_writer, UINT32_C(0) );
  1613. chunkSize[1] = write(_writer, _dxbc.outputSignature);
  1614. chunkOffset[2] = uint32_t(bx::seek(_writer) - dxbcOffset);
  1615. size += write(_writer, _dxbc.shader.shex ? DXBC_CHUNK_SHADER_EX : DXBC_CHUNK_SHADER);
  1616. size += write(_writer, UINT32_C(0) );
  1617. chunkSize[2] = write(_writer, _dxbc.shader);
  1618. size += 0
  1619. + chunkSize[0]
  1620. + chunkSize[1]
  1621. + chunkSize[2]
  1622. ;
  1623. int64_t eof = bx::seek(_writer);
  1624. bx::seek(_writer, sizeOffset, bx::Whence::Begin);
  1625. bx::write(_writer, size);
  1626. bx::seek(_writer, chunksOffsets, bx::Whence::Begin);
  1627. bx::write(_writer, chunkOffset, sizeof(chunkOffset) );
  1628. for (uint32_t ii = 0; ii < BX_COUNTOF(chunkOffset); ++ii)
  1629. {
  1630. bx::seek(_writer, chunkOffset[ii]+4, bx::Whence::Begin);
  1631. bx::write(_writer, chunkSize[ii]);
  1632. }
  1633. bx::seek(_writer, eof, bx::Whence::Begin);
  1634. return size;
  1635. }
  1636. void parse(const DxbcShader& _src, DxbcParseFn _fn, void* _userData)
  1637. {
  1638. bx::MemoryReader reader(_src.byteCode.data(), uint32_t(_src.byteCode.size() ) );
  1639. for (uint32_t token = 0, numTokens = uint32_t(_src.byteCode.size() / sizeof(uint32_t) ); token < numTokens;)
  1640. {
  1641. DxbcInstruction instruction;
  1642. uint32_t size = read(&reader, instruction);
  1643. BX_CHECK(size/4 == instruction.length, "read %d, expected %d", size/4, instruction.length); BX_UNUSED(size);
  1644. bool cont = _fn(token * sizeof(uint32_t), instruction, _userData);
  1645. if (!cont)
  1646. {
  1647. return;
  1648. }
  1649. token += instruction.length;
  1650. }
  1651. }
  1652. void filter(DxbcShader& _dst, const DxbcShader& _src, DxbcFilterFn _fn, void* _userData)
  1653. {
  1654. bx::MemoryReader reader(_src.byteCode.data(), uint32_t(_src.byteCode.size() ) );
  1655. bx::CrtAllocator r;
  1656. bx::MemoryBlock mb(&r);
  1657. bx::MemoryWriter writer(&mb);
  1658. for (uint32_t token = 0, numTokens = uint32_t(_src.byteCode.size() / sizeof(uint32_t) ); token < numTokens;)
  1659. {
  1660. DxbcInstruction instruction;
  1661. uint32_t size = read(&reader, instruction);
  1662. BX_CHECK(size/4 == instruction.length, "read %d, expected %d", size/4, instruction.length); BX_UNUSED(size);
  1663. _fn(instruction, _userData);
  1664. write(&writer, instruction);
  1665. token += instruction.length;
  1666. }
  1667. uint8_t* data = (uint8_t*)mb.more();
  1668. uint32_t size = uint32_t(bx::getSize(&writer) );
  1669. _dst.byteCode.reserve(size);
  1670. memcpy(_dst.byteCode.data(), data, size);
  1671. }
  1672. } // namespace bgfx