shader_dxbc.cpp 60 KB

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