DX12Shader.cpp 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010
  1. #include "DX12Shader.h"
  2. #include "DX12CommandQueue.h"
  3. #include "DX12SamplerState.h"
  4. #include "DX12Texture.h"
  5. #include "DX12TLAS.h"
  6. #include "Logging.h"
  7. using namespace Framework;
  8. Framework::DX12ShaderSignature::DX12ShaderSignature()
  9. : ReferenceCounter(),
  10. signature(0),
  11. changed(1),
  12. shaderBindingTableParamCount(0)
  13. {}
  14. Framework::DX12ShaderSignature::~DX12ShaderSignature()
  15. {
  16. if (signature)
  17. {
  18. signature->Release();
  19. }
  20. for (DX12ShaderRegisterUsage* usage : descriptorHeapBindings)
  21. {
  22. delete usage;
  23. }
  24. for (DX12ShaderRegisterUsage* usage : bindingTableBindings)
  25. {
  26. delete usage;
  27. }
  28. }
  29. int* Framework::DX12ShaderSignature::addRegisterUsageLinkedToShaderBindingTable(
  30. DX12ShaderRegister registerType, int registerIndex, int spaceIndex)
  31. {
  32. if (registerType == DX12_SHADER_REGISTER_S_SAMPLER)
  33. {
  34. Logging::error() << "Sampler register usage can not be linked to "
  35. "shader binding table";
  36. throw std::logic_error(
  37. "Sampler register usage can not be linked to shader binding table");
  38. }
  39. for (DX12ShaderRegisterUsage* usage : descriptorHeapBindings)
  40. {
  41. if (usage->registerType == registerType
  42. && usage->registerIndex == registerIndex
  43. && usage->spaceIndex == spaceIndex)
  44. {
  45. Logging::error()
  46. << "Duplicate register usage in root signature: "
  47. << registerType << " " << registerIndex << " " << spaceIndex;
  48. throw std::invalid_argument(
  49. "Duplicate register usage in root signature");
  50. }
  51. }
  52. for (DX12ShaderRegisterUsage* usage : bindingTableBindings)
  53. {
  54. if (usage->registerType == registerType
  55. && usage->registerIndex == registerIndex
  56. && usage->spaceIndex == spaceIndex)
  57. {
  58. Logging::error()
  59. << "Duplicate register usage in root signature: "
  60. << registerType << " " << registerIndex << " " << spaceIndex;
  61. throw std::invalid_argument(
  62. "Duplicate register usage in root signature");
  63. }
  64. }
  65. DX12ShaderRegisterUsage* usage = new DX12ShaderRegisterUsage{registerType,
  66. GLOBAL_DESCRIPTOR_HEAP,
  67. registerIndex,
  68. spaceIndex,
  69. -1,
  70. 0,
  71. 0,
  72. -1};
  73. bindingTableBindings.add(usage);
  74. changed = 1;
  75. return &usage->bindingTableIndex;
  76. }
  77. void Framework::DX12ShaderSignature::addRegisterUsageLinkedToDescriptorHeap(
  78. int descriptorHeapIndex,
  79. DX12ShaderRegister registerType,
  80. int registerIndex,
  81. int spaceIndex,
  82. DX12DescriptorHeapType descriptorHeapType,
  83. bool array,
  84. int arraySize)
  85. {
  86. if ((registerType == DX12_SHADER_REGISTER_S_SAMPLER)
  87. != (descriptorHeapType == SAMPLER_DESCRIPTOR_HEAP))
  88. {
  89. Logging::error()
  90. << "Sampler register usage must be linked to sampler descriptor "
  91. "heap and vice versa";
  92. throw std::logic_error(
  93. "Sampler register usage must be linked to sampler descriptor "
  94. "heap and vice versa");
  95. }
  96. if (descriptorHeapIndex < 0)
  97. {
  98. Logging::error() << "descriptorHeapIndex can not be below 0";
  99. throw std::invalid_argument("descriptorHeapIndex can not be below 0");
  100. }
  101. for (DX12ShaderRegisterUsage* usage : descriptorHeapBindings)
  102. {
  103. if (usage->registerType == registerType
  104. && usage->registerIndex == registerIndex
  105. && usage->spaceIndex == spaceIndex)
  106. {
  107. Logging::error()
  108. << "Duplicate register usage in root signature: "
  109. << registerType << " " << registerIndex << " " << spaceIndex;
  110. throw std::invalid_argument(
  111. "Duplicate register usage in root signature");
  112. }
  113. }
  114. // descriptor heap bindings sould be sorted by descriptorHeapType ->
  115. // registerType -> spaceIndex -> registerIndex
  116. ArrayIterator<DX12ShaderRegisterUsage*> it = descriptorHeapBindings.begin();
  117. bool found = 0;
  118. while (it)
  119. {
  120. if (it->descriptorHeapType > descriptorHeapType)
  121. {
  122. found = 1;
  123. break;
  124. }
  125. if (it->descriptorHeapType == descriptorHeapType)
  126. {
  127. if (it->registerType > registerType)
  128. {
  129. found = 1;
  130. break;
  131. }
  132. if (it->registerType == registerType)
  133. {
  134. if (it->spaceIndex > spaceIndex)
  135. {
  136. found = 1;
  137. break;
  138. }
  139. if (it->spaceIndex == spaceIndex)
  140. {
  141. if (it->registerIndex >= registerIndex)
  142. {
  143. found = 1;
  144. break;
  145. }
  146. }
  147. }
  148. }
  149. ++it;
  150. }
  151. if (found)
  152. {
  153. if (it->registerIndex == registerIndex && it->spaceIndex == spaceIndex
  154. && it->registerType == registerType)
  155. {
  156. Logging::error()
  157. << "Duplicate register usage in root signature: "
  158. << registerType << " " << registerIndex << " " << spaceIndex;
  159. throw std::invalid_argument(
  160. "Duplicate register usage in root signature");
  161. }
  162. it.addBefore(new DX12ShaderRegisterUsage{registerType,
  163. descriptorHeapType,
  164. registerIndex,
  165. spaceIndex,
  166. descriptorHeapIndex,
  167. 0,
  168. array,
  169. arraySize});
  170. }
  171. else
  172. {
  173. descriptorHeapBindings.add(new DX12ShaderRegisterUsage{registerType,
  174. descriptorHeapType,
  175. registerIndex,
  176. spaceIndex,
  177. descriptorHeapIndex,
  178. 0,
  179. array,
  180. arraySize});
  181. }
  182. changed = 1;
  183. }
  184. void Framework::DX12ShaderSignature::createSignature(ID3D12Device5* zDevice,
  185. PFN_D3D12_SERIALIZE_ROOT_SIGNATURE pfnD3D12SerializeRootSignature)
  186. {
  187. if (!changed)
  188. {
  189. return;
  190. }
  191. changed = 0;
  192. if (signature)
  193. {
  194. signature->Release();
  195. signature = 0;
  196. }
  197. int paramCount = (descriptorHeapBindings.getEntryCount() > 0
  198. ? __DESCRIPTOR_HEAP_TYPE_COUNT__
  199. : 0)
  200. + bindingTableBindings.getEntryCount();
  201. D3D12_ROOT_PARAMETER* descriptorTable
  202. = new D3D12_ROOT_PARAMETER[paramCount];
  203. int index = 0;
  204. D3D12_DESCRIPTOR_RANGE** descriptorRanges
  205. = new D3D12_DESCRIPTOR_RANGE*[__DESCRIPTOR_HEAP_TYPE_COUNT__];
  206. int rangeCount = 0;
  207. ArrayIterator<DX12ShaderRegisterUsage*> it = descriptorHeapBindings.begin();
  208. DX12DescriptorHeapType currentDescriptorHeapType;
  209. useGlobalDescriptorHeap = 0;
  210. useTextureDescriptorHeap = 0;
  211. while (it)
  212. {
  213. descriptorTable[index].ParameterType
  214. = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
  215. descriptorTable[index].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
  216. descriptorRanges[index]
  217. = new D3D12_DESCRIPTOR_RANGE[descriptorHeapBindings
  218. .getEntryCount()];
  219. currentDescriptorHeapType = it->descriptorHeapType;
  220. if (currentDescriptorHeapType == GLOBAL_DESCRIPTOR_HEAP)
  221. {
  222. useGlobalDescriptorHeap = true;
  223. }
  224. else if (currentDescriptorHeapType == TEXTURE_DESCRIPTOR_HEAP)
  225. {
  226. useTextureDescriptorHeap = true;
  227. }
  228. rangeCount = 0;
  229. while (it && it->descriptorHeapType == currentDescriptorHeapType)
  230. {
  231. it->bindingTableIndex = 0;
  232. D3D12_DESCRIPTOR_RANGE& range = descriptorRanges[index][rangeCount];
  233. switch (it->registerType)
  234. {
  235. case DX12_SHADER_REGISTER_B_CONST_BUFFER:
  236. range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
  237. break;
  238. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  239. range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
  240. break;
  241. case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
  242. range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
  243. break;
  244. case DX12_SHADER_REGISTER_S_SAMPLER:
  245. range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
  246. break;
  247. }
  248. range.BaseShaderRegister = it->registerIndex;
  249. range.OffsetInDescriptorsFromTableStart = it->descriptorHeapIndex;
  250. range.RegisterSpace = it->spaceIndex;
  251. if (it->array)
  252. {
  253. range.NumDescriptors = it->arraySize;
  254. }
  255. else
  256. {
  257. ArrayIterator<DX12ShaderRegisterUsage*> next = it.next();
  258. int size = 1;
  259. while (next && next->registerType == it->registerType
  260. && next->spaceIndex == it->spaceIndex
  261. && next->registerIndex == it->registerIndex + size
  262. && next->descriptorHeapIndex
  263. == it->descriptorHeapIndex + size
  264. && it->descriptorHeapType == currentDescriptorHeapType)
  265. {
  266. ++size;
  267. it = next;
  268. it->bindingTableIndex = 0;
  269. ++next;
  270. }
  271. range.NumDescriptors = size;
  272. }
  273. ++it;
  274. ++rangeCount;
  275. }
  276. descriptorTable[index].DescriptorTable.pDescriptorRanges
  277. = descriptorRanges[index];
  278. descriptorTable[index].DescriptorTable.NumDescriptorRanges = rangeCount;
  279. index++;
  280. }
  281. for (DX12ShaderRegisterUsage* usage : bindingTableBindings)
  282. {
  283. usage->bindingTableIndex = index;
  284. switch (usage->registerType)
  285. {
  286. case DX12_SHADER_REGISTER_B_CONST_BUFFER:
  287. descriptorTable[index].ParameterType
  288. = D3D12_ROOT_PARAMETER_TYPE_CBV;
  289. break;
  290. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  291. descriptorTable[index].ParameterType
  292. = D3D12_ROOT_PARAMETER_TYPE_SRV;
  293. break;
  294. case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
  295. descriptorTable[index].ParameterType
  296. = D3D12_ROOT_PARAMETER_TYPE_UAV;
  297. break;
  298. }
  299. descriptorTable[index].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
  300. descriptorTable[index].Descriptor.ShaderRegister = usage->registerIndex;
  301. descriptorTable[index].Descriptor.RegisterSpace = usage->spaceIndex;
  302. ++index;
  303. }
  304. shaderBindingTableParamCount = index;
  305. D3D12_ROOT_SIGNATURE_DESC rootDesc = {};
  306. rootDesc.NumParameters = shaderBindingTableParamCount;
  307. rootDesc.pParameters = descriptorTable;
  308. rootDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
  309. ID3DBlob* pSigBlob = 0;
  310. ID3DBlob* pErrorBlob = 0;
  311. HRESULT hr = pfnD3D12SerializeRootSignature(
  312. &rootDesc, D3D_ROOT_SIGNATURE_VERSION_1_0, &pSigBlob, &pErrorBlob);
  313. if (pSigBlob)
  314. {
  315. zDevice->CreateRootSignature(0,
  316. pSigBlob->GetBufferPointer(),
  317. pSigBlob->GetBufferSize(),
  318. __uuidof(ID3D12RootSignature),
  319. (void**)&signature);
  320. pSigBlob->Release();
  321. }
  322. if (pErrorBlob)
  323. {
  324. std::string errorMessage(
  325. static_cast<const char*>(pErrorBlob->GetBufferPointer()),
  326. pErrorBlob->GetBufferSize());
  327. Logging::error() << "Failed to serialize root signature: "
  328. << errorMessage;
  329. pErrorBlob->Release();
  330. }
  331. delete[] descriptorRanges;
  332. delete[] descriptorTable;
  333. }
  334. ID3D12RootSignature* Framework::DX12ShaderSignature::zSignature() const
  335. {
  336. return signature;
  337. }
  338. const Array<DX12ShaderRegisterUsage*>&
  339. Framework::DX12ShaderSignature::getDescriptorHeapBindings() const
  340. {
  341. return descriptorHeapBindings;
  342. }
  343. int Framework::DX12ShaderSignature::gerShaderBindingTableParamCount() const
  344. {
  345. return shaderBindingTableParamCount;
  346. }
  347. bool Framework::DX12ShaderSignature::doesUseGlobalDescriptorHeap() const
  348. {
  349. return useGlobalDescriptorHeap;
  350. }
  351. bool Framework::DX12ShaderSignature::doesUseTextureDescriptorHeap() const
  352. {
  353. return useTextureDescriptorHeap;
  354. }
  355. bool Framework::DX12ShaderSignature::doesUseSamplerDescriptorHeap() const
  356. {
  357. return useSamplerDescriptorHeap;
  358. }
  359. Framework::DX12ShaderFunction::DX12ShaderFunction(const Text& functionName,
  360. DX12ShaderSignature* signature,
  361. DX12ShaderFunctionType functionType)
  362. : ReferenceCounter(),
  363. functionName(functionName),
  364. signature(signature),
  365. functionType(functionType),
  366. exportDesc(new D3D12_EXPORT_DESC())
  367. {
  368. wchar_t* wc = new wchar_t[functionName.getLength() + 1];
  369. mbstowcs_s(0,
  370. wc,
  371. functionName.getLength() + 1,
  372. functionName.getText(),
  373. functionName.getLength() + 1);
  374. wc[functionName.getLength()] = 0;
  375. exportDesc->Name = wc;
  376. exportDesc->ExportToRename = 0;
  377. exportDesc->Flags = D3D12_EXPORT_FLAG_NONE;
  378. }
  379. Framework::DX12ShaderFunction::~DX12ShaderFunction()
  380. {
  381. signature->release();
  382. delete[] exportDesc->Name;
  383. delete exportDesc;
  384. }
  385. const Text& Framework::DX12ShaderFunction::getFunctionName() const
  386. {
  387. return functionName;
  388. }
  389. DX12ShaderSignature* Framework::DX12ShaderFunction::zSignature() const
  390. {
  391. return signature;
  392. }
  393. D3D12_EXPORT_DESC* Framework::DX12ShaderFunction::zExportDesc() const
  394. {
  395. return exportDesc;
  396. }
  397. DX12ShaderFunctionType Framework::DX12ShaderFunction::getFunctionType() const
  398. {
  399. return functionType;
  400. }
  401. Framework::DX12Shader::DX12Shader(
  402. const unsigned char* shaderBytes, int shaderBytesSize)
  403. : ReferenceCounter(),
  404. shaderBytes(shaderBytes),
  405. shaderBytesSize(shaderBytesSize),
  406. libraryDesc(new D3D12_DXIL_LIBRARY_DESC())
  407. {
  408. libraryDesc->DXILLibrary.pShaderBytecode = shaderBytes;
  409. libraryDesc->DXILLibrary.BytecodeLength = shaderBytesSize;
  410. libraryDesc->NumExports = 0;
  411. libraryDesc->pExports = 0;
  412. }
  413. Framework::DX12Shader::~DX12Shader()
  414. {
  415. delete[] libraryDesc->pExports;
  416. delete libraryDesc;
  417. }
  418. void Framework::DX12Shader::addFunction(DX12ShaderFunction* function)
  419. {
  420. functions.add(function);
  421. }
  422. int Framework::DX12Shader::getShaderBytesSize() const
  423. {
  424. return shaderBytesSize;
  425. }
  426. const unsigned char* Framework::DX12Shader::getShaderBytes() const
  427. {
  428. return shaderBytes;
  429. }
  430. const RCArray<DX12ShaderFunction>& Framework::DX12Shader::getFunctions() const
  431. {
  432. return functions;
  433. }
  434. D3D12_DXIL_LIBRARY_DESC* Framework::DX12Shader::zLibraryDesc() const
  435. {
  436. if (libraryDesc->NumExports != functions.getEntryCount())
  437. {
  438. delete[] libraryDesc->pExports;
  439. libraryDesc->NumExports = functions.getEntryCount();
  440. D3D12_EXPORT_DESC* pExports
  441. = new D3D12_EXPORT_DESC[functions.getEntryCount()];
  442. int index = 0;
  443. for (const auto& function : functions)
  444. {
  445. memcpy(pExports + index,
  446. function->zExportDesc(),
  447. sizeof(D3D12_EXPORT_DESC));
  448. index++;
  449. }
  450. libraryDesc->pExports = pExports;
  451. }
  452. return libraryDesc;
  453. }
  454. Framework::DX12ShaderHitGroup::DX12ShaderHitGroup(const Text name)
  455. : ReferenceCounter(),
  456. name(name),
  457. closestHitShaderFunction(0),
  458. anyHitShaderFunction(0),
  459. intersectionShaderFunction(0),
  460. payloadSize(0),
  461. attributeSize(0),
  462. hitGroupDesc(new D3D12_HIT_GROUP_DESC())
  463. {
  464. wchar_t* wc = new wchar_t[name.getLength() + 1];
  465. mbstowcs_s(
  466. 0, wc, name.getLength() + 1, name.getText(), name.getLength() + 1);
  467. wc[name.getLength()] = 0;
  468. hitGroupDesc->HitGroupExport = wc;
  469. hitGroupDesc->IntersectionShaderImport = 0;
  470. hitGroupDesc->AnyHitShaderImport = 0;
  471. hitGroupDesc->ClosestHitShaderImport = 0;
  472. }
  473. Framework::DX12ShaderHitGroup::~DX12ShaderHitGroup()
  474. {
  475. delete[] hitGroupDesc->HitGroupExport;
  476. delete hitGroupDesc;
  477. if (closestHitShaderFunction)
  478. {
  479. closestHitShaderFunction->release();
  480. }
  481. if (anyHitShaderFunction)
  482. {
  483. anyHitShaderFunction->release();
  484. }
  485. if (intersectionShaderFunction)
  486. {
  487. intersectionShaderFunction->release();
  488. }
  489. }
  490. void Framework::DX12ShaderHitGroup::setClosestHitShaderFunction(
  491. DX12ShaderFunction* zClosestHitShaderFunction)
  492. {
  493. if (this->closestHitShaderFunction == zClosestHitShaderFunction)
  494. {
  495. return;
  496. }
  497. if (anyHitShaderFunction
  498. && anyHitShaderFunction->zSignature()
  499. != zClosestHitShaderFunction->zSignature())
  500. {
  501. Logging::error()
  502. << "Any-hit shader function and closest-hit shader "
  503. "function must have the same root signature when they are "
  504. "combined in the same hit group. HitGroup Name: '"
  505. << name << "' Any Hit Shader Function: '"
  506. << anyHitShaderFunction->getFunctionName().getText()
  507. << "' Closest Hit Shader Function: '"
  508. << zClosestHitShaderFunction->getFunctionName().getText() << "'";
  509. throw std::runtime_error("Incompatible root signatures in hit group");
  510. }
  511. if (intersectionShaderFunction
  512. && intersectionShaderFunction->zSignature()
  513. != zClosestHitShaderFunction->zSignature())
  514. {
  515. Logging::error()
  516. << "Intersection shader function and closest-hit shader "
  517. "function must have the same root signature when they are "
  518. "combined in the same hit group. HitGroup Name: '"
  519. << name << "' Intersection Shader Function: '"
  520. << intersectionShaderFunction->getFunctionName().getText()
  521. << "' Closest Hit Shader Function: '"
  522. << zClosestHitShaderFunction->getFunctionName().getText() << "'";
  523. throw std::runtime_error("Incompatible root signatures in hit group");
  524. }
  525. if (closestHitShaderFunction)
  526. {
  527. closestHitShaderFunction->release();
  528. }
  529. closestHitShaderFunction = zClosestHitShaderFunction;
  530. hitGroupDesc->ClosestHitShaderImport = 0;
  531. if (closestHitShaderFunction)
  532. {
  533. hitGroupDesc->ClosestHitShaderImport
  534. = closestHitShaderFunction->zExportDesc()->Name;
  535. closestHitShaderFunction->getThis();
  536. }
  537. }
  538. void Framework::DX12ShaderHitGroup::setAnyHitShaderFunction(
  539. DX12ShaderFunction* zAnyHitShaderFunction)
  540. {
  541. if (this->anyHitShaderFunction == zAnyHitShaderFunction)
  542. {
  543. return;
  544. }
  545. if (closestHitShaderFunction
  546. && closestHitShaderFunction->zSignature()
  547. != zAnyHitShaderFunction->zSignature())
  548. {
  549. Logging::error()
  550. << "Any-hit shader function and closest-hit shader "
  551. "function must have the same root signature when they are "
  552. "combined in the same hit group. HitGroup Name: '"
  553. << name << "' Any Hit Shader Function: '"
  554. << zAnyHitShaderFunction->getFunctionName().getText()
  555. << "' Closest Hit Shader Function: '"
  556. << closestHitShaderFunction->getFunctionName().getText() << "'";
  557. throw std::runtime_error("Incompatible root signatures in hit group");
  558. }
  559. if (intersectionShaderFunction
  560. && intersectionShaderFunction->zSignature()
  561. != zAnyHitShaderFunction->zSignature())
  562. {
  563. Logging::error()
  564. << "Intersection shader function and any-hit shader "
  565. "function must have the same root signature when they are "
  566. "combined in the same hit group. HitGroup Name: '"
  567. << name << "' Intersection Shader Function: '"
  568. << intersectionShaderFunction->getFunctionName().getText()
  569. << "' Any Hit Shader Function: '"
  570. << zAnyHitShaderFunction->getFunctionName().getText() << "'";
  571. throw std::runtime_error("Incompatible root signatures in hit group");
  572. }
  573. if (anyHitShaderFunction)
  574. {
  575. anyHitShaderFunction->release();
  576. }
  577. anyHitShaderFunction = zAnyHitShaderFunction;
  578. hitGroupDesc->AnyHitShaderImport = 0;
  579. if (anyHitShaderFunction)
  580. {
  581. hitGroupDesc->AnyHitShaderImport
  582. = anyHitShaderFunction->zExportDesc()->Name;
  583. anyHitShaderFunction->getThis();
  584. }
  585. }
  586. void Framework::DX12ShaderHitGroup::setIntersectionShaderFunction(
  587. DX12ShaderFunction* zIntersectionShaderFunction)
  588. {
  589. if (intersectionShaderFunction == zIntersectionShaderFunction)
  590. {
  591. return;
  592. }
  593. if (closestHitShaderFunction
  594. && closestHitShaderFunction->zSignature()
  595. != zIntersectionShaderFunction->zSignature())
  596. {
  597. Logging::error()
  598. << "Intersection shader function and closest-hit shader "
  599. "function must have the same root signature when they are "
  600. "combined in the same hit group. HitGroup Name: '"
  601. << name << "' Intersection Shader Function: '"
  602. << zIntersectionShaderFunction->getFunctionName().getText()
  603. << "' Closest Hit Shader Function: '"
  604. << closestHitShaderFunction->getFunctionName().getText() << "'";
  605. throw std::runtime_error("Incompatible root signatures in hit group");
  606. }
  607. if (anyHitShaderFunction
  608. && anyHitShaderFunction->zSignature()
  609. != zIntersectionShaderFunction->zSignature())
  610. {
  611. Logging::error()
  612. << "Intersection shader function and any-hit shader "
  613. "function must have the same root signature when they are "
  614. "combined in the same hit group. HitGroup Name: '"
  615. << name << "' Intersection Shader Function: '"
  616. << zIntersectionShaderFunction->getFunctionName().getText()
  617. << "' Any Hit Shader Function: '"
  618. << anyHitShaderFunction->getFunctionName().getText() << "'";
  619. throw std::runtime_error("Incompatible root signatures in hit group");
  620. }
  621. if (intersectionShaderFunction)
  622. {
  623. intersectionShaderFunction->release();
  624. }
  625. intersectionShaderFunction = zIntersectionShaderFunction;
  626. hitGroupDesc->IntersectionShaderImport = 0;
  627. if (intersectionShaderFunction)
  628. {
  629. hitGroupDesc->IntersectionShaderImport
  630. = intersectionShaderFunction->zExportDesc()->Name;
  631. intersectionShaderFunction->getThis();
  632. }
  633. }
  634. void Framework::DX12ShaderHitGroup::setPayloadSize(int payloadSize)
  635. {
  636. this->payloadSize = payloadSize;
  637. }
  638. void Framework::DX12ShaderHitGroup::setAttributeSize(int attributeSize)
  639. {
  640. this->attributeSize = attributeSize;
  641. }
  642. const Text& Framework::DX12ShaderHitGroup::getName() const
  643. {
  644. return name;
  645. }
  646. DX12ShaderFunction*
  647. Framework::DX12ShaderHitGroup::zClosestHitShaderFunction() const
  648. {
  649. return closestHitShaderFunction;
  650. }
  651. DX12ShaderFunction* Framework::DX12ShaderHitGroup::zAnyHitShaderFunction() const
  652. {
  653. return anyHitShaderFunction;
  654. }
  655. DX12ShaderFunction*
  656. Framework::DX12ShaderHitGroup::zIntersectionShaderFunction() const
  657. {
  658. return intersectionShaderFunction;
  659. }
  660. int Framework::DX12ShaderHitGroup::getPayloadSize() const
  661. {
  662. return payloadSize;
  663. }
  664. int Framework::DX12ShaderHitGroup::getAttributeSize() const
  665. {
  666. return attributeSize;
  667. }
  668. D3D12_HIT_GROUP_DESC* Framework::DX12ShaderHitGroup::zHitGroupDesc() const
  669. {
  670. if (hitGroupDesc->IntersectionShaderImport)
  671. {
  672. hitGroupDesc->Type = D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE;
  673. }
  674. else
  675. {
  676. hitGroupDesc->Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
  677. }
  678. return hitGroupDesc;
  679. }
  680. DX12ShaderSignature* Framework::DX12ShaderHitGroup::zSignature() const
  681. {
  682. if (closestHitShaderFunction)
  683. {
  684. return closestHitShaderFunction->zSignature();
  685. }
  686. if (anyHitShaderFunction)
  687. {
  688. return anyHitShaderFunction->zSignature();
  689. }
  690. if (intersectionShaderFunction)
  691. {
  692. return intersectionShaderFunction->zSignature();
  693. }
  694. return 0;
  695. }
  696. Framework::DX12Pipeline::DX12Pipeline()
  697. : ReferenceCounter(),
  698. emptyGlobalRootSignature(0),
  699. emptyLocalRootSignature(0),
  700. pipelineState(0),
  701. maxRecursionDepth(0)
  702. {}
  703. Framework::DX12Pipeline::~DX12Pipeline()
  704. {
  705. if (emptyGlobalRootSignature)
  706. {
  707. emptyGlobalRootSignature->Release();
  708. }
  709. if (emptyLocalRootSignature)
  710. {
  711. emptyLocalRootSignature->Release();
  712. }
  713. if (pipelineState)
  714. {
  715. pipelineState->Release();
  716. }
  717. }
  718. void Framework::DX12Pipeline::addShader(DX12Shader* shader)
  719. {
  720. shaders.add(shader);
  721. }
  722. void Framework::DX12Pipeline::addHitGroup(DX12ShaderHitGroup* hitGroup)
  723. {
  724. hitGroups.add(hitGroup);
  725. }
  726. void Framework::DX12Pipeline::setMaxRecursionDepth(int maxRecursionDepth)
  727. {
  728. this->maxRecursionDepth = maxRecursionDepth;
  729. }
  730. void Framework::DX12Pipeline::createPipelineState(ID3D12Device5* zDevice,
  731. PFN_D3D12_SERIALIZE_ROOT_SIGNATURE pfnD3D12SerializeRootSignature)
  732. {
  733. if (!emptyGlobalRootSignature)
  734. {
  735. D3D12_ROOT_SIGNATURE_DESC rootDesc = {};
  736. rootDesc.NumParameters = 0;
  737. rootDesc.pParameters = 0;
  738. rootDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
  739. ID3DBlob* pSigBlob = 0;
  740. ID3DBlob* pErrorBlob = 0;
  741. HRESULT hr = pfnD3D12SerializeRootSignature(
  742. &rootDesc, D3D_ROOT_SIGNATURE_VERSION_1_0, &pSigBlob, &pErrorBlob);
  743. if (pSigBlob)
  744. {
  745. zDevice->CreateRootSignature(0,
  746. pSigBlob->GetBufferPointer(),
  747. pSigBlob->GetBufferSize(),
  748. __uuidof(ID3D12RootSignature),
  749. (void**)&emptyGlobalRootSignature);
  750. pSigBlob->Release();
  751. }
  752. if (pErrorBlob)
  753. {
  754. std::string errorMessage(
  755. static_cast<const char*>(pErrorBlob->GetBufferPointer()),
  756. pErrorBlob->GetBufferSize());
  757. Logging::error()
  758. << "Failed to serialize empty root signature: " << errorMessage;
  759. pErrorBlob->Release();
  760. }
  761. }
  762. if (!emptyLocalRootSignature)
  763. {
  764. D3D12_ROOT_SIGNATURE_DESC rootDesc = {};
  765. rootDesc.NumParameters = 0;
  766. rootDesc.pParameters = 0;
  767. rootDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
  768. ID3DBlob* pSigBlob = 0;
  769. ID3DBlob* pErrorBlob = 0;
  770. HRESULT hr = pfnD3D12SerializeRootSignature(
  771. &rootDesc, D3D_ROOT_SIGNATURE_VERSION_1_0, &pSigBlob, &pErrorBlob);
  772. if (pSigBlob)
  773. {
  774. zDevice->CreateRootSignature(0,
  775. pSigBlob->GetBufferPointer(),
  776. pSigBlob->GetBufferSize(),
  777. __uuidof(ID3D12RootSignature),
  778. (void**)&emptyLocalRootSignature);
  779. pSigBlob->Release();
  780. }
  781. if (pErrorBlob)
  782. {
  783. std::string errorMessage(
  784. static_cast<const char*>(pErrorBlob->GetBufferPointer()),
  785. pErrorBlob->GetBufferSize());
  786. Logging::error()
  787. << "Failed to serialize empty root signature: " << errorMessage;
  788. pErrorBlob->Release();
  789. }
  790. }
  791. unsigned int subobjectCount
  792. = shaders.getEntryCount() + hitGroups.getEntryCount() + 5;
  793. Array<DX12ShaderSignature*> distinctSignatures;
  794. for (const DX12Shader* shader : shaders)
  795. {
  796. for (const DX12ShaderFunction* function : shader->getFunctions())
  797. {
  798. DX12ShaderSignature* signature = function->zSignature();
  799. if (distinctSignatures.getValueIndex(signature) < 0)
  800. {
  801. distinctSignatures.add(signature);
  802. }
  803. }
  804. }
  805. subobjectCount += distinctSignatures.getEntryCount()
  806. * 2; // Local root signatures for each distinct signature
  807. D3D12_STATE_SUBOBJECT* subobjects
  808. = new D3D12_STATE_SUBOBJECT[subobjectCount];
  809. int index = 0;
  810. for (const DX12Shader* shader : shaders)
  811. {
  812. subobjects[index].Type = D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY;
  813. subobjects[index].pDesc = shader->zLibraryDesc();
  814. index++;
  815. }
  816. int maxPayloadSize = 0;
  817. int maxAttributeSize = 0;
  818. for (const DX12ShaderHitGroup* hitGroup : hitGroups)
  819. {
  820. subobjects[index].Type = D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP;
  821. subobjects[index].pDesc = hitGroup->zHitGroupDesc();
  822. if (hitGroup->getPayloadSize() > maxPayloadSize)
  823. {
  824. maxPayloadSize = hitGroup->getPayloadSize();
  825. }
  826. if (hitGroup->getAttributeSize() > maxAttributeSize)
  827. {
  828. maxAttributeSize = hitGroup->getAttributeSize();
  829. }
  830. index++;
  831. }
  832. D3D12_RAYTRACING_SHADER_CONFIG shaderDesc = {};
  833. shaderDesc.MaxPayloadSizeInBytes = maxPayloadSize;
  834. shaderDesc.MaxAttributeSizeInBytes = maxAttributeSize;
  835. subobjects[index].Type
  836. = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG;
  837. subobjects[index].pDesc = &shaderDesc;
  838. index++;
  839. functionsWithoutHitGroups.clear();
  840. // create export list for hole pipeline with all hitgroups and all functions
  841. // that are not part of a hit group
  842. for (const DX12Shader* shader : shaders)
  843. {
  844. for (const DX12ShaderFunction* function : shader->getFunctions())
  845. {
  846. bool found = 0;
  847. for (const DX12ShaderHitGroup* hitGroup : hitGroups)
  848. {
  849. if (hitGroup->zClosestHitShaderFunction() == function
  850. || hitGroup->zAnyHitShaderFunction() == function
  851. || hitGroup->zIntersectionShaderFunction() == function)
  852. {
  853. found = 1;
  854. break;
  855. }
  856. }
  857. if (!found)
  858. {
  859. functionsWithoutHitGroups.add(function);
  860. }
  861. }
  862. }
  863. const wchar_t** functionAndHitGroupNames
  864. = new const wchar_t*[functionsWithoutHitGroups.getEntryCount()
  865. + hitGroups.getEntryCount()];
  866. int nameIndex = 0;
  867. for (const DX12ShaderFunction* function : functionsWithoutHitGroups)
  868. {
  869. functionAndHitGroupNames[nameIndex]
  870. = const_cast<wchar_t*>(function->zExportDesc()->Name);
  871. nameIndex++;
  872. }
  873. for (const DX12ShaderHitGroup* hitGroup : hitGroups)
  874. {
  875. functionAndHitGroupNames[nameIndex]
  876. = const_cast<wchar_t*>(hitGroup->zHitGroupDesc()->HitGroupExport);
  877. nameIndex++;
  878. }
  879. D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION shaderPayloadAssociation = {};
  880. shaderPayloadAssociation.NumExports
  881. = functionsWithoutHitGroups.getEntryCount() + hitGroups.getEntryCount();
  882. shaderPayloadAssociation.pExports = functionAndHitGroupNames;
  883. shaderPayloadAssociation.pSubobjectToAssociate
  884. = &subobjects[index - 1]; // shader config
  885. subobjects[index].Type
  886. = D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
  887. subobjects[index].pDesc = &shaderPayloadAssociation;
  888. index++;
  889. D3D12_LOCAL_ROOT_SIGNATURE* localRootSignatures
  890. = new D3D12_LOCAL_ROOT_SIGNATURE[distinctSignatures.getEntryCount()];
  891. int rootSignatureIndex = 0;
  892. const wchar_t*** rootSignatureExports
  893. = new const wchar_t**[distinctSignatures.getEntryCount()];
  894. D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION* localRootAssociations
  895. = new D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION[distinctSignatures
  896. .getEntryCount()];
  897. for (DX12ShaderSignature* signature : distinctSignatures)
  898. {
  899. signature->createSignature(zDevice, pfnD3D12SerializeRootSignature);
  900. subobjects[index].Type
  901. = D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE;
  902. localRootSignatures[rootSignatureIndex].pLocalRootSignature
  903. = signature->zSignature();
  904. subobjects[index].pDesc = &localRootSignatures[rootSignatureIndex];
  905. index++;
  906. Array<const DX12ShaderFunction*> functionsWithThisSignature;
  907. for (const DX12Shader* shader : shaders)
  908. {
  909. for (const DX12ShaderFunction* function : shader->getFunctions())
  910. {
  911. if (function->zSignature() == signature)
  912. {
  913. bool found = 0;
  914. for (DX12ShaderHitGroup* hitGroup : hitGroups)
  915. {
  916. if (hitGroup->zClosestHitShaderFunction() == function
  917. || hitGroup->zAnyHitShaderFunction() == function
  918. || hitGroup->zIntersectionShaderFunction()
  919. == function)
  920. {
  921. found = 1;
  922. break;
  923. }
  924. }
  925. if (!found)
  926. {
  927. functionsWithThisSignature.add(function);
  928. }
  929. }
  930. }
  931. }
  932. Array<const DX12ShaderHitGroup*> hitGroupsWithThisSignature;
  933. for (const DX12ShaderHitGroup* hitGroup : hitGroups)
  934. {
  935. if (hitGroup->zClosestHitShaderFunction()
  936. && hitGroup->zClosestHitShaderFunction()->zSignature()
  937. == signature)
  938. {
  939. hitGroupsWithThisSignature.add(hitGroup);
  940. }
  941. else if (hitGroup->zAnyHitShaderFunction()
  942. && hitGroup->zAnyHitShaderFunction()->zSignature()
  943. == signature)
  944. {
  945. hitGroupsWithThisSignature.add(hitGroup);
  946. }
  947. else if (hitGroup->zIntersectionShaderFunction()
  948. && hitGroup->zIntersectionShaderFunction()->zSignature()
  949. == signature)
  950. {
  951. hitGroupsWithThisSignature.add(hitGroup);
  952. }
  953. }
  954. rootSignatureExports[rootSignatureIndex]
  955. = new const wchar_t*[functionsWithThisSignature.getEntryCount()
  956. + hitGroupsWithThisSignature.getEntryCount()];
  957. int nameIndex = 0;
  958. for (const DX12ShaderFunction* function : functionsWithThisSignature)
  959. {
  960. rootSignatureExports[rootSignatureIndex][nameIndex]
  961. = function->zExportDesc()->Name;
  962. nameIndex++;
  963. }
  964. for (const DX12ShaderHitGroup* hitGroup : hitGroupsWithThisSignature)
  965. {
  966. rootSignatureExports[rootSignatureIndex][nameIndex]
  967. = hitGroup->zHitGroupDesc()->HitGroupExport;
  968. nameIndex++;
  969. }
  970. localRootAssociations[rootSignatureIndex].NumExports
  971. = functionsWithThisSignature.getEntryCount()
  972. + hitGroupsWithThisSignature.getEntryCount();
  973. localRootAssociations[rootSignatureIndex].pExports
  974. = rootSignatureExports[rootSignatureIndex];
  975. localRootAssociations[rootSignatureIndex].pSubobjectToAssociate
  976. = &subobjects[index - 1]; // local root signature
  977. subobjects[index].Type
  978. = D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
  979. subobjects[index].pDesc = &localRootAssociations[rootSignatureIndex];
  980. index++;
  981. rootSignatureIndex++;
  982. }
  983. subobjects[index].Type = D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE;
  984. subobjects[index].pDesc = &emptyGlobalRootSignature;
  985. index++;
  986. subobjects[index].Type = D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE;
  987. subobjects[index].pDesc = &emptyLocalRootSignature;
  988. index++;
  989. D3D12_RAYTRACING_PIPELINE_CONFIG pipelineConfig = {};
  990. pipelineConfig.MaxTraceRecursionDepth = maxRecursionDepth;
  991. subobjects[index].Type
  992. = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG;
  993. subobjects[index].pDesc = &pipelineConfig;
  994. index++;
  995. D3D12_STATE_OBJECT_DESC pipelineDesc = {};
  996. pipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE;
  997. pipelineDesc.NumSubobjects = subobjectCount;
  998. pipelineDesc.pSubobjects = subobjects;
  999. HRESULT hr = zDevice->CreateStateObject(
  1000. &pipelineDesc, __uuidof(ID3D12StateObject), (void**)&pipelineState);
  1001. if (FAILED(hr))
  1002. {
  1003. Logging::error()
  1004. << "Failed to create raytracing pipeline state object: " << std::hex
  1005. << hr;
  1006. throw std::logic_error("Could not create the raytracing state object");
  1007. }
  1008. /* delete[] functionAndHitGroupNames;
  1009. delete[] localRootSignatures;
  1010. for (int i = 0; i < distinctSignatures.getEntryCount(); i++)
  1011. {
  1012. delete[] rootSignatureExports[i];
  1013. }
  1014. delete[] rootSignatureExports;
  1015. delete[] localRootAssociations;*/
  1016. }
  1017. ID3D12StateObject* Framework::DX12Pipeline::zPipelineState() const
  1018. {
  1019. return pipelineState;
  1020. }
  1021. DX12ShaderBindingTable* Framework::DX12Pipeline::createShaderBindingTable()
  1022. {
  1023. return new DX12ShaderBindingTable(dynamic_cast<DX12Pipeline*>(getThis()));
  1024. }
  1025. DX12GlobalDescriptorHeap* Framework::DX12Pipeline::createGlobalDescriptorHeap(
  1026. DX12DescriptorHeapType type)
  1027. {
  1028. return new DX12GlobalDescriptorHeap(
  1029. dynamic_cast<DX12Pipeline*>(getThis()), type);
  1030. }
  1031. const RCArray<DX12Shader>& Framework::DX12Pipeline::getShaders() const
  1032. {
  1033. return shaders;
  1034. }
  1035. const Array<const DX12ShaderFunction*>&
  1036. Framework::DX12Pipeline::getFunctionsWithoutHitGroups() const
  1037. {
  1038. return functionsWithoutHitGroups;
  1039. }
  1040. const RCArray<DX12ShaderHitGroup>& Framework::DX12Pipeline::getHitGroups() const
  1041. {
  1042. return hitGroups;
  1043. }
  1044. Framework::DX12GlobalDescriptorHeap::DX12GlobalDescriptorHeap(
  1045. DX12Pipeline* pipeline, DX12DescriptorHeapType type)
  1046. : ReferenceCounter(),
  1047. pipeline(pipeline),
  1048. descriptorHeap(0),
  1049. lastDescriptorHeapSize(0),
  1050. zDevice(0),
  1051. type(type),
  1052. heapChanged(0)
  1053. {}
  1054. Framework::DX12GlobalDescriptorHeap::~DX12GlobalDescriptorHeap()
  1055. {
  1056. pipeline->release();
  1057. if (descriptorHeap)
  1058. {
  1059. descriptorHeap->Release();
  1060. }
  1061. for (const DX12ShaderRegisterInput* input : registerInputs)
  1062. {
  1063. input->inputResource->release();
  1064. delete input;
  1065. }
  1066. }
  1067. void Framework::DX12GlobalDescriptorHeap::addInput(
  1068. DX12ShaderRegister type, ReferenceCounter* inputResource)
  1069. {
  1070. bool found = 0;
  1071. for (DX12Shader* shader : pipeline->getShaders())
  1072. {
  1073. for (DX12ShaderFunction* function : shader->getFunctions())
  1074. {
  1075. for (const DX12ShaderRegisterUsage* usage :
  1076. function->zSignature()->getDescriptorHeapBindings())
  1077. {
  1078. if (usage->descriptorHeapIndex == registerInputs.getEntryCount()
  1079. && usage->descriptorHeapType == this->type)
  1080. {
  1081. if (usage->registerType != type)
  1082. {
  1083. Logging::error()
  1084. << "Register type mismatch for register index "
  1085. << usage->registerIndex << ", space index "
  1086. << usage->spaceIndex << ". Expected register type: "
  1087. << usage->registerType
  1088. << ", given register type: " << type
  1089. << ". The register type is specified in the "
  1090. "signature of shader function '"
  1091. << function->getFunctionName() << "'";
  1092. throw std::logic_error(
  1093. "Register type mismatch for shader input");
  1094. }
  1095. else
  1096. {
  1097. found = 1;
  1098. break;
  1099. }
  1100. }
  1101. }
  1102. if (found)
  1103. {
  1104. break;
  1105. }
  1106. }
  1107. if (found)
  1108. {
  1109. break;
  1110. }
  1111. }
  1112. registerInputs.add(new DX12ShaderRegisterInput{
  1113. type, inputResource ? inputResource->getThis() : 0});
  1114. }
  1115. void Framework::DX12GlobalDescriptorHeap::addTextureInput(
  1116. DX12ShaderRegister type, Texture* zTexture)
  1117. {
  1118. addInput(type, zTexture);
  1119. }
  1120. void Framework::DX12GlobalDescriptorHeap::updateTextureInput(
  1121. int heapIndex, DX12ShaderRegister type, Texture* zTexture)
  1122. {
  1123. DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
  1124. if (registerInputs.get(heapIndex)->inputResource
  1125. != dynamic_cast<ReferenceCounter*>(zTexture)
  1126. || zTexture->hasBufferChanged())
  1127. {
  1128. zTexture->setBufferChanged(0);
  1129. if (input->registerType != type)
  1130. {
  1131. Logging::error()
  1132. << "Register type mismatch for descriptor heap index "
  1133. << heapIndex
  1134. << ". Expected register type: " << input->registerType
  1135. << ", given register type: " << type << ".";
  1136. throw std::logic_error("Register type mismatch in descriptor heap");
  1137. }
  1138. registerInputs.get(heapIndex)->inputResource->release();
  1139. registerInputs.get(heapIndex)->inputResource = zTexture->getThis();
  1140. if (descriptorHeap)
  1141. {
  1142. D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
  1143. = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
  1144. descriptorHeapHandle.ptr
  1145. += zDevice->GetDescriptorHandleIncrementSize(
  1146. D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
  1147. * heapIndex;
  1148. switch (input->registerType)
  1149. {
  1150. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  1151. {
  1152. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
  1153. srvDesc.Format = DXGI_FORMAT_UNKNOWN;
  1154. srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
  1155. srvDesc.Texture2D.MipLevels = 0;
  1156. srvDesc.Texture2D.MostDetailedMip = 0;
  1157. srvDesc.Texture2D.PlaneSlice = 0;
  1158. srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
  1159. srvDesc.Shader4ComponentMapping
  1160. = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
  1161. zDevice->CreateShaderResourceView(
  1162. ((DX12Texture*)zTexture)->zResource(),
  1163. &srvDesc,
  1164. descriptorHeapHandle);
  1165. break;
  1166. }
  1167. case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
  1168. {
  1169. D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
  1170. uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
  1171. uavDesc.Format = DXGI_FORMAT_UNKNOWN;
  1172. uavDesc.Texture2D.MipSlice = 0;
  1173. uavDesc.Texture2D.PlaneSlice = 0;
  1174. zDevice->CreateUnorderedAccessView(
  1175. ((DX12Texture*)zTexture)->zResource(),
  1176. 0,
  1177. &uavDesc,
  1178. descriptorHeapHandle);
  1179. break;
  1180. }
  1181. }
  1182. }
  1183. }
  1184. }
  1185. void Framework::DX12GlobalDescriptorHeap::addBufferInput(
  1186. DX12ShaderRegister type, DXBuffer* zBuffer)
  1187. {
  1188. addInput(type, zBuffer);
  1189. }
  1190. void Framework::DX12GlobalDescriptorHeap::addTLASInput(
  1191. DX12ShaderRegister type, DX12TLAS* zTLAS)
  1192. {
  1193. addInput(type, zTLAS);
  1194. }
  1195. void Framework::DX12GlobalDescriptorHeap::updateTLASInput(
  1196. int heapIndex, DX12ShaderRegister type, DX12TLAS* zTLAS)
  1197. {
  1198. DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
  1199. if (registerInputs.get(heapIndex)->inputResource
  1200. != dynamic_cast<ReferenceCounter*>(zTLAS)
  1201. || zTLAS->hasBufferChanged())
  1202. {
  1203. zTLAS->setBufferChanged(0);
  1204. if (input->registerType != type)
  1205. {
  1206. Logging::error()
  1207. << "Register type mismatch for descriptor heap index "
  1208. << heapIndex
  1209. << ". Expected register type: " << input->registerType
  1210. << ", given register type: " << type << ".";
  1211. throw std::logic_error("Register type mismatch in descriptor heap");
  1212. }
  1213. if (registerInputs.get(heapIndex)->inputResource)
  1214. {
  1215. registerInputs.get(heapIndex)->inputResource->release();
  1216. }
  1217. registerInputs.get(heapIndex)->inputResource = zTLAS->getThis();
  1218. if (descriptorHeap)
  1219. {
  1220. D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
  1221. = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
  1222. descriptorHeapHandle.ptr
  1223. += zDevice->GetDescriptorHandleIncrementSize(
  1224. D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
  1225. * heapIndex;
  1226. switch (input->registerType)
  1227. {
  1228. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  1229. {
  1230. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
  1231. srvDesc.Format = DXGI_FORMAT_UNKNOWN;
  1232. srvDesc.ViewDimension
  1233. = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
  1234. srvDesc.RaytracingAccelerationStructure.Location
  1235. = zTLAS->zResultBuffer()
  1236. ->zBuffer()
  1237. ->GetGPUVirtualAddress();
  1238. srvDesc.Shader4ComponentMapping
  1239. = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
  1240. zDevice->CreateShaderResourceView(
  1241. 0, &srvDesc, descriptorHeapHandle);
  1242. break;
  1243. }
  1244. }
  1245. }
  1246. }
  1247. }
  1248. void Framework::DX12GlobalDescriptorHeap::addSamplerInput(
  1249. DX12SamplerState* zSampler)
  1250. {
  1251. addInput(DX12_SHADER_REGISTER_S_SAMPLER, zSampler);
  1252. }
  1253. void Framework::DX12GlobalDescriptorHeap::updateDescriptorHeap(
  1254. ID3D12Device5* zDevice)
  1255. {
  1256. this->zDevice = zDevice;
  1257. if (!descriptorHeap
  1258. || lastDescriptorHeapSize != registerInputs.getEntryCount())
  1259. {
  1260. if (descriptorHeap)
  1261. {
  1262. descriptorHeap->Release();
  1263. }
  1264. D3D12_DESCRIPTOR_HEAP_DESC desc = {};
  1265. desc.NumDescriptors = registerInputs.getEntryCount();
  1266. desc.Type = type == SAMPLER_DESCRIPTOR_HEAP
  1267. ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER
  1268. : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
  1269. desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
  1270. desc.NodeMask = 0;
  1271. HRESULT r = zDevice->CreateDescriptorHeap(
  1272. &desc, __uuidof(ID3D12DescriptorHeap), (void**)&descriptorHeap);
  1273. lastDescriptorHeapSize = registerInputs.getEntryCount();
  1274. heapChanged = 1;
  1275. }
  1276. D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
  1277. = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
  1278. for (const DX12ShaderRegisterInput* input : registerInputs)
  1279. {
  1280. DX12TLAS* zTLAS = dynamic_cast<DX12TLAS*>(input->inputResource);
  1281. DX12Texture* zTexture
  1282. = dynamic_cast<DX12Texture*>(input->inputResource);
  1283. if (zTexture && !zTexture->zResource())
  1284. {
  1285. zTexture = 0;
  1286. }
  1287. DX12Buffer* zBuffer = dynamic_cast<DX12Buffer*>(input->inputResource);
  1288. DX12SamplerState* zSampler
  1289. = dynamic_cast<DX12SamplerState*>(input->inputResource);
  1290. switch (input->registerType)
  1291. {
  1292. case DX12_SHADER_REGISTER_B_CONST_BUFFER:
  1293. {
  1294. D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
  1295. if (!zBuffer)
  1296. {
  1297. Logging::error()
  1298. << "Expected a buffer resource for register type "
  1299. << input->registerType;
  1300. throw std::logic_error(
  1301. "Expected a buffer resource for register type "
  1302. + std::to_string(input->registerType));
  1303. }
  1304. cbvDesc.BufferLocation
  1305. = zBuffer->zBuffer()->GetGPUVirtualAddress();
  1306. cbvDesc.SizeInBytes = (unsigned)zBuffer->getElementCount()
  1307. * zBuffer->getElementLength();
  1308. zDevice->CreateConstantBufferView(
  1309. &cbvDesc, descriptorHeapHandle);
  1310. break;
  1311. }
  1312. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  1313. {
  1314. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
  1315. srvDesc.Format = DXGI_FORMAT_UNKNOWN;
  1316. bool doNothing = 0;
  1317. if (zTLAS)
  1318. {
  1319. srvDesc.ViewDimension
  1320. = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
  1321. srvDesc.RaytracingAccelerationStructure.Location
  1322. = zTLAS->zResultBuffer()
  1323. ->zBuffer()
  1324. ->GetGPUVirtualAddress();
  1325. }
  1326. else if (zTexture)
  1327. {
  1328. srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
  1329. srvDesc.Texture2D.MipLevels = 1;
  1330. srvDesc.Texture2D.MostDetailedMip = 0;
  1331. srvDesc.Texture2D.PlaneSlice = 0;
  1332. srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
  1333. }
  1334. else if (zBuffer)
  1335. {
  1336. srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
  1337. srvDesc.Buffer.FirstElement = 0;
  1338. srvDesc.Buffer.NumElements
  1339. = (unsigned)zBuffer->getElementCount();
  1340. srvDesc.Buffer.StructureByteStride
  1341. = zBuffer->getElementLength();
  1342. srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
  1343. }
  1344. else if (zSampler)
  1345. {
  1346. Logging::error()
  1347. << "Expected a texture or buffer or TLAS resource for "
  1348. "register type "
  1349. << input->registerType;
  1350. throw std::logic_error(
  1351. "Expected a texture or buffer or TLAS resource for "
  1352. "register type "
  1353. + std::to_string(input->registerType));
  1354. }
  1355. else
  1356. {
  1357. doNothing = 1;
  1358. }
  1359. if (!doNothing)
  1360. {
  1361. srvDesc.Shader4ComponentMapping
  1362. = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
  1363. zDevice->CreateShaderResourceView(
  1364. zTexture ? zTexture->zResource()
  1365. : (zBuffer ? zBuffer->zBuffer() : 0),
  1366. &srvDesc,
  1367. descriptorHeapHandle);
  1368. }
  1369. break;
  1370. }
  1371. case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
  1372. {
  1373. D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
  1374. bool doNothing = 0;
  1375. if (zTexture)
  1376. {
  1377. uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
  1378. uavDesc.Format = DXGI_FORMAT_UNKNOWN;
  1379. uavDesc.Texture2D.MipSlice = 0;
  1380. uavDesc.Texture2D.PlaneSlice = 0;
  1381. }
  1382. else if (zBuffer)
  1383. {
  1384. uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
  1385. uavDesc.Buffer.FirstElement = 0;
  1386. uavDesc.Buffer.NumElements
  1387. = (unsigned)zBuffer->getElementCount();
  1388. uavDesc.Buffer.StructureByteStride
  1389. = zBuffer->getElementLength();
  1390. uavDesc.Buffer.CounterOffsetInBytes = 0;
  1391. uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
  1392. }
  1393. else if (zTLAS || zSampler)
  1394. {
  1395. Logging::error()
  1396. << "Expected a texture or buffer resource for "
  1397. "register type "
  1398. << input->registerType;
  1399. throw std::logic_error(
  1400. "Expected a texture or buffer resource for "
  1401. "register "
  1402. "type "
  1403. + std::to_string(input->registerType));
  1404. }
  1405. else
  1406. {
  1407. doNothing = 1;
  1408. }
  1409. if (!doNothing)
  1410. {
  1411. zDevice->CreateUnorderedAccessView(
  1412. zTexture ? zTexture->zResource() : zBuffer->zBuffer(),
  1413. 0,
  1414. &uavDesc,
  1415. descriptorHeapHandle);
  1416. }
  1417. break;
  1418. }
  1419. case DX12_SHADER_REGISTER_S_SAMPLER:
  1420. if (zSampler)
  1421. {
  1422. zDevice->CreateSampler(
  1423. zSampler->zSamplerDesc(), descriptorHeapHandle);
  1424. }
  1425. else
  1426. {
  1427. Logging::error()
  1428. << "Expected a sampler resource for register type "
  1429. << input->registerType;
  1430. throw std::logic_error(
  1431. "Expected a sampler resource for register type "
  1432. + std::to_string(input->registerType));
  1433. }
  1434. }
  1435. descriptorHeapHandle.ptr += zDevice->GetDescriptorHandleIncrementSize(
  1436. type == SAMPLER_DESCRIPTOR_HEAP
  1437. ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER
  1438. : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
  1439. }
  1440. }
  1441. DX12Pipeline* Framework::DX12GlobalDescriptorHeap::zPipeline() const
  1442. {
  1443. return pipeline;
  1444. }
  1445. ID3D12DescriptorHeap*
  1446. Framework::DX12GlobalDescriptorHeap::zDescriptorHeap() const
  1447. {
  1448. return descriptorHeap;
  1449. }
  1450. void Framework::DX12GlobalDescriptorHeap::setHeapChanged(bool changed)
  1451. {
  1452. heapChanged = changed;
  1453. }
  1454. bool Framework::DX12GlobalDescriptorHeap::wasHeapChanged() const
  1455. {
  1456. return heapChanged;
  1457. }
  1458. Framework::DX12ShaderBindingTable::DX12ShaderBindingTable(
  1459. DX12Pipeline* pipeline)
  1460. : ReferenceCounter(),
  1461. pipeline(pipeline),
  1462. shaderBindingTableBuffer(0),
  1463. globalDescriptorHeap(0),
  1464. textureDescriptorHeap(0),
  1465. samplerDescriptorHeap(0),
  1466. rayGenRecordSize(0),
  1467. rayGenCount(0),
  1468. missRecordSize(0),
  1469. missCount(0),
  1470. callableRecordSize(0),
  1471. callableCount(0),
  1472. hitGroupRecordSize(0),
  1473. hitGroupCount(0),
  1474. tableBuffer(0),
  1475. tableBufferSize(0),
  1476. nextHitGroupOffset(0),
  1477. stateObjectProperties(0)
  1478. {
  1479. pipeline->zPipelineState()->QueryInterface(
  1480. __uuidof(ID3D12StateObjectProperties), (void**)&stateObjectProperties);
  1481. }
  1482. Framework::DX12ShaderBindingTable::~DX12ShaderBindingTable()
  1483. {
  1484. stateObjectProperties->Release();
  1485. if (pipeline)
  1486. {
  1487. pipeline->release();
  1488. }
  1489. if (shaderBindingTableBuffer)
  1490. {
  1491. shaderBindingTableBuffer->release();
  1492. }
  1493. if (globalDescriptorHeap)
  1494. {
  1495. globalDescriptorHeap->release();
  1496. }
  1497. if (textureDescriptorHeap)
  1498. {
  1499. textureDescriptorHeap->release();
  1500. }
  1501. if (samplerDescriptorHeap)
  1502. {
  1503. samplerDescriptorHeap->release();
  1504. }
  1505. for (const char* buffer : tempBuffers)
  1506. {
  1507. delete[] buffer;
  1508. }
  1509. }
  1510. void Framework::DX12ShaderBindingTable::setGlobalDescriptorHeap(
  1511. DX12GlobalDescriptorHeap* zGlobalDescriptorHeap)
  1512. {
  1513. if (this->globalDescriptorHeap != zGlobalDescriptorHeap)
  1514. {
  1515. if (this->globalDescriptorHeap)
  1516. {
  1517. this->globalDescriptorHeap->release();
  1518. }
  1519. this->globalDescriptorHeap = zGlobalDescriptorHeap;
  1520. if (this->globalDescriptorHeap)
  1521. {
  1522. this->globalDescriptorHeap->getThis();
  1523. }
  1524. }
  1525. }
  1526. void Framework::DX12ShaderBindingTable::setTextureDescriptorHeap(
  1527. DX12GlobalDescriptorHeap* zTextureDescriptorHeap)
  1528. {
  1529. if (this->textureDescriptorHeap != zTextureDescriptorHeap)
  1530. {
  1531. if (this->textureDescriptorHeap)
  1532. {
  1533. this->textureDescriptorHeap->release();
  1534. }
  1535. this->textureDescriptorHeap = zTextureDescriptorHeap;
  1536. if (this->textureDescriptorHeap)
  1537. {
  1538. this->textureDescriptorHeap->getThis();
  1539. }
  1540. }
  1541. }
  1542. void Framework::DX12ShaderBindingTable::setSamplerDescriptorHeap(
  1543. DX12GlobalDescriptorHeap* zSamplerDescriptorHeap)
  1544. {
  1545. if (this->samplerDescriptorHeap != zSamplerDescriptorHeap)
  1546. {
  1547. if (this->samplerDescriptorHeap)
  1548. {
  1549. this->samplerDescriptorHeap->release();
  1550. }
  1551. this->samplerDescriptorHeap = zSamplerDescriptorHeap;
  1552. if (this->samplerDescriptorHeap)
  1553. {
  1554. this->samplerDescriptorHeap->getThis();
  1555. }
  1556. }
  1557. }
  1558. void Framework::DX12ShaderBindingTable::startUpdate()
  1559. {
  1560. if (shaderBindingTableBuffer)
  1561. {
  1562. shaderBindingTableBuffer->zBuffer()->Map(0, 0, (void**)&tableBuffer);
  1563. tableBufferSize = (int)shaderBindingTableBuffer->getElementCount()
  1564. * shaderBindingTableBuffer->getElementLength();
  1565. }
  1566. else
  1567. {
  1568. tableBuffer = 0;
  1569. tableBufferSize = 0;
  1570. }
  1571. rayGenRecordSize = 0;
  1572. rayGenCount = 0;
  1573. missRecordSize = 0;
  1574. missCount = 0;
  1575. callableRecordSize = 0;
  1576. callableCount = 0;
  1577. for (const DX12ShaderFunction* function :
  1578. pipeline->getFunctionsWithoutHitGroups())
  1579. {
  1580. DX12ShaderSignature* signature = function->zSignature();
  1581. if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_RAY_GEN)
  1582. {
  1583. if (rayGenRecordSize < signature->gerShaderBindingTableParamCount())
  1584. {
  1585. rayGenRecordSize = signature->gerShaderBindingTableParamCount();
  1586. }
  1587. rayGenCount++;
  1588. }
  1589. else if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_MISS)
  1590. {
  1591. if (missRecordSize < signature->gerShaderBindingTableParamCount())
  1592. {
  1593. missRecordSize = signature->gerShaderBindingTableParamCount();
  1594. }
  1595. missCount++;
  1596. }
  1597. else if (function->getFunctionType()
  1598. == DX12_SHADER_FUNCTION_TYPE_CALLABLE)
  1599. {
  1600. if (callableRecordSize
  1601. < signature->gerShaderBindingTableParamCount())
  1602. {
  1603. callableRecordSize
  1604. = signature->gerShaderBindingTableParamCount();
  1605. }
  1606. callableCount++;
  1607. }
  1608. }
  1609. rayGenRecordSize = ROUND_UP_POWER_OF_2(
  1610. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + rayGenRecordSize * 8,
  1611. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1612. missRecordSize = ROUND_UP_POWER_OF_2(
  1613. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + missRecordSize * 8,
  1614. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1615. callableRecordSize = ROUND_UP_POWER_OF_2(
  1616. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + callableRecordSize * 8,
  1617. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1618. hitGroupCount = 0;
  1619. hitGroupRecordSize = 0;
  1620. for (DX12ShaderHitGroup* hitGroup : pipeline->getHitGroups())
  1621. {
  1622. DX12ShaderSignature* signature = hitGroup->zSignature();
  1623. if (hitGroupRecordSize < signature->gerShaderBindingTableParamCount())
  1624. {
  1625. hitGroupRecordSize = signature->gerShaderBindingTableParamCount();
  1626. }
  1627. }
  1628. hitGroupRecordSize = ROUND_UP_POWER_OF_2(
  1629. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + hitGroupRecordSize * 8,
  1630. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1631. nextHitGroupOffset = ROUND_UP_POWER_OF_2(
  1632. rayGenRecordSize * rayGenCount + missRecordSize * missCount
  1633. + callableRecordSize * callableCount,
  1634. 64);
  1635. }
  1636. void Framework::DX12ShaderBindingTable::set(int index, void* data, int size)
  1637. {
  1638. if (tableBufferSize >= index + size)
  1639. {
  1640. memcpy(tableBuffer + index, data, size);
  1641. }
  1642. else
  1643. {
  1644. index -= tableBufferSize;
  1645. ArrayIterator<char*> it = tempBuffers.begin();
  1646. while (it && 2048 < index + size)
  1647. {
  1648. index -= 2048;
  1649. it++;
  1650. }
  1651. while (2048 < index + size)
  1652. {
  1653. char* newBuffer = new char[2048];
  1654. memset(newBuffer, 0, 2048);
  1655. tempBuffers.add(newBuffer);
  1656. index -= 2048;
  1657. }
  1658. // because the buffer size is allways rounded up to multiples
  1659. // of 32 and the size written at once is always 8 or 32 it
  1660. // should never be possible to have a negative index here
  1661. assert(index >= 0);
  1662. if (!it)
  1663. {
  1664. char* newBuffer = new char[2048];
  1665. memset(newBuffer, 0, 2048);
  1666. tempBuffers.add(newBuffer);
  1667. memcpy(newBuffer + index, data, size);
  1668. }
  1669. else
  1670. {
  1671. memcpy(it.val() + index, data, size);
  1672. }
  1673. }
  1674. }
  1675. void Framework::DX12ShaderBindingTable::setShaderInput(
  1676. DX12ShaderFunction* zFunction, int* offsetPointer, __int64 gpuAddress)
  1677. {
  1678. int index = 0;
  1679. for (const DX12ShaderFunction* pf :
  1680. pipeline->getFunctionsWithoutHitGroups())
  1681. {
  1682. if (pf == zFunction)
  1683. {
  1684. break;
  1685. }
  1686. if (pf->getFunctionType() == zFunction->getFunctionType())
  1687. {
  1688. index++;
  1689. }
  1690. }
  1691. int offset = 0;
  1692. if (zFunction->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_RAY_GEN)
  1693. {
  1694. offset = index * rayGenRecordSize;
  1695. }
  1696. else if (zFunction->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_MISS)
  1697. {
  1698. offset = rayGenRecordSize * rayGenCount + index * missRecordSize;
  1699. }
  1700. else if (zFunction->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_CALLABLE)
  1701. {
  1702. offset = rayGenRecordSize * rayGenCount + missRecordSize * missCount
  1703. + index * callableRecordSize;
  1704. }
  1705. else
  1706. {
  1707. throw std::logic_error("setShaderInput can only be used for ray "
  1708. "generation, miss, and callable "
  1709. "shader functions");
  1710. }
  1711. offset += D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT
  1712. + sizeof(__int64) * *offsetPointer;
  1713. set(offset, &gpuAddress, sizeof(__int64));
  1714. }
  1715. int Framework::DX12ShaderBindingTable::addHitGroup(
  1716. DX12ShaderHitGroup* zHitGroup, int lastIndex)
  1717. {
  1718. int index = nextHitGroupOffset;
  1719. bool changed
  1720. = index + D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT != lastIndex;
  1721. if (changed)
  1722. {
  1723. set(index,
  1724. stateObjectProperties->GetShaderIdentifier(
  1725. zHitGroup->zHitGroupDesc()->HitGroupExport),
  1726. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1727. }
  1728. index += D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
  1729. if (zHitGroup->zSignature()->doesUseGlobalDescriptorHeap())
  1730. {
  1731. if ((changed || globalDescriptorHeap->wasHeapChanged()))
  1732. {
  1733. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1734. = globalDescriptorHeap->zDescriptorHeap()
  1735. ->GetGPUDescriptorHandleForHeapStart();
  1736. set(index, &gpuAddress.ptr, sizeof(__int64));
  1737. }
  1738. index += sizeof(__int64);
  1739. }
  1740. if (zHitGroup->zSignature()->doesUseTextureDescriptorHeap())
  1741. {
  1742. if ((changed || textureDescriptorHeap->wasHeapChanged()))
  1743. {
  1744. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1745. = textureDescriptorHeap->zDescriptorHeap()
  1746. ->GetGPUDescriptorHandleForHeapStart();
  1747. set(index, &gpuAddress.ptr, sizeof(__int64));
  1748. }
  1749. index += sizeof(__int64);
  1750. }
  1751. if (zHitGroup->zSignature()->doesUseSamplerDescriptorHeap())
  1752. {
  1753. if ((changed || samplerDescriptorHeap->wasHeapChanged()))
  1754. {
  1755. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1756. = samplerDescriptorHeap->zDescriptorHeap()
  1757. ->GetGPUDescriptorHandleForHeapStart();
  1758. set(index, &gpuAddress.ptr, sizeof(__int64));
  1759. }
  1760. index += sizeof(__int64);
  1761. }
  1762. hitGroupCount++;
  1763. nextHitGroupOffset += hitGroupRecordSize;
  1764. return nextHitGroupOffset - hitGroupRecordSize
  1765. + D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
  1766. }
  1767. void Framework::DX12ShaderBindingTable::setHitGroupShaderInput(
  1768. int hitGroupOffset, int* offsetPointer, __int64 gpuAddress)
  1769. {
  1770. set(hitGroupOffset + sizeof(__int64) * *offsetPointer,
  1771. &gpuAddress,
  1772. sizeof(__int64));
  1773. }
  1774. void Framework::DX12ShaderBindingTable::endUpdate(
  1775. ID3D12Device5* zDevice, DX12CommandQueue* zQueue)
  1776. {
  1777. int rayTracingIndex = 0;
  1778. int missIndex = 0;
  1779. int callableIndex = 0;
  1780. for (const DX12ShaderFunction* function :
  1781. pipeline->getFunctionsWithoutHitGroups())
  1782. {
  1783. int offset = -1;
  1784. DX12ShaderSignature* signature = function->zSignature();
  1785. if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_RAY_GEN)
  1786. {
  1787. offset = rayTracingIndex * rayGenRecordSize;
  1788. rayTracingIndex++;
  1789. }
  1790. else if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_MISS)
  1791. {
  1792. offset
  1793. = rayGenRecordSize * rayGenCount + missIndex * missRecordSize;
  1794. missIndex++;
  1795. }
  1796. else if (function->getFunctionType()
  1797. == DX12_SHADER_FUNCTION_TYPE_CALLABLE)
  1798. {
  1799. offset = rayGenRecordSize * rayGenCount + missRecordSize * missCount
  1800. + callableIndex * callableRecordSize;
  1801. callableIndex++;
  1802. }
  1803. if (offset >= 0)
  1804. {
  1805. set(offset,
  1806. stateObjectProperties->GetShaderIdentifier(
  1807. function->zExportDesc()->Name),
  1808. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1809. offset += D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
  1810. if (function->zSignature()->doesUseGlobalDescriptorHeap())
  1811. {
  1812. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1813. = globalDescriptorHeap->zDescriptorHeap()
  1814. ->GetGPUDescriptorHandleForHeapStart();
  1815. set(offset, &gpuAddress.ptr, sizeof(__int64));
  1816. offset += sizeof(__int64);
  1817. }
  1818. if (function->zSignature()->doesUseTextureDescriptorHeap())
  1819. {
  1820. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1821. = textureDescriptorHeap->zDescriptorHeap()
  1822. ->GetGPUDescriptorHandleForHeapStart();
  1823. set(offset, &gpuAddress.ptr, sizeof(__int64));
  1824. offset += sizeof(__int64);
  1825. }
  1826. if (function->zSignature()->doesUseSamplerDescriptorHeap())
  1827. {
  1828. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1829. = samplerDescriptorHeap->zDescriptorHeap()
  1830. ->GetGPUDescriptorHandleForHeapStart();
  1831. set(offset, &gpuAddress.ptr, sizeof(__int64));
  1832. offset += sizeof(__int64);
  1833. }
  1834. }
  1835. }
  1836. if (nextHitGroupOffset > tableBufferSize)
  1837. {
  1838. DX12Buffer* newBuffer = new DX12Buffer(1,
  1839. zDevice,
  1840. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  1841. D3D12_RESOURCE_FLAG_NONE);
  1842. newBuffer->setLength(ROUND_UP_POWER_OF_2(nextHitGroupOffset, 256));
  1843. newBuffer->createBufferWithoutData(
  1844. D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_HEAP_TYPE_UPLOAD);
  1845. void* newTableBuffer = 0;
  1846. newBuffer->zBuffer()->Map(0, 0, (void**)&newTableBuffer);
  1847. int sizeToCopy = nextHitGroupOffset;
  1848. int index = 0;
  1849. if (tableBufferSize > 0)
  1850. {
  1851. memcpy(newTableBuffer, tableBuffer, tableBufferSize);
  1852. sizeToCopy -= tableBufferSize;
  1853. index = tableBufferSize;
  1854. }
  1855. for (char* buffer : tempBuffers)
  1856. {
  1857. int bytesToCopy = sizeToCopy < 2048 ? sizeToCopy : 2048;
  1858. memcpy((char*)newTableBuffer + index, buffer, bytesToCopy);
  1859. sizeToCopy -= bytesToCopy;
  1860. index += bytesToCopy;
  1861. if (sizeToCopy == 0)
  1862. {
  1863. break;
  1864. }
  1865. }
  1866. assert(sizeToCopy == 0);
  1867. newBuffer->zBuffer()->Unmap(0, 0);
  1868. if (shaderBindingTableBuffer)
  1869. {
  1870. shaderBindingTableBuffer->zBuffer()->Unmap(0, 0);
  1871. shaderBindingTableBuffer->release();
  1872. }
  1873. shaderBindingTableBuffer = newBuffer;
  1874. }
  1875. else
  1876. {
  1877. shaderBindingTableBuffer->zBuffer()->Unmap(0, 0);
  1878. }
  1879. }
  1880. void Framework::DX12ShaderBindingTable::fillDispatchRaysDesc(
  1881. D3D12_DISPATCH_RAYS_DESC* dispatchRaysDesc)
  1882. {
  1883. dispatchRaysDesc->RayGenerationShaderRecord.SizeInBytes
  1884. = rayGenCount * rayGenRecordSize;
  1885. dispatchRaysDesc->RayGenerationShaderRecord.StartAddress
  1886. = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress();
  1887. dispatchRaysDesc->MissShaderTable.SizeInBytes = missCount * missRecordSize;
  1888. dispatchRaysDesc->MissShaderTable.StartAddress
  1889. = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
  1890. + rayGenCount * rayGenRecordSize;
  1891. dispatchRaysDesc->MissShaderTable.StrideInBytes = missRecordSize;
  1892. dispatchRaysDesc->HitGroupTable.SizeInBytes
  1893. = hitGroupCount * hitGroupRecordSize;
  1894. dispatchRaysDesc->HitGroupTable.StartAddress
  1895. = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
  1896. + ROUND_UP_POWER_OF_2(rayGenCount * rayGenRecordSize
  1897. + missCount * missRecordSize
  1898. + callableCount * callableRecordSize,
  1899. 64);
  1900. dispatchRaysDesc->HitGroupTable.StrideInBytes = hitGroupRecordSize;
  1901. dispatchRaysDesc->CallableShaderTable.SizeInBytes
  1902. = callableCount * callableRecordSize;
  1903. dispatchRaysDesc->CallableShaderTable.StartAddress
  1904. = callableCount > 0
  1905. ? shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
  1906. + rayGenCount * rayGenRecordSize + missCount * missRecordSize
  1907. : 0;
  1908. dispatchRaysDesc->CallableShaderTable.StrideInBytes
  1909. = callableCount > 0 ? callableRecordSize : 0;
  1910. }
  1911. DX12Pipeline* Framework::DX12ShaderBindingTable::zPipeline() const
  1912. {
  1913. return pipeline;
  1914. }