DX12Shader.cpp 66 KB

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