DX12Shader.cpp 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945
  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* closestHitShaderFunction)
  492. {
  493. if (anyHitShaderFunction
  494. && anyHitShaderFunction->zSignature()
  495. != closestHitShaderFunction->zSignature())
  496. {
  497. Logging::error()
  498. << "Any-hit shader function and closest-hit shader "
  499. "function must have the same root signature when they are "
  500. "combined in the same hit group. HitGroup Name: '"
  501. << name << "' Any Hit Shader Function: '"
  502. << anyHitShaderFunction->getFunctionName().getText()
  503. << "' Closest Hit Shader Function: '"
  504. << closestHitShaderFunction->getFunctionName().getText() << "'";
  505. throw std::runtime_error("Incompatible root signatures in hit group");
  506. }
  507. if (intersectionShaderFunction
  508. && intersectionShaderFunction->zSignature()
  509. != closestHitShaderFunction->zSignature())
  510. {
  511. Logging::error()
  512. << "Intersection shader function and closest-hit shader "
  513. "function must have the same root signature when they are "
  514. "combined in the same hit group. HitGroup Name: '"
  515. << name << "' Intersection Shader Function: '"
  516. << intersectionShaderFunction->getFunctionName().getText()
  517. << "' Closest Hit Shader Function: '"
  518. << closestHitShaderFunction->getFunctionName().getText() << "'";
  519. throw std::runtime_error("Incompatible root signatures in hit group");
  520. }
  521. if (this->closestHitShaderFunction)
  522. {
  523. this->closestHitShaderFunction->release();
  524. }
  525. this->closestHitShaderFunction = closestHitShaderFunction;
  526. hitGroupDesc->ClosestHitShaderImport = 0;
  527. if (closestHitShaderFunction)
  528. {
  529. hitGroupDesc->ClosestHitShaderImport
  530. = closestHitShaderFunction->zExportDesc()->Name;
  531. }
  532. }
  533. void Framework::DX12ShaderHitGroup::setAnyHitShaderFunction(
  534. DX12ShaderFunction* anyHitShaderFunction)
  535. {
  536. if (closestHitShaderFunction
  537. && closestHitShaderFunction->zSignature()
  538. != anyHitShaderFunction->zSignature())
  539. {
  540. Logging::error()
  541. << "Any-hit shader function and closest-hit shader "
  542. "function must have the same root signature when they are "
  543. "combined in the same hit group. HitGroup Name: '"
  544. << name << "' Any Hit Shader Function: '"
  545. << anyHitShaderFunction->getFunctionName().getText()
  546. << "' Closest Hit Shader Function: '"
  547. << closestHitShaderFunction->getFunctionName().getText() << "'";
  548. throw std::runtime_error("Incompatible root signatures in hit group");
  549. }
  550. if (intersectionShaderFunction
  551. && intersectionShaderFunction->zSignature()
  552. != anyHitShaderFunction->zSignature())
  553. {
  554. Logging::error()
  555. << "Intersection shader function and any-hit shader "
  556. "function must have the same root signature when they are "
  557. "combined in the same hit group. HitGroup Name: '"
  558. << name << "' Intersection Shader Function: '"
  559. << intersectionShaderFunction->getFunctionName().getText()
  560. << "' Any Hit Shader Function: '"
  561. << anyHitShaderFunction->getFunctionName().getText() << "'";
  562. throw std::runtime_error("Incompatible root signatures in hit group");
  563. }
  564. if (this->anyHitShaderFunction)
  565. {
  566. this->anyHitShaderFunction->release();
  567. }
  568. this->anyHitShaderFunction = anyHitShaderFunction;
  569. hitGroupDesc->AnyHitShaderImport = 0;
  570. if (anyHitShaderFunction)
  571. {
  572. hitGroupDesc->AnyHitShaderImport
  573. = anyHitShaderFunction->zExportDesc()->Name;
  574. }
  575. }
  576. void Framework::DX12ShaderHitGroup::setIntersectionShaderFunction(
  577. DX12ShaderFunction* zIntersectionShaderFunction)
  578. {
  579. if (closestHitShaderFunction
  580. && closestHitShaderFunction->zSignature()
  581. != zIntersectionShaderFunction->zSignature())
  582. {
  583. Logging::error()
  584. << "Intersection shader function and closest-hit shader "
  585. "function must have the same root signature when they are "
  586. "combined in the same hit group. HitGroup Name: '"
  587. << name << "' Intersection Shader Function: '"
  588. << zIntersectionShaderFunction->getFunctionName().getText()
  589. << "' Closest Hit Shader Function: '"
  590. << closestHitShaderFunction->getFunctionName().getText() << "'";
  591. throw std::runtime_error("Incompatible root signatures in hit group");
  592. }
  593. if (anyHitShaderFunction
  594. && anyHitShaderFunction->zSignature()
  595. != zIntersectionShaderFunction->zSignature())
  596. {
  597. Logging::error()
  598. << "Intersection shader function and any-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. << "' Any Hit Shader Function: '"
  604. << anyHitShaderFunction->getFunctionName().getText() << "'";
  605. throw std::runtime_error("Incompatible root signatures in hit group");
  606. }
  607. if (intersectionShaderFunction)
  608. {
  609. intersectionShaderFunction->release();
  610. }
  611. intersectionShaderFunction = dynamic_cast<DX12ShaderFunction*>(
  612. zIntersectionShaderFunction->getThis());
  613. hitGroupDesc->IntersectionShaderImport = 0;
  614. if (intersectionShaderFunction)
  615. {
  616. hitGroupDesc->IntersectionShaderImport
  617. = intersectionShaderFunction->zExportDesc()->Name;
  618. }
  619. }
  620. void Framework::DX12ShaderHitGroup::setPayloadSize(int payloadSize)
  621. {
  622. this->payloadSize = payloadSize;
  623. }
  624. void Framework::DX12ShaderHitGroup::setAttributeSize(int attributeSize)
  625. {
  626. this->attributeSize = attributeSize;
  627. }
  628. const Text& Framework::DX12ShaderHitGroup::getName() const
  629. {
  630. return name;
  631. }
  632. DX12ShaderFunction*
  633. Framework::DX12ShaderHitGroup::zClosestHitShaderFunction() const
  634. {
  635. return closestHitShaderFunction;
  636. }
  637. DX12ShaderFunction* Framework::DX12ShaderHitGroup::zAnyHitShaderFunction() const
  638. {
  639. return anyHitShaderFunction;
  640. }
  641. DX12ShaderFunction*
  642. Framework::DX12ShaderHitGroup::zIntersectionShaderFunction() const
  643. {
  644. return intersectionShaderFunction;
  645. }
  646. int Framework::DX12ShaderHitGroup::getPayloadSize() const
  647. {
  648. return payloadSize;
  649. }
  650. int Framework::DX12ShaderHitGroup::getAttributeSize() const
  651. {
  652. return attributeSize;
  653. }
  654. D3D12_HIT_GROUP_DESC* Framework::DX12ShaderHitGroup::zHitGroupDesc() const
  655. {
  656. if (hitGroupDesc->IntersectionShaderImport)
  657. {
  658. hitGroupDesc->Type = D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE;
  659. }
  660. else
  661. {
  662. hitGroupDesc->Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
  663. }
  664. return hitGroupDesc;
  665. }
  666. DX12ShaderSignature* Framework::DX12ShaderHitGroup::zSignature() const
  667. {
  668. if (closestHitShaderFunction)
  669. {
  670. return closestHitShaderFunction->zSignature();
  671. }
  672. if (anyHitShaderFunction)
  673. {
  674. return anyHitShaderFunction->zSignature();
  675. }
  676. if (intersectionShaderFunction)
  677. {
  678. return intersectionShaderFunction->zSignature();
  679. }
  680. return 0;
  681. }
  682. Framework::DX12Pipeline::DX12Pipeline()
  683. : ReferenceCounter(),
  684. emptyGlobalRootSignature(0),
  685. emptyLocalRootSignature(0),
  686. pipelineState(0),
  687. maxRecursionDepth(0)
  688. {}
  689. Framework::DX12Pipeline::~DX12Pipeline()
  690. {
  691. if (emptyGlobalRootSignature)
  692. {
  693. emptyGlobalRootSignature->Release();
  694. }
  695. if (emptyLocalRootSignature)
  696. {
  697. emptyLocalRootSignature->Release();
  698. }
  699. if (pipelineState)
  700. {
  701. pipelineState->Release();
  702. }
  703. }
  704. void Framework::DX12Pipeline::addShader(DX12Shader* shader)
  705. {
  706. shaders.add(shader);
  707. }
  708. void Framework::DX12Pipeline::addHitGroup(DX12ShaderHitGroup* hitGroup)
  709. {
  710. hitGroups.add(hitGroup);
  711. }
  712. void Framework::DX12Pipeline::setMaxRecursionDepth(int maxRecursionDepth)
  713. {
  714. this->maxRecursionDepth = maxRecursionDepth;
  715. }
  716. void Framework::DX12Pipeline::createPipelineState(ID3D12Device5* zDevice,
  717. PFN_D3D12_SERIALIZE_ROOT_SIGNATURE pfnD3D12SerializeRootSignature)
  718. {
  719. if (!emptyGlobalRootSignature)
  720. {
  721. D3D12_ROOT_SIGNATURE_DESC rootDesc = {};
  722. rootDesc.NumParameters = 0;
  723. rootDesc.pParameters = 0;
  724. rootDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
  725. ID3DBlob* pSigBlob = 0;
  726. ID3DBlob* pErrorBlob = 0;
  727. HRESULT hr = pfnD3D12SerializeRootSignature(
  728. &rootDesc, D3D_ROOT_SIGNATURE_VERSION_1_0, &pSigBlob, &pErrorBlob);
  729. if (pSigBlob)
  730. {
  731. zDevice->CreateRootSignature(0,
  732. pSigBlob->GetBufferPointer(),
  733. pSigBlob->GetBufferSize(),
  734. __uuidof(ID3D12RootSignature),
  735. (void**)&emptyGlobalRootSignature);
  736. pSigBlob->Release();
  737. }
  738. if (pErrorBlob)
  739. {
  740. std::string errorMessage(
  741. static_cast<const char*>(pErrorBlob->GetBufferPointer()),
  742. pErrorBlob->GetBufferSize());
  743. Logging::error()
  744. << "Failed to serialize empty root signature: " << errorMessage;
  745. pErrorBlob->Release();
  746. }
  747. }
  748. if (!emptyLocalRootSignature)
  749. {
  750. D3D12_ROOT_SIGNATURE_DESC rootDesc = {};
  751. rootDesc.NumParameters = 0;
  752. rootDesc.pParameters = 0;
  753. rootDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
  754. ID3DBlob* pSigBlob = 0;
  755. ID3DBlob* pErrorBlob = 0;
  756. HRESULT hr = pfnD3D12SerializeRootSignature(
  757. &rootDesc, D3D_ROOT_SIGNATURE_VERSION_1_0, &pSigBlob, &pErrorBlob);
  758. if (pSigBlob)
  759. {
  760. zDevice->CreateRootSignature(0,
  761. pSigBlob->GetBufferPointer(),
  762. pSigBlob->GetBufferSize(),
  763. __uuidof(ID3D12RootSignature),
  764. (void**)&emptyLocalRootSignature);
  765. pSigBlob->Release();
  766. }
  767. if (pErrorBlob)
  768. {
  769. std::string errorMessage(
  770. static_cast<const char*>(pErrorBlob->GetBufferPointer()),
  771. pErrorBlob->GetBufferSize());
  772. Logging::error()
  773. << "Failed to serialize empty root signature: " << errorMessage;
  774. pErrorBlob->Release();
  775. }
  776. }
  777. unsigned int subobjectCount
  778. = shaders.getEntryCount() + hitGroups.getEntryCount() + 5;
  779. Array<DX12ShaderSignature*> distinctSignatures;
  780. for (const DX12Shader* shader : shaders)
  781. {
  782. for (const DX12ShaderFunction* function : shader->getFunctions())
  783. {
  784. DX12ShaderSignature* signature = function->zSignature();
  785. if (distinctSignatures.getValueIndex(signature) < 0)
  786. {
  787. distinctSignatures.add(signature);
  788. }
  789. }
  790. }
  791. subobjectCount += distinctSignatures.getEntryCount()
  792. * 2; // Local root signatures for each distinct signature
  793. D3D12_STATE_SUBOBJECT* subobjects
  794. = new D3D12_STATE_SUBOBJECT[subobjectCount];
  795. int index = 0;
  796. for (const DX12Shader* shader : shaders)
  797. {
  798. subobjects[index].Type = D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY;
  799. subobjects[index].pDesc = shader->zLibraryDesc();
  800. index++;
  801. }
  802. int maxPayloadSize = 0;
  803. int maxAttributeSize = 0;
  804. for (const DX12ShaderHitGroup* hitGroup : hitGroups)
  805. {
  806. subobjects[index].Type = D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP;
  807. subobjects[index].pDesc = hitGroup->zHitGroupDesc();
  808. if (hitGroup->getPayloadSize() > maxPayloadSize)
  809. {
  810. maxPayloadSize = hitGroup->getPayloadSize();
  811. }
  812. if (hitGroup->getAttributeSize() > maxAttributeSize)
  813. {
  814. maxAttributeSize = hitGroup->getAttributeSize();
  815. }
  816. index++;
  817. }
  818. D3D12_RAYTRACING_SHADER_CONFIG shaderDesc = {};
  819. shaderDesc.MaxPayloadSizeInBytes = maxPayloadSize;
  820. shaderDesc.MaxAttributeSizeInBytes = maxAttributeSize;
  821. subobjects[index].Type
  822. = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG;
  823. subobjects[index].pDesc = &shaderDesc;
  824. index++;
  825. functionsWithoutHitGroups.clear();
  826. // create export list for hole pipeline with all hitgroups and all functions
  827. // that are not part of a hit group
  828. for (const DX12Shader* shader : shaders)
  829. {
  830. for (const DX12ShaderFunction* function : shader->getFunctions())
  831. {
  832. bool found = 0;
  833. for (const DX12ShaderHitGroup* hitGroup : hitGroups)
  834. {
  835. if (hitGroup->zClosestHitShaderFunction() == function
  836. || hitGroup->zAnyHitShaderFunction() == function
  837. || hitGroup->zIntersectionShaderFunction() == function)
  838. {
  839. found = 1;
  840. break;
  841. }
  842. }
  843. if (!found)
  844. {
  845. functionsWithoutHitGroups.add(function);
  846. }
  847. }
  848. }
  849. const wchar_t** functionAndHitGroupNames
  850. = new const wchar_t*[functionsWithoutHitGroups.getEntryCount()
  851. + hitGroups.getEntryCount()];
  852. int nameIndex = 0;
  853. for (const DX12ShaderFunction* function : functionsWithoutHitGroups)
  854. {
  855. functionAndHitGroupNames[nameIndex]
  856. = const_cast<wchar_t*>(function->zExportDesc()->Name);
  857. nameIndex++;
  858. }
  859. for (const DX12ShaderHitGroup* hitGroup : hitGroups)
  860. {
  861. functionAndHitGroupNames[nameIndex]
  862. = const_cast<wchar_t*>(hitGroup->zHitGroupDesc()->HitGroupExport);
  863. nameIndex++;
  864. }
  865. D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION shaderPayloadAssociation = {};
  866. shaderPayloadAssociation.NumExports
  867. = functionsWithoutHitGroups.getEntryCount() + hitGroups.getEntryCount();
  868. shaderPayloadAssociation.pExports = functionAndHitGroupNames;
  869. shaderPayloadAssociation.pSubobjectToAssociate
  870. = &subobjects[index - 1]; // shader config
  871. subobjects[index].Type
  872. = D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
  873. subobjects[index].pDesc = &shaderPayloadAssociation;
  874. index++;
  875. D3D12_LOCAL_ROOT_SIGNATURE* localRootSignatures
  876. = new D3D12_LOCAL_ROOT_SIGNATURE[distinctSignatures.getEntryCount()];
  877. int rootSignatureIndex = 0;
  878. const wchar_t*** rootSignatureExports
  879. = new const wchar_t**[distinctSignatures.getEntryCount()];
  880. D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION* localRootAssociations
  881. = new D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION[distinctSignatures
  882. .getEntryCount()];
  883. for (DX12ShaderSignature* signature : distinctSignatures)
  884. {
  885. signature->createSignature(zDevice, pfnD3D12SerializeRootSignature);
  886. subobjects[index].Type
  887. = D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE;
  888. localRootSignatures[rootSignatureIndex].pLocalRootSignature
  889. = signature->zSignature();
  890. subobjects[index].pDesc = &localRootSignatures[rootSignatureIndex];
  891. index++;
  892. Array<const DX12ShaderFunction*> functionsWithThisSignature;
  893. for (const DX12Shader* shader : shaders)
  894. {
  895. for (const DX12ShaderFunction* function : shader->getFunctions())
  896. {
  897. if (function->zSignature() == signature)
  898. {
  899. bool found = 0;
  900. for (DX12ShaderHitGroup* hitGroup : hitGroups)
  901. {
  902. if (hitGroup->zClosestHitShaderFunction() == function
  903. || hitGroup->zAnyHitShaderFunction() == function
  904. || hitGroup->zIntersectionShaderFunction()
  905. == function)
  906. {
  907. found = 1;
  908. break;
  909. }
  910. }
  911. if (!found)
  912. {
  913. functionsWithThisSignature.add(function);
  914. }
  915. }
  916. }
  917. }
  918. Array<const DX12ShaderHitGroup*> hitGroupsWithThisSignature;
  919. for (const DX12ShaderHitGroup* hitGroup : hitGroups)
  920. {
  921. if (hitGroup->zClosestHitShaderFunction()
  922. && hitGroup->zClosestHitShaderFunction()->zSignature()
  923. == signature)
  924. {
  925. hitGroupsWithThisSignature.add(hitGroup);
  926. }
  927. else if (hitGroup->zAnyHitShaderFunction()
  928. && hitGroup->zAnyHitShaderFunction()->zSignature()
  929. == signature)
  930. {
  931. hitGroupsWithThisSignature.add(hitGroup);
  932. }
  933. else if (hitGroup->zIntersectionShaderFunction()
  934. && hitGroup->zIntersectionShaderFunction()->zSignature()
  935. == signature)
  936. {
  937. hitGroupsWithThisSignature.add(hitGroup);
  938. }
  939. }
  940. rootSignatureExports[rootSignatureIndex]
  941. = new const wchar_t*[functionsWithThisSignature.getEntryCount()
  942. + hitGroupsWithThisSignature.getEntryCount()];
  943. int nameIndex = 0;
  944. for (const DX12ShaderFunction* function : functionsWithThisSignature)
  945. {
  946. rootSignatureExports[rootSignatureIndex][nameIndex]
  947. = function->zExportDesc()->Name;
  948. nameIndex++;
  949. }
  950. for (const DX12ShaderHitGroup* hitGroup : hitGroupsWithThisSignature)
  951. {
  952. rootSignatureExports[rootSignatureIndex][nameIndex]
  953. = hitGroup->zHitGroupDesc()->HitGroupExport;
  954. nameIndex++;
  955. }
  956. localRootAssociations[rootSignatureIndex].NumExports
  957. = functionsWithThisSignature.getEntryCount()
  958. + hitGroupsWithThisSignature.getEntryCount();
  959. localRootAssociations[rootSignatureIndex].pExports
  960. = rootSignatureExports[rootSignatureIndex];
  961. localRootAssociations[rootSignatureIndex].pSubobjectToAssociate
  962. = &subobjects[index - 1]; // local root signature
  963. subobjects[index].Type
  964. = D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
  965. subobjects[index].pDesc = &localRootAssociations[rootSignatureIndex];
  966. index++;
  967. rootSignatureIndex++;
  968. }
  969. subobjects[index].Type = D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE;
  970. subobjects[index].pDesc = &emptyGlobalRootSignature;
  971. index++;
  972. subobjects[index].Type = D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE;
  973. subobjects[index].pDesc = &emptyLocalRootSignature;
  974. index++;
  975. D3D12_RAYTRACING_PIPELINE_CONFIG pipelineConfig = {};
  976. pipelineConfig.MaxTraceRecursionDepth = maxRecursionDepth;
  977. subobjects[index].Type
  978. = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG;
  979. subobjects[index].pDesc = &pipelineConfig;
  980. index++;
  981. D3D12_STATE_OBJECT_DESC pipelineDesc = {};
  982. pipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE;
  983. pipelineDesc.NumSubobjects = subobjectCount;
  984. pipelineDesc.pSubobjects = subobjects;
  985. HRESULT hr = zDevice->CreateStateObject(
  986. &pipelineDesc, __uuidof(ID3D12StateObject), (void**)&pipelineState);
  987. if (FAILED(hr))
  988. {
  989. Logging::error()
  990. << "Failed to create raytracing pipeline state object: " << std::hex
  991. << hr;
  992. throw std::logic_error("Could not create the raytracing state object");
  993. }
  994. /* delete[] functionAndHitGroupNames;
  995. delete[] localRootSignatures;
  996. for (int i = 0; i < distinctSignatures.getEntryCount(); i++)
  997. {
  998. delete[] rootSignatureExports[i];
  999. }
  1000. delete[] rootSignatureExports;
  1001. delete[] localRootAssociations;*/
  1002. }
  1003. ID3D12StateObject* Framework::DX12Pipeline::zPipelineState() const
  1004. {
  1005. return pipelineState;
  1006. }
  1007. DX12ShaderBindingTable* Framework::DX12Pipeline::createShaderBindingTable()
  1008. {
  1009. return new DX12ShaderBindingTable(dynamic_cast<DX12Pipeline*>(getThis()));
  1010. }
  1011. DX12GlobalDescriptorHeap* Framework::DX12Pipeline::createGlobalDescriptorHeap(
  1012. DX12DescriptorHeapType type)
  1013. {
  1014. return new DX12GlobalDescriptorHeap(
  1015. dynamic_cast<DX12Pipeline*>(getThis()), type);
  1016. }
  1017. const RCArray<DX12Shader>& Framework::DX12Pipeline::getShaders() const
  1018. {
  1019. return shaders;
  1020. }
  1021. const Array<const DX12ShaderFunction*>&
  1022. Framework::DX12Pipeline::getFunctionsWithoutHitGroups() const
  1023. {
  1024. return functionsWithoutHitGroups;
  1025. }
  1026. const RCArray<DX12ShaderHitGroup>& Framework::DX12Pipeline::getHitGroups() const
  1027. {
  1028. return hitGroups;
  1029. }
  1030. Framework::DX12GlobalDescriptorHeap::DX12GlobalDescriptorHeap(
  1031. DX12Pipeline* pipeline, DX12DescriptorHeapType type)
  1032. : ReferenceCounter(),
  1033. pipeline(pipeline),
  1034. descriptorHeap(0),
  1035. lastDescriptorHeapSize(0),
  1036. zDevice(0),
  1037. type(type)
  1038. {}
  1039. Framework::DX12GlobalDescriptorHeap::~DX12GlobalDescriptorHeap()
  1040. {
  1041. pipeline->release();
  1042. if (descriptorHeap)
  1043. {
  1044. descriptorHeap->Release();
  1045. }
  1046. for (const DX12ShaderRegisterInput* input : registerInputs)
  1047. {
  1048. input->inputResource->release();
  1049. delete input;
  1050. }
  1051. }
  1052. void Framework::DX12GlobalDescriptorHeap::addInput(
  1053. DX12ShaderRegister type, ReferenceCounter* inputResource)
  1054. {
  1055. bool found = 0;
  1056. for (DX12Shader* shader : pipeline->getShaders())
  1057. {
  1058. for (DX12ShaderFunction* function : shader->getFunctions())
  1059. {
  1060. for (const DX12ShaderRegisterUsage* usage :
  1061. function->zSignature()->getDescriptorHeapBindings())
  1062. {
  1063. if (usage->descriptorHeapIndex == registerInputs.getEntryCount()
  1064. && usage->descriptorHeapType == this->type)
  1065. {
  1066. if (usage->registerType != type)
  1067. {
  1068. Logging::error()
  1069. << "Register type mismatch for register index "
  1070. << usage->registerIndex << ", space index "
  1071. << usage->spaceIndex << ". Expected register type: "
  1072. << usage->registerType
  1073. << ", given register type: " << type
  1074. << ". The register type is specified in the "
  1075. "signature of shader function '"
  1076. << function->getFunctionName() << "'";
  1077. throw std::logic_error(
  1078. "Register type mismatch for shader input");
  1079. }
  1080. else
  1081. {
  1082. found = 1;
  1083. break;
  1084. }
  1085. }
  1086. }
  1087. if (found)
  1088. {
  1089. break;
  1090. }
  1091. }
  1092. if (found)
  1093. {
  1094. break;
  1095. }
  1096. }
  1097. registerInputs.add(new DX12ShaderRegisterInput{
  1098. type, inputResource ? inputResource->getThis() : 0});
  1099. }
  1100. void Framework::DX12GlobalDescriptorHeap::addTextureInput(
  1101. DX12ShaderRegister type, Texture* zTexture)
  1102. {
  1103. addInput(type, zTexture);
  1104. }
  1105. void Framework::DX12GlobalDescriptorHeap::updateTextureInput(
  1106. int heapIndex, DX12ShaderRegister type, Texture* zTexture)
  1107. {
  1108. DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
  1109. if (registerInputs.get(heapIndex)->inputResource
  1110. != dynamic_cast<ReferenceCounter*>(zTexture)
  1111. || zTexture->hasBufferChanged())
  1112. {
  1113. zTexture->setBufferChanged(0);
  1114. if (input->registerType != type)
  1115. {
  1116. Logging::error()
  1117. << "Register type mismatch for descriptor heap index "
  1118. << heapIndex
  1119. << ". Expected register type: " << input->registerType
  1120. << ", given register type: " << type << ".";
  1121. throw std::logic_error("Register type mismatch in descriptor heap");
  1122. }
  1123. registerInputs.get(heapIndex)->inputResource->release();
  1124. registerInputs.get(heapIndex)->inputResource = zTexture->getThis();
  1125. if (descriptorHeap)
  1126. {
  1127. D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
  1128. = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
  1129. descriptorHeapHandle.ptr
  1130. += zDevice->GetDescriptorHandleIncrementSize(
  1131. D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
  1132. * heapIndex;
  1133. switch (input->registerType)
  1134. {
  1135. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  1136. {
  1137. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
  1138. srvDesc.Format = DXGI_FORMAT_UNKNOWN;
  1139. srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
  1140. srvDesc.Texture2D.MipLevels = 0;
  1141. srvDesc.Texture2D.MostDetailedMip = 0;
  1142. srvDesc.Texture2D.PlaneSlice = 0;
  1143. srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
  1144. srvDesc.Shader4ComponentMapping
  1145. = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
  1146. zDevice->CreateShaderResourceView(
  1147. ((DX12Texture*)zTexture)->zResource(),
  1148. &srvDesc,
  1149. descriptorHeapHandle);
  1150. break;
  1151. }
  1152. case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
  1153. {
  1154. D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
  1155. uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
  1156. uavDesc.Format = DXGI_FORMAT_UNKNOWN;
  1157. uavDesc.Texture2D.MipSlice = 0;
  1158. uavDesc.Texture2D.PlaneSlice = 0;
  1159. zDevice->CreateUnorderedAccessView(
  1160. ((DX12Texture*)zTexture)->zResource(),
  1161. 0,
  1162. &uavDesc,
  1163. descriptorHeapHandle);
  1164. break;
  1165. }
  1166. }
  1167. }
  1168. }
  1169. }
  1170. void Framework::DX12GlobalDescriptorHeap::addBufferInput(
  1171. DX12ShaderRegister type, DXBuffer* zBuffer)
  1172. {
  1173. addInput(type, zBuffer);
  1174. }
  1175. void Framework::DX12GlobalDescriptorHeap::addTLASInput(
  1176. DX12ShaderRegister type, DX12TLAS* zTLAS)
  1177. {
  1178. addInput(type, zTLAS);
  1179. }
  1180. void Framework::DX12GlobalDescriptorHeap::updateTLASInput(
  1181. int heapIndex, DX12ShaderRegister type, DX12TLAS* zTLAS)
  1182. {
  1183. DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
  1184. if (registerInputs.get(heapIndex)->inputResource
  1185. != dynamic_cast<ReferenceCounter*>(zTLAS)
  1186. || zTLAS->hasBufferChanged())
  1187. {
  1188. zTLAS->setBufferChanged(0);
  1189. if (input->registerType != type)
  1190. {
  1191. Logging::error()
  1192. << "Register type mismatch for descriptor heap index "
  1193. << heapIndex
  1194. << ". Expected register type: " << input->registerType
  1195. << ", given register type: " << type << ".";
  1196. throw std::logic_error("Register type mismatch in descriptor heap");
  1197. }
  1198. if (registerInputs.get(heapIndex)->inputResource)
  1199. {
  1200. registerInputs.get(heapIndex)->inputResource->release();
  1201. }
  1202. registerInputs.get(heapIndex)->inputResource = zTLAS->getThis();
  1203. if (descriptorHeap)
  1204. {
  1205. D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
  1206. = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
  1207. descriptorHeapHandle.ptr
  1208. += zDevice->GetDescriptorHandleIncrementSize(
  1209. D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
  1210. * heapIndex;
  1211. switch (input->registerType)
  1212. {
  1213. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  1214. {
  1215. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
  1216. srvDesc.Format = DXGI_FORMAT_UNKNOWN;
  1217. srvDesc.ViewDimension
  1218. = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
  1219. srvDesc.RaytracingAccelerationStructure.Location
  1220. = zTLAS->zResultBuffer()
  1221. ->zBuffer()
  1222. ->GetGPUVirtualAddress();
  1223. srvDesc.Shader4ComponentMapping
  1224. = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
  1225. zDevice->CreateShaderResourceView(
  1226. 0, &srvDesc, descriptorHeapHandle);
  1227. break;
  1228. }
  1229. }
  1230. }
  1231. }
  1232. }
  1233. void Framework::DX12GlobalDescriptorHeap::addSamplerInput(
  1234. DX12SamplerState* zSampler)
  1235. {
  1236. addInput(DX12_SHADER_REGISTER_S_SAMPLER, zSampler);
  1237. }
  1238. void Framework::DX12GlobalDescriptorHeap::updateDescriptorHeap(
  1239. ID3D12Device5* zDevice)
  1240. {
  1241. this->zDevice = zDevice;
  1242. if (!descriptorHeap
  1243. || lastDescriptorHeapSize != registerInputs.getEntryCount())
  1244. {
  1245. if (descriptorHeap)
  1246. {
  1247. descriptorHeap->Release();
  1248. }
  1249. D3D12_DESCRIPTOR_HEAP_DESC desc = {};
  1250. desc.NumDescriptors = registerInputs.getEntryCount();
  1251. desc.Type = type == SAMPLER_DESCRIPTOR_HEAP
  1252. ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER :
  1253. D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
  1254. desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
  1255. desc.NodeMask = 0;
  1256. HRESULT r = zDevice->CreateDescriptorHeap(
  1257. &desc, __uuidof(ID3D12DescriptorHeap), (void**)&descriptorHeap);
  1258. lastDescriptorHeapSize = registerInputs.getEntryCount();
  1259. }
  1260. D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
  1261. = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
  1262. for (const DX12ShaderRegisterInput* input : registerInputs)
  1263. {
  1264. DX12TLAS* zTLAS = dynamic_cast<DX12TLAS*>(input->inputResource);
  1265. DX12Texture* zTexture
  1266. = dynamic_cast<DX12Texture*>(input->inputResource);
  1267. DX12Buffer* zBuffer = dynamic_cast<DX12Buffer*>(input->inputResource);
  1268. DX12SamplerState* zSampler
  1269. = dynamic_cast<DX12SamplerState*>(input->inputResource);
  1270. switch (input->registerType)
  1271. {
  1272. case DX12_SHADER_REGISTER_B_CONST_BUFFER:
  1273. {
  1274. D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
  1275. if (!zBuffer)
  1276. {
  1277. Logging::error()
  1278. << "Expected a buffer resource for register type "
  1279. << input->registerType;
  1280. throw std::logic_error(
  1281. "Expected a buffer resource for register type "
  1282. + std::to_string(input->registerType));
  1283. }
  1284. cbvDesc.BufferLocation
  1285. = zBuffer->zBuffer()->GetGPUVirtualAddress();
  1286. cbvDesc.SizeInBytes = (unsigned)zBuffer->getElementCount()
  1287. * zBuffer->getElementLength();
  1288. zDevice->CreateConstantBufferView(
  1289. &cbvDesc, descriptorHeapHandle);
  1290. break;
  1291. }
  1292. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  1293. {
  1294. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
  1295. srvDesc.Format = DXGI_FORMAT_UNKNOWN;
  1296. bool doNothing = 0;
  1297. if (zTLAS)
  1298. {
  1299. srvDesc.ViewDimension
  1300. = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
  1301. srvDesc.RaytracingAccelerationStructure.Location
  1302. = zTLAS->zResultBuffer()
  1303. ->zBuffer()
  1304. ->GetGPUVirtualAddress();
  1305. }
  1306. else if (zTexture)
  1307. {
  1308. srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
  1309. srvDesc.Texture2D.MipLevels = 1;
  1310. srvDesc.Texture2D.MostDetailedMip = 0;
  1311. srvDesc.Texture2D.PlaneSlice = 0;
  1312. srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
  1313. }
  1314. else if (zBuffer)
  1315. {
  1316. srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
  1317. srvDesc.Buffer.FirstElement = 0;
  1318. srvDesc.Buffer.NumElements
  1319. = (unsigned)zBuffer->getElementCount();
  1320. srvDesc.Buffer.StructureByteStride
  1321. = zBuffer->getElementLength();
  1322. srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
  1323. }
  1324. else
  1325. {
  1326. doNothing = 1;
  1327. }
  1328. if (!doNothing)
  1329. {
  1330. srvDesc.Shader4ComponentMapping
  1331. = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
  1332. zDevice->CreateShaderResourceView(
  1333. zTexture ? zTexture->zResource()
  1334. : (zBuffer ? zBuffer->zBuffer() : 0),
  1335. &srvDesc,
  1336. descriptorHeapHandle);
  1337. }
  1338. break;
  1339. }
  1340. case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
  1341. {
  1342. D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
  1343. if (zTexture)
  1344. {
  1345. uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
  1346. uavDesc.Format = DXGI_FORMAT_UNKNOWN;
  1347. uavDesc.Texture2D.MipSlice = 0;
  1348. uavDesc.Texture2D.PlaneSlice = 0;
  1349. }
  1350. else if (zBuffer)
  1351. {
  1352. uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
  1353. uavDesc.Buffer.FirstElement = 0;
  1354. uavDesc.Buffer.NumElements
  1355. = (unsigned)zBuffer->getElementCount();
  1356. uavDesc.Buffer.StructureByteStride
  1357. = zBuffer->getElementLength();
  1358. uavDesc.Buffer.CounterOffsetInBytes = 0;
  1359. uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
  1360. }
  1361. else
  1362. {
  1363. Logging::error()
  1364. << "Expected a texture or buffer resource for "
  1365. "register type "
  1366. << input->registerType;
  1367. throw std::logic_error(
  1368. "Expected a texture or buffer resource for "
  1369. "register "
  1370. "type "
  1371. + std::to_string(input->registerType));
  1372. }
  1373. zDevice->CreateUnorderedAccessView(
  1374. zTexture ? zTexture->zResource() : zBuffer->zBuffer(),
  1375. 0,
  1376. &uavDesc,
  1377. descriptorHeapHandle);
  1378. break;
  1379. }
  1380. case DX12_SHADER_REGISTER_S_SAMPLER:
  1381. if (zSampler)
  1382. {
  1383. zDevice->CreateSampler(
  1384. zSampler->zSamplerDesc(), descriptorHeapHandle);
  1385. }
  1386. else
  1387. {
  1388. Logging::error()
  1389. << "Expected a sampler resource for register type "
  1390. << input->registerType;
  1391. throw std::logic_error(
  1392. "Expected a sampler resource for register type "
  1393. + std::to_string(input->registerType));
  1394. }
  1395. }
  1396. descriptorHeapHandle.ptr += zDevice->GetDescriptorHandleIncrementSize(
  1397. D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
  1398. }
  1399. }
  1400. DX12Pipeline* Framework::DX12GlobalDescriptorHeap::zPipeline() const
  1401. {
  1402. return pipeline;
  1403. }
  1404. ID3D12DescriptorHeap*
  1405. Framework::DX12GlobalDescriptorHeap::zDescriptorHeap() const
  1406. {
  1407. return descriptorHeap;
  1408. }
  1409. Framework::DX12ShaderBindingTable::DX12ShaderBindingTable(
  1410. DX12Pipeline* pipeline)
  1411. : ReferenceCounter(),
  1412. pipeline(pipeline),
  1413. shaderBindingTableBuffer(0),
  1414. globalDescriptorHeap(0),
  1415. textureDescriptorHeap(0),
  1416. samplerDescriptorHeap(0),
  1417. rayGenRecordSize(0),
  1418. rayGenCount(0),
  1419. missRecordSize(0),
  1420. missCount(0),
  1421. callableRecordSize(0),
  1422. callableCount(0),
  1423. hitGroupRecordSize(0),
  1424. hitGroupCount(0),
  1425. tableBuffer(0),
  1426. tableBufferSize(0),
  1427. nextHitGroupOffset(0),
  1428. stateObjectProperties(0)
  1429. {
  1430. pipeline->zPipelineState()->QueryInterface(
  1431. __uuidof(ID3D12StateObjectProperties), (void**)&stateObjectProperties);
  1432. }
  1433. Framework::DX12ShaderBindingTable::~DX12ShaderBindingTable()
  1434. {
  1435. stateObjectProperties->Release();
  1436. if (pipeline)
  1437. {
  1438. pipeline->release();
  1439. }
  1440. if (shaderBindingTableBuffer)
  1441. {
  1442. shaderBindingTableBuffer->release();
  1443. }
  1444. if (globalDescriptorHeap)
  1445. {
  1446. globalDescriptorHeap->release();
  1447. }
  1448. if (textureDescriptorHeap)
  1449. {
  1450. textureDescriptorHeap->release();
  1451. }
  1452. if (samplerDescriptorHeap)
  1453. {
  1454. samplerDescriptorHeap->release();
  1455. }
  1456. for (const char* buffer : tempBuffers)
  1457. {
  1458. delete[] buffer;
  1459. }
  1460. }
  1461. void Framework::DX12ShaderBindingTable::setGlobalDescriptorHeap(
  1462. DX12GlobalDescriptorHeap* zGlobalDescriptorHeap)
  1463. {
  1464. if (this->globalDescriptorHeap != zGlobalDescriptorHeap)
  1465. {
  1466. if (this->globalDescriptorHeap)
  1467. {
  1468. this->globalDescriptorHeap->release();
  1469. }
  1470. this->globalDescriptorHeap = zGlobalDescriptorHeap;
  1471. if (this->globalDescriptorHeap)
  1472. {
  1473. this->globalDescriptorHeap->getThis();
  1474. }
  1475. }
  1476. }
  1477. void Framework::DX12ShaderBindingTable::setTextureDescriptorHeap(
  1478. DX12GlobalDescriptorHeap* zTextureDescriptorHeap)
  1479. {
  1480. if (this->textureDescriptorHeap != zTextureDescriptorHeap)
  1481. {
  1482. if (this->textureDescriptorHeap)
  1483. {
  1484. this->textureDescriptorHeap->release();
  1485. }
  1486. this->textureDescriptorHeap = zTextureDescriptorHeap;
  1487. if (this->textureDescriptorHeap)
  1488. {
  1489. this->textureDescriptorHeap->getThis();
  1490. }
  1491. }
  1492. }
  1493. void Framework::DX12ShaderBindingTable::setSamplerDescriptorHeap(
  1494. DX12GlobalDescriptorHeap* zSamplerDescriptorHeap)
  1495. {
  1496. if (this->samplerDescriptorHeap != zSamplerDescriptorHeap)
  1497. {
  1498. if (this->samplerDescriptorHeap)
  1499. {
  1500. this->samplerDescriptorHeap->release();
  1501. }
  1502. this->samplerDescriptorHeap = zSamplerDescriptorHeap;
  1503. if (this->samplerDescriptorHeap)
  1504. {
  1505. this->samplerDescriptorHeap->getThis();
  1506. }
  1507. }
  1508. }
  1509. void Framework::DX12ShaderBindingTable::startUpdate()
  1510. {
  1511. if (shaderBindingTableBuffer)
  1512. {
  1513. shaderBindingTableBuffer->zBuffer()->Map(0, 0, (void**)&tableBuffer);
  1514. tableBufferSize = (int)shaderBindingTableBuffer->getElementCount()
  1515. * shaderBindingTableBuffer->getElementLength();
  1516. }
  1517. else
  1518. {
  1519. tableBuffer = 0;
  1520. tableBufferSize = 0;
  1521. }
  1522. rayGenRecordSize = 0;
  1523. rayGenCount = 0;
  1524. missRecordSize = 0;
  1525. missCount = 0;
  1526. callableRecordSize = 0;
  1527. callableCount = 0;
  1528. for (const DX12ShaderFunction* function :
  1529. pipeline->getFunctionsWithoutHitGroups())
  1530. {
  1531. DX12ShaderSignature* signature = function->zSignature();
  1532. if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_RAY_GEN)
  1533. {
  1534. if (rayGenRecordSize < signature->gerShaderBindingTableParamCount())
  1535. {
  1536. rayGenRecordSize = signature->gerShaderBindingTableParamCount();
  1537. }
  1538. rayGenCount++;
  1539. }
  1540. else if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_MISS)
  1541. {
  1542. if (missRecordSize < signature->gerShaderBindingTableParamCount())
  1543. {
  1544. missRecordSize = signature->gerShaderBindingTableParamCount();
  1545. }
  1546. missCount++;
  1547. }
  1548. else if (function->getFunctionType()
  1549. == DX12_SHADER_FUNCTION_TYPE_CALLABLE)
  1550. {
  1551. if (callableRecordSize
  1552. < signature->gerShaderBindingTableParamCount())
  1553. {
  1554. callableRecordSize
  1555. = signature->gerShaderBindingTableParamCount();
  1556. }
  1557. callableCount++;
  1558. }
  1559. }
  1560. rayGenRecordSize = ROUND_UP_POWER_OF_2(
  1561. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + rayGenRecordSize * 8,
  1562. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1563. missRecordSize = ROUND_UP_POWER_OF_2(
  1564. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + missRecordSize * 8,
  1565. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1566. callableRecordSize = ROUND_UP_POWER_OF_2(
  1567. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + callableRecordSize * 8,
  1568. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1569. hitGroupCount = 0;
  1570. hitGroupRecordSize = 0;
  1571. for (DX12ShaderHitGroup* hitGroup : pipeline->getHitGroups())
  1572. {
  1573. DX12ShaderSignature* signature = hitGroup->zSignature();
  1574. if (hitGroupRecordSize < signature->gerShaderBindingTableParamCount())
  1575. {
  1576. hitGroupRecordSize = signature->gerShaderBindingTableParamCount();
  1577. }
  1578. }
  1579. hitGroupRecordSize = ROUND_UP_POWER_OF_2(
  1580. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + hitGroupRecordSize * 8,
  1581. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1582. nextHitGroupOffset = ROUND_UP_POWER_OF_2(
  1583. rayGenRecordSize * rayGenCount + missRecordSize * missCount
  1584. + callableRecordSize * callableCount,
  1585. 64);
  1586. }
  1587. void Framework::DX12ShaderBindingTable::set(int index, void* data, int size)
  1588. {
  1589. if (tableBufferSize >= index + size)
  1590. {
  1591. memcpy(tableBuffer + index, data, size);
  1592. }
  1593. else
  1594. {
  1595. index -= tableBufferSize;
  1596. ArrayIterator<char*> it = tempBuffers.begin();
  1597. while (it && 2048 < index + size)
  1598. {
  1599. index -= 2048;
  1600. it++;
  1601. }
  1602. while (2048 < index + size)
  1603. {
  1604. char* newBuffer = new char[2048];
  1605. memset(newBuffer, 0, 2048);
  1606. tempBuffers.add(newBuffer);
  1607. index -= 2048;
  1608. }
  1609. // because the buffer size is allways rounded up to multiples
  1610. // of 32 and the size written at once is always 8 or 32 it
  1611. // should never be possible to have a negative index here
  1612. assert(index >= 0);
  1613. if (!it)
  1614. {
  1615. char* newBuffer = new char[2048];
  1616. memset(newBuffer, 0, 2048);
  1617. tempBuffers.add(newBuffer);
  1618. memcpy(newBuffer + index, data, size);
  1619. }
  1620. else
  1621. {
  1622. memcpy(it.val() + index, data, size);
  1623. }
  1624. }
  1625. }
  1626. void Framework::DX12ShaderBindingTable::setShaderInput(
  1627. DX12ShaderFunction* zFunction, int* offsetPointer, __int64 gpuAddress)
  1628. {
  1629. int index = 0;
  1630. for (const DX12ShaderFunction* pf :
  1631. pipeline->getFunctionsWithoutHitGroups())
  1632. {
  1633. if (pf == zFunction)
  1634. {
  1635. break;
  1636. }
  1637. if (pf->getFunctionType() == zFunction->getFunctionType())
  1638. {
  1639. index++;
  1640. }
  1641. }
  1642. int offset = 0;
  1643. if (zFunction->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_RAY_GEN)
  1644. {
  1645. offset = index * rayGenRecordSize;
  1646. }
  1647. else if (zFunction->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_MISS)
  1648. {
  1649. offset = rayGenRecordSize * rayGenCount + index * missRecordSize;
  1650. }
  1651. else if (zFunction->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_CALLABLE)
  1652. {
  1653. offset = rayGenRecordSize * rayGenCount + missRecordSize * missCount
  1654. + index * callableRecordSize;
  1655. }
  1656. else
  1657. {
  1658. throw std::logic_error("setShaderInput can only be used for ray "
  1659. "generation, miss, and callable "
  1660. "shader functions");
  1661. }
  1662. offset += D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT
  1663. + sizeof(__int64) * *offsetPointer;
  1664. set(offset, &gpuAddress, sizeof(__int64));
  1665. }
  1666. int Framework::DX12ShaderBindingTable::addHitGroup(
  1667. DX12ShaderHitGroup* zHitGroup)
  1668. {
  1669. int index = nextHitGroupOffset;
  1670. set(index,
  1671. stateObjectProperties->GetShaderIdentifier(
  1672. zHitGroup->zHitGroupDesc()->HitGroupExport),
  1673. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1674. index += D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
  1675. if (zHitGroup->zSignature()->doesUseGlobalDescriptorHeap())
  1676. {
  1677. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1678. = globalDescriptorHeap->zDescriptorHeap()
  1679. ->GetGPUDescriptorHandleForHeapStart();
  1680. set(index, &gpuAddress.ptr, sizeof(__int64));
  1681. index += sizeof(__int64);
  1682. }
  1683. if (zHitGroup->zSignature()->doesUseTextureDescriptorHeap())
  1684. {
  1685. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1686. = textureDescriptorHeap->zDescriptorHeap()
  1687. ->GetGPUDescriptorHandleForHeapStart();
  1688. set(index, &gpuAddress.ptr, sizeof(__int64));
  1689. index += sizeof(__int64);
  1690. }
  1691. if (zHitGroup->zSignature()->doesUseSamplerDescriptorHeap())
  1692. {
  1693. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1694. = samplerDescriptorHeap->zDescriptorHeap()
  1695. ->GetGPUDescriptorHandleForHeapStart();
  1696. set(index, &gpuAddress.ptr, sizeof(__int64));
  1697. index += sizeof(__int64);
  1698. }
  1699. hitGroupCount++;
  1700. nextHitGroupOffset += hitGroupRecordSize;
  1701. return nextHitGroupOffset - hitGroupRecordSize
  1702. + D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
  1703. }
  1704. void Framework::DX12ShaderBindingTable::setHitGroupShaderInput(
  1705. int hitGroupOffset, int* offsetPointer, __int64 gpuAddress)
  1706. {
  1707. set(hitGroupOffset + sizeof(__int64) * *offsetPointer,
  1708. &gpuAddress,
  1709. sizeof(__int64));
  1710. }
  1711. void Framework::DX12ShaderBindingTable::endUpdate(
  1712. ID3D12Device5* zDevice, DX12CommandQueue* zQueue)
  1713. {
  1714. int rayTracingIndex = 0;
  1715. int missIndex = 0;
  1716. int callableIndex = 0;
  1717. for (const DX12ShaderFunction* function :
  1718. pipeline->getFunctionsWithoutHitGroups())
  1719. {
  1720. int offset = -1;
  1721. DX12ShaderSignature* signature = function->zSignature();
  1722. if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_RAY_GEN)
  1723. {
  1724. offset = rayTracingIndex * rayGenRecordSize;
  1725. rayTracingIndex++;
  1726. }
  1727. else if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_MISS)
  1728. {
  1729. offset
  1730. = rayGenRecordSize * rayGenCount + missIndex * missRecordSize;
  1731. missIndex++;
  1732. }
  1733. else if (function->getFunctionType()
  1734. == DX12_SHADER_FUNCTION_TYPE_CALLABLE)
  1735. {
  1736. offset = rayGenRecordSize * rayGenCount + missRecordSize * missCount
  1737. + callableIndex * callableRecordSize;
  1738. callableIndex++;
  1739. }
  1740. if (offset >= 0)
  1741. {
  1742. set(offset,
  1743. stateObjectProperties->GetShaderIdentifier(
  1744. function->zExportDesc()->Name),
  1745. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1746. offset += D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
  1747. if (function->zSignature()->doesUseGlobalDescriptorHeap())
  1748. {
  1749. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1750. = globalDescriptorHeap->zDescriptorHeap()
  1751. ->GetGPUDescriptorHandleForHeapStart();
  1752. set(offset, &gpuAddress.ptr, sizeof(__int64));
  1753. offset += sizeof(__int64);
  1754. }
  1755. if (function->zSignature()->doesUseTextureDescriptorHeap())
  1756. {
  1757. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1758. = textureDescriptorHeap->zDescriptorHeap()
  1759. ->GetGPUDescriptorHandleForHeapStart();
  1760. set(offset, &gpuAddress.ptr, sizeof(__int64));
  1761. offset += sizeof(__int64);
  1762. }
  1763. if (function->zSignature()->doesUseSamplerDescriptorHeap())
  1764. {
  1765. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1766. = samplerDescriptorHeap->zDescriptorHeap()
  1767. ->GetGPUDescriptorHandleForHeapStart();
  1768. set(offset, &gpuAddress.ptr, sizeof(__int64));
  1769. offset += sizeof(__int64);
  1770. }
  1771. }
  1772. }
  1773. if (nextHitGroupOffset > tableBufferSize)
  1774. {
  1775. DX12Buffer* newBuffer = new DX12Buffer(1,
  1776. zDevice,
  1777. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  1778. D3D12_RESOURCE_FLAG_NONE);
  1779. newBuffer->setLength(ROUND_UP_POWER_OF_2(nextHitGroupOffset, 256));
  1780. newBuffer->createBufferWithoutData(
  1781. D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_HEAP_TYPE_UPLOAD);
  1782. void* newTableBuffer = 0;
  1783. newBuffer->zBuffer()->Map(0, 0, (void**)&newTableBuffer);
  1784. int sizeToCopy = nextHitGroupOffset;
  1785. int index = 0;
  1786. if (tableBufferSize > 0)
  1787. {
  1788. memcpy(newTableBuffer, tableBuffer, tableBufferSize);
  1789. sizeToCopy -= tableBufferSize;
  1790. index = tableBufferSize;
  1791. }
  1792. for (char* buffer : tempBuffers)
  1793. {
  1794. int bytesToCopy = sizeToCopy < 2048 ? sizeToCopy : 2048;
  1795. memcpy((char*)newTableBuffer + index, buffer, bytesToCopy);
  1796. sizeToCopy -= bytesToCopy;
  1797. index += bytesToCopy;
  1798. if (sizeToCopy == 0)
  1799. {
  1800. break;
  1801. }
  1802. }
  1803. assert(sizeToCopy == 0);
  1804. newBuffer->zBuffer()->Unmap(0, 0);
  1805. if (shaderBindingTableBuffer)
  1806. {
  1807. shaderBindingTableBuffer->zBuffer()->Unmap(0, 0);
  1808. shaderBindingTableBuffer->release();
  1809. }
  1810. shaderBindingTableBuffer = newBuffer;
  1811. }
  1812. else
  1813. {
  1814. shaderBindingTableBuffer->zBuffer()->Unmap(0, 0);
  1815. }
  1816. }
  1817. void Framework::DX12ShaderBindingTable::fillDispatchRaysDesc(
  1818. D3D12_DISPATCH_RAYS_DESC* dispatchRaysDesc)
  1819. {
  1820. dispatchRaysDesc->RayGenerationShaderRecord.SizeInBytes
  1821. = rayGenCount * rayGenRecordSize;
  1822. dispatchRaysDesc->RayGenerationShaderRecord.StartAddress
  1823. = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress();
  1824. dispatchRaysDesc->MissShaderTable.SizeInBytes = missCount * missRecordSize;
  1825. dispatchRaysDesc->MissShaderTable.StartAddress
  1826. = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
  1827. + rayGenCount * rayGenRecordSize;
  1828. dispatchRaysDesc->MissShaderTable.StrideInBytes = missRecordSize;
  1829. dispatchRaysDesc->HitGroupTable.SizeInBytes
  1830. = hitGroupCount * hitGroupRecordSize;
  1831. dispatchRaysDesc->HitGroupTable.StartAddress
  1832. = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
  1833. + ROUND_UP_POWER_OF_2(rayGenCount * rayGenRecordSize
  1834. + missCount * missRecordSize
  1835. + callableCount * callableRecordSize,
  1836. 64);
  1837. dispatchRaysDesc->HitGroupTable.StrideInBytes = hitGroupRecordSize;
  1838. dispatchRaysDesc->CallableShaderTable.SizeInBytes
  1839. = callableCount * callableRecordSize;
  1840. dispatchRaysDesc->CallableShaderTable.StartAddress
  1841. = callableCount > 0
  1842. ? shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
  1843. + rayGenCount * rayGenRecordSize + missCount * missRecordSize
  1844. : 0;
  1845. dispatchRaysDesc->CallableShaderTable.StrideInBytes
  1846. = callableCount > 0 ? callableRecordSize : 0;
  1847. }
  1848. DX12Pipeline* Framework::DX12ShaderBindingTable::zPipeline() const
  1849. {
  1850. return pipeline;
  1851. }