DX12Shader.cpp 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996
  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. heapChanged(0)
  1039. {}
  1040. Framework::DX12GlobalDescriptorHeap::~DX12GlobalDescriptorHeap()
  1041. {
  1042. pipeline->release();
  1043. if (descriptorHeap)
  1044. {
  1045. descriptorHeap->Release();
  1046. }
  1047. for (const DX12ShaderRegisterInput* input : registerInputs)
  1048. {
  1049. input->inputResource->release();
  1050. delete input;
  1051. }
  1052. }
  1053. void Framework::DX12GlobalDescriptorHeap::addInput(
  1054. DX12ShaderRegister type, ReferenceCounter* inputResource)
  1055. {
  1056. bool found = 0;
  1057. for (DX12Shader* shader : pipeline->getShaders())
  1058. {
  1059. for (DX12ShaderFunction* function : shader->getFunctions())
  1060. {
  1061. for (const DX12ShaderRegisterUsage* usage :
  1062. function->zSignature()->getDescriptorHeapBindings())
  1063. {
  1064. if (usage->descriptorHeapIndex == registerInputs.getEntryCount()
  1065. && usage->descriptorHeapType == this->type)
  1066. {
  1067. if (usage->registerType != type)
  1068. {
  1069. Logging::error()
  1070. << "Register type mismatch for register index "
  1071. << usage->registerIndex << ", space index "
  1072. << usage->spaceIndex << ". Expected register type: "
  1073. << usage->registerType
  1074. << ", given register type: " << type
  1075. << ". The register type is specified in the "
  1076. "signature of shader function '"
  1077. << function->getFunctionName() << "'";
  1078. throw std::logic_error(
  1079. "Register type mismatch for shader input");
  1080. }
  1081. else
  1082. {
  1083. found = 1;
  1084. break;
  1085. }
  1086. }
  1087. }
  1088. if (found)
  1089. {
  1090. break;
  1091. }
  1092. }
  1093. if (found)
  1094. {
  1095. break;
  1096. }
  1097. }
  1098. registerInputs.add(new DX12ShaderRegisterInput{
  1099. type, inputResource ? inputResource->getThis() : 0});
  1100. }
  1101. void Framework::DX12GlobalDescriptorHeap::addTextureInput(
  1102. DX12ShaderRegister type, Texture* zTexture)
  1103. {
  1104. addInput(type, zTexture);
  1105. }
  1106. void Framework::DX12GlobalDescriptorHeap::updateTextureInput(
  1107. int heapIndex, DX12ShaderRegister type, Texture* zTexture)
  1108. {
  1109. DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
  1110. if (registerInputs.get(heapIndex)->inputResource
  1111. != dynamic_cast<ReferenceCounter*>(zTexture)
  1112. || zTexture->hasBufferChanged())
  1113. {
  1114. zTexture->setBufferChanged(0);
  1115. if (input->registerType != type)
  1116. {
  1117. Logging::error()
  1118. << "Register type mismatch for descriptor heap index "
  1119. << heapIndex
  1120. << ". Expected register type: " << input->registerType
  1121. << ", given register type: " << type << ".";
  1122. throw std::logic_error("Register type mismatch in descriptor heap");
  1123. }
  1124. registerInputs.get(heapIndex)->inputResource->release();
  1125. registerInputs.get(heapIndex)->inputResource = zTexture->getThis();
  1126. if (descriptorHeap)
  1127. {
  1128. D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
  1129. = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
  1130. descriptorHeapHandle.ptr
  1131. += zDevice->GetDescriptorHandleIncrementSize(
  1132. D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
  1133. * heapIndex;
  1134. switch (input->registerType)
  1135. {
  1136. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  1137. {
  1138. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
  1139. srvDesc.Format = DXGI_FORMAT_UNKNOWN;
  1140. srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
  1141. srvDesc.Texture2D.MipLevels = 0;
  1142. srvDesc.Texture2D.MostDetailedMip = 0;
  1143. srvDesc.Texture2D.PlaneSlice = 0;
  1144. srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
  1145. srvDesc.Shader4ComponentMapping
  1146. = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
  1147. zDevice->CreateShaderResourceView(
  1148. ((DX12Texture*)zTexture)->zResource(),
  1149. &srvDesc,
  1150. descriptorHeapHandle);
  1151. break;
  1152. }
  1153. case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
  1154. {
  1155. D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
  1156. uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
  1157. uavDesc.Format = DXGI_FORMAT_UNKNOWN;
  1158. uavDesc.Texture2D.MipSlice = 0;
  1159. uavDesc.Texture2D.PlaneSlice = 0;
  1160. zDevice->CreateUnorderedAccessView(
  1161. ((DX12Texture*)zTexture)->zResource(),
  1162. 0,
  1163. &uavDesc,
  1164. descriptorHeapHandle);
  1165. break;
  1166. }
  1167. }
  1168. }
  1169. }
  1170. }
  1171. void Framework::DX12GlobalDescriptorHeap::addBufferInput(
  1172. DX12ShaderRegister type, DXBuffer* zBuffer)
  1173. {
  1174. addInput(type, zBuffer);
  1175. }
  1176. void Framework::DX12GlobalDescriptorHeap::addTLASInput(
  1177. DX12ShaderRegister type, DX12TLAS* zTLAS)
  1178. {
  1179. addInput(type, zTLAS);
  1180. }
  1181. void Framework::DX12GlobalDescriptorHeap::updateTLASInput(
  1182. int heapIndex, DX12ShaderRegister type, DX12TLAS* zTLAS)
  1183. {
  1184. DX12ShaderRegisterInput* input = registerInputs.get(heapIndex);
  1185. if (registerInputs.get(heapIndex)->inputResource
  1186. != dynamic_cast<ReferenceCounter*>(zTLAS)
  1187. || zTLAS->hasBufferChanged())
  1188. {
  1189. zTLAS->setBufferChanged(0);
  1190. if (input->registerType != type)
  1191. {
  1192. Logging::error()
  1193. << "Register type mismatch for descriptor heap index "
  1194. << heapIndex
  1195. << ". Expected register type: " << input->registerType
  1196. << ", given register type: " << type << ".";
  1197. throw std::logic_error("Register type mismatch in descriptor heap");
  1198. }
  1199. if (registerInputs.get(heapIndex)->inputResource)
  1200. {
  1201. registerInputs.get(heapIndex)->inputResource->release();
  1202. }
  1203. registerInputs.get(heapIndex)->inputResource = zTLAS->getThis();
  1204. if (descriptorHeap)
  1205. {
  1206. D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
  1207. = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
  1208. descriptorHeapHandle.ptr
  1209. += zDevice->GetDescriptorHandleIncrementSize(
  1210. D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
  1211. * heapIndex;
  1212. switch (input->registerType)
  1213. {
  1214. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  1215. {
  1216. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
  1217. srvDesc.Format = DXGI_FORMAT_UNKNOWN;
  1218. srvDesc.ViewDimension
  1219. = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
  1220. srvDesc.RaytracingAccelerationStructure.Location
  1221. = zTLAS->zResultBuffer()
  1222. ->zBuffer()
  1223. ->GetGPUVirtualAddress();
  1224. srvDesc.Shader4ComponentMapping
  1225. = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
  1226. zDevice->CreateShaderResourceView(
  1227. 0, &srvDesc, descriptorHeapHandle);
  1228. break;
  1229. }
  1230. }
  1231. }
  1232. }
  1233. }
  1234. void Framework::DX12GlobalDescriptorHeap::addSamplerInput(
  1235. DX12SamplerState* zSampler)
  1236. {
  1237. addInput(DX12_SHADER_REGISTER_S_SAMPLER, zSampler);
  1238. }
  1239. void Framework::DX12GlobalDescriptorHeap::updateDescriptorHeap(
  1240. ID3D12Device5* zDevice)
  1241. {
  1242. this->zDevice = zDevice;
  1243. if (!descriptorHeap
  1244. || lastDescriptorHeapSize != registerInputs.getEntryCount())
  1245. {
  1246. if (descriptorHeap)
  1247. {
  1248. descriptorHeap->Release();
  1249. }
  1250. D3D12_DESCRIPTOR_HEAP_DESC desc = {};
  1251. desc.NumDescriptors = registerInputs.getEntryCount();
  1252. desc.Type = type == SAMPLER_DESCRIPTOR_HEAP
  1253. ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER
  1254. : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
  1255. desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
  1256. desc.NodeMask = 0;
  1257. HRESULT r = zDevice->CreateDescriptorHeap(
  1258. &desc, __uuidof(ID3D12DescriptorHeap), (void**)&descriptorHeap);
  1259. lastDescriptorHeapSize = registerInputs.getEntryCount();
  1260. heapChanged = 1;
  1261. }
  1262. D3D12_CPU_DESCRIPTOR_HANDLE descriptorHeapHandle
  1263. = descriptorHeap->GetCPUDescriptorHandleForHeapStart();
  1264. for (const DX12ShaderRegisterInput* input : registerInputs)
  1265. {
  1266. DX12TLAS* zTLAS = dynamic_cast<DX12TLAS*>(input->inputResource);
  1267. DX12Texture* zTexture
  1268. = dynamic_cast<DX12Texture*>(input->inputResource);
  1269. if (zTexture && !zTexture->zResource())
  1270. {
  1271. zTexture = 0;
  1272. }
  1273. DX12Buffer* zBuffer = dynamic_cast<DX12Buffer*>(input->inputResource);
  1274. DX12SamplerState* zSampler
  1275. = dynamic_cast<DX12SamplerState*>(input->inputResource);
  1276. switch (input->registerType)
  1277. {
  1278. case DX12_SHADER_REGISTER_B_CONST_BUFFER:
  1279. {
  1280. D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
  1281. if (!zBuffer)
  1282. {
  1283. Logging::error()
  1284. << "Expected a buffer resource for register type "
  1285. << input->registerType;
  1286. throw std::logic_error(
  1287. "Expected a buffer resource for register type "
  1288. + std::to_string(input->registerType));
  1289. }
  1290. cbvDesc.BufferLocation
  1291. = zBuffer->zBuffer()->GetGPUVirtualAddress();
  1292. cbvDesc.SizeInBytes = (unsigned)zBuffer->getElementCount()
  1293. * zBuffer->getElementLength();
  1294. zDevice->CreateConstantBufferView(
  1295. &cbvDesc, descriptorHeapHandle);
  1296. break;
  1297. }
  1298. case DX12_SHADER_REGISTER_T_SHADER_RESOURCE:
  1299. {
  1300. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
  1301. srvDesc.Format = DXGI_FORMAT_UNKNOWN;
  1302. bool doNothing = 0;
  1303. if (zTLAS)
  1304. {
  1305. srvDesc.ViewDimension
  1306. = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
  1307. srvDesc.RaytracingAccelerationStructure.Location
  1308. = zTLAS->zResultBuffer()
  1309. ->zBuffer()
  1310. ->GetGPUVirtualAddress();
  1311. }
  1312. else if (zTexture)
  1313. {
  1314. srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
  1315. srvDesc.Texture2D.MipLevels = 1;
  1316. srvDesc.Texture2D.MostDetailedMip = 0;
  1317. srvDesc.Texture2D.PlaneSlice = 0;
  1318. srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
  1319. }
  1320. else if (zBuffer)
  1321. {
  1322. srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
  1323. srvDesc.Buffer.FirstElement = 0;
  1324. srvDesc.Buffer.NumElements
  1325. = (unsigned)zBuffer->getElementCount();
  1326. srvDesc.Buffer.StructureByteStride
  1327. = zBuffer->getElementLength();
  1328. srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
  1329. }
  1330. else if (zSampler)
  1331. {
  1332. Logging::error()
  1333. << "Expected a texture or buffer or TLAS resource for "
  1334. "register type "
  1335. << input->registerType;
  1336. throw std::logic_error(
  1337. "Expected a texture or buffer or TLAS resource for "
  1338. "register type "
  1339. + std::to_string(input->registerType));
  1340. }
  1341. else
  1342. {
  1343. doNothing = 1;
  1344. }
  1345. if (!doNothing)
  1346. {
  1347. srvDesc.Shader4ComponentMapping
  1348. = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
  1349. zDevice->CreateShaderResourceView(
  1350. zTexture ? zTexture->zResource()
  1351. : (zBuffer ? zBuffer->zBuffer() : 0),
  1352. &srvDesc,
  1353. descriptorHeapHandle);
  1354. }
  1355. break;
  1356. }
  1357. case DX12_SHADER_REGISTER_U_UNORDERED_ACCESS:
  1358. {
  1359. D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
  1360. bool doNothing = 0;
  1361. if (zTexture)
  1362. {
  1363. uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
  1364. uavDesc.Format = DXGI_FORMAT_UNKNOWN;
  1365. uavDesc.Texture2D.MipSlice = 0;
  1366. uavDesc.Texture2D.PlaneSlice = 0;
  1367. }
  1368. else if (zBuffer)
  1369. {
  1370. uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
  1371. uavDesc.Buffer.FirstElement = 0;
  1372. uavDesc.Buffer.NumElements
  1373. = (unsigned)zBuffer->getElementCount();
  1374. uavDesc.Buffer.StructureByteStride
  1375. = zBuffer->getElementLength();
  1376. uavDesc.Buffer.CounterOffsetInBytes = 0;
  1377. uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
  1378. }
  1379. else if (zTLAS || zSampler)
  1380. {
  1381. Logging::error()
  1382. << "Expected a texture or buffer resource for "
  1383. "register type "
  1384. << input->registerType;
  1385. throw std::logic_error(
  1386. "Expected a texture or buffer resource for "
  1387. "register "
  1388. "type "
  1389. + std::to_string(input->registerType));
  1390. }
  1391. else
  1392. {
  1393. doNothing = 1;
  1394. }
  1395. if (!doNothing)
  1396. {
  1397. zDevice->CreateUnorderedAccessView(
  1398. zTexture ? zTexture->zResource() : zBuffer->zBuffer(),
  1399. 0,
  1400. &uavDesc,
  1401. descriptorHeapHandle);
  1402. }
  1403. break;
  1404. }
  1405. case DX12_SHADER_REGISTER_S_SAMPLER:
  1406. if (zSampler)
  1407. {
  1408. zDevice->CreateSampler(
  1409. zSampler->zSamplerDesc(), descriptorHeapHandle);
  1410. }
  1411. else
  1412. {
  1413. Logging::error()
  1414. << "Expected a sampler resource for register type "
  1415. << input->registerType;
  1416. throw std::logic_error(
  1417. "Expected a sampler resource for register type "
  1418. + std::to_string(input->registerType));
  1419. }
  1420. }
  1421. descriptorHeapHandle.ptr += zDevice->GetDescriptorHandleIncrementSize(
  1422. type == SAMPLER_DESCRIPTOR_HEAP
  1423. ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER
  1424. : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
  1425. }
  1426. }
  1427. DX12Pipeline* Framework::DX12GlobalDescriptorHeap::zPipeline() const
  1428. {
  1429. return pipeline;
  1430. }
  1431. ID3D12DescriptorHeap*
  1432. Framework::DX12GlobalDescriptorHeap::zDescriptorHeap() const
  1433. {
  1434. return descriptorHeap;
  1435. }
  1436. void Framework::DX12GlobalDescriptorHeap::setHeapChanged(bool changed)
  1437. {
  1438. heapChanged = changed;
  1439. }
  1440. bool Framework::DX12GlobalDescriptorHeap::wasHeapChanged() const
  1441. {
  1442. return heapChanged;
  1443. }
  1444. Framework::DX12ShaderBindingTable::DX12ShaderBindingTable(
  1445. DX12Pipeline* pipeline)
  1446. : ReferenceCounter(),
  1447. pipeline(pipeline),
  1448. shaderBindingTableBuffer(0),
  1449. globalDescriptorHeap(0),
  1450. textureDescriptorHeap(0),
  1451. samplerDescriptorHeap(0),
  1452. rayGenRecordSize(0),
  1453. rayGenCount(0),
  1454. missRecordSize(0),
  1455. missCount(0),
  1456. callableRecordSize(0),
  1457. callableCount(0),
  1458. hitGroupRecordSize(0),
  1459. hitGroupCount(0),
  1460. tableBuffer(0),
  1461. tableBufferSize(0),
  1462. nextHitGroupOffset(0),
  1463. stateObjectProperties(0)
  1464. {
  1465. pipeline->zPipelineState()->QueryInterface(
  1466. __uuidof(ID3D12StateObjectProperties), (void**)&stateObjectProperties);
  1467. }
  1468. Framework::DX12ShaderBindingTable::~DX12ShaderBindingTable()
  1469. {
  1470. stateObjectProperties->Release();
  1471. if (pipeline)
  1472. {
  1473. pipeline->release();
  1474. }
  1475. if (shaderBindingTableBuffer)
  1476. {
  1477. shaderBindingTableBuffer->release();
  1478. }
  1479. if (globalDescriptorHeap)
  1480. {
  1481. globalDescriptorHeap->release();
  1482. }
  1483. if (textureDescriptorHeap)
  1484. {
  1485. textureDescriptorHeap->release();
  1486. }
  1487. if (samplerDescriptorHeap)
  1488. {
  1489. samplerDescriptorHeap->release();
  1490. }
  1491. for (const char* buffer : tempBuffers)
  1492. {
  1493. delete[] buffer;
  1494. }
  1495. }
  1496. void Framework::DX12ShaderBindingTable::setGlobalDescriptorHeap(
  1497. DX12GlobalDescriptorHeap* zGlobalDescriptorHeap)
  1498. {
  1499. if (this->globalDescriptorHeap != zGlobalDescriptorHeap)
  1500. {
  1501. if (this->globalDescriptorHeap)
  1502. {
  1503. this->globalDescriptorHeap->release();
  1504. }
  1505. this->globalDescriptorHeap = zGlobalDescriptorHeap;
  1506. if (this->globalDescriptorHeap)
  1507. {
  1508. this->globalDescriptorHeap->getThis();
  1509. }
  1510. }
  1511. }
  1512. void Framework::DX12ShaderBindingTable::setTextureDescriptorHeap(
  1513. DX12GlobalDescriptorHeap* zTextureDescriptorHeap)
  1514. {
  1515. if (this->textureDescriptorHeap != zTextureDescriptorHeap)
  1516. {
  1517. if (this->textureDescriptorHeap)
  1518. {
  1519. this->textureDescriptorHeap->release();
  1520. }
  1521. this->textureDescriptorHeap = zTextureDescriptorHeap;
  1522. if (this->textureDescriptorHeap)
  1523. {
  1524. this->textureDescriptorHeap->getThis();
  1525. }
  1526. }
  1527. }
  1528. void Framework::DX12ShaderBindingTable::setSamplerDescriptorHeap(
  1529. DX12GlobalDescriptorHeap* zSamplerDescriptorHeap)
  1530. {
  1531. if (this->samplerDescriptorHeap != zSamplerDescriptorHeap)
  1532. {
  1533. if (this->samplerDescriptorHeap)
  1534. {
  1535. this->samplerDescriptorHeap->release();
  1536. }
  1537. this->samplerDescriptorHeap = zSamplerDescriptorHeap;
  1538. if (this->samplerDescriptorHeap)
  1539. {
  1540. this->samplerDescriptorHeap->getThis();
  1541. }
  1542. }
  1543. }
  1544. void Framework::DX12ShaderBindingTable::startUpdate()
  1545. {
  1546. if (shaderBindingTableBuffer)
  1547. {
  1548. shaderBindingTableBuffer->zBuffer()->Map(0, 0, (void**)&tableBuffer);
  1549. tableBufferSize = (int)shaderBindingTableBuffer->getElementCount()
  1550. * shaderBindingTableBuffer->getElementLength();
  1551. }
  1552. else
  1553. {
  1554. tableBuffer = 0;
  1555. tableBufferSize = 0;
  1556. }
  1557. rayGenRecordSize = 0;
  1558. rayGenCount = 0;
  1559. missRecordSize = 0;
  1560. missCount = 0;
  1561. callableRecordSize = 0;
  1562. callableCount = 0;
  1563. for (const DX12ShaderFunction* function :
  1564. pipeline->getFunctionsWithoutHitGroups())
  1565. {
  1566. DX12ShaderSignature* signature = function->zSignature();
  1567. if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_RAY_GEN)
  1568. {
  1569. if (rayGenRecordSize < signature->gerShaderBindingTableParamCount())
  1570. {
  1571. rayGenRecordSize = signature->gerShaderBindingTableParamCount();
  1572. }
  1573. rayGenCount++;
  1574. }
  1575. else if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_MISS)
  1576. {
  1577. if (missRecordSize < signature->gerShaderBindingTableParamCount())
  1578. {
  1579. missRecordSize = signature->gerShaderBindingTableParamCount();
  1580. }
  1581. missCount++;
  1582. }
  1583. else if (function->getFunctionType()
  1584. == DX12_SHADER_FUNCTION_TYPE_CALLABLE)
  1585. {
  1586. if (callableRecordSize
  1587. < signature->gerShaderBindingTableParamCount())
  1588. {
  1589. callableRecordSize
  1590. = signature->gerShaderBindingTableParamCount();
  1591. }
  1592. callableCount++;
  1593. }
  1594. }
  1595. rayGenRecordSize = ROUND_UP_POWER_OF_2(
  1596. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + rayGenRecordSize * 8,
  1597. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1598. missRecordSize = ROUND_UP_POWER_OF_2(
  1599. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + missRecordSize * 8,
  1600. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1601. callableRecordSize = ROUND_UP_POWER_OF_2(
  1602. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + callableRecordSize * 8,
  1603. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1604. hitGroupCount = 0;
  1605. hitGroupRecordSize = 0;
  1606. for (DX12ShaderHitGroup* hitGroup : pipeline->getHitGroups())
  1607. {
  1608. DX12ShaderSignature* signature = hitGroup->zSignature();
  1609. if (hitGroupRecordSize < signature->gerShaderBindingTableParamCount())
  1610. {
  1611. hitGroupRecordSize = signature->gerShaderBindingTableParamCount();
  1612. }
  1613. }
  1614. hitGroupRecordSize = ROUND_UP_POWER_OF_2(
  1615. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT + hitGroupRecordSize * 8,
  1616. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1617. nextHitGroupOffset = ROUND_UP_POWER_OF_2(
  1618. rayGenRecordSize * rayGenCount + missRecordSize * missCount
  1619. + callableRecordSize * callableCount,
  1620. 64);
  1621. }
  1622. void Framework::DX12ShaderBindingTable::set(int index, void* data, int size)
  1623. {
  1624. if (tableBufferSize >= index + size)
  1625. {
  1626. memcpy(tableBuffer + index, data, size);
  1627. }
  1628. else
  1629. {
  1630. index -= tableBufferSize;
  1631. ArrayIterator<char*> it = tempBuffers.begin();
  1632. while (it && 2048 < index + size)
  1633. {
  1634. index -= 2048;
  1635. it++;
  1636. }
  1637. while (2048 < index + size)
  1638. {
  1639. char* newBuffer = new char[2048];
  1640. memset(newBuffer, 0, 2048);
  1641. tempBuffers.add(newBuffer);
  1642. index -= 2048;
  1643. }
  1644. // because the buffer size is allways rounded up to multiples
  1645. // of 32 and the size written at once is always 8 or 32 it
  1646. // should never be possible to have a negative index here
  1647. assert(index >= 0);
  1648. if (!it)
  1649. {
  1650. char* newBuffer = new char[2048];
  1651. memset(newBuffer, 0, 2048);
  1652. tempBuffers.add(newBuffer);
  1653. memcpy(newBuffer + index, data, size);
  1654. }
  1655. else
  1656. {
  1657. memcpy(it.val() + index, data, size);
  1658. }
  1659. }
  1660. }
  1661. void Framework::DX12ShaderBindingTable::setShaderInput(
  1662. DX12ShaderFunction* zFunction, int* offsetPointer, __int64 gpuAddress)
  1663. {
  1664. int index = 0;
  1665. for (const DX12ShaderFunction* pf :
  1666. pipeline->getFunctionsWithoutHitGroups())
  1667. {
  1668. if (pf == zFunction)
  1669. {
  1670. break;
  1671. }
  1672. if (pf->getFunctionType() == zFunction->getFunctionType())
  1673. {
  1674. index++;
  1675. }
  1676. }
  1677. int offset = 0;
  1678. if (zFunction->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_RAY_GEN)
  1679. {
  1680. offset = index * rayGenRecordSize;
  1681. }
  1682. else if (zFunction->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_MISS)
  1683. {
  1684. offset = rayGenRecordSize * rayGenCount + index * missRecordSize;
  1685. }
  1686. else if (zFunction->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_CALLABLE)
  1687. {
  1688. offset = rayGenRecordSize * rayGenCount + missRecordSize * missCount
  1689. + index * callableRecordSize;
  1690. }
  1691. else
  1692. {
  1693. throw std::logic_error("setShaderInput can only be used for ray "
  1694. "generation, miss, and callable "
  1695. "shader functions");
  1696. }
  1697. offset += D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT
  1698. + sizeof(__int64) * *offsetPointer;
  1699. set(offset, &gpuAddress, sizeof(__int64));
  1700. }
  1701. int Framework::DX12ShaderBindingTable::addHitGroup(
  1702. DX12ShaderHitGroup* zHitGroup, int lastIndex)
  1703. {
  1704. int index = nextHitGroupOffset;
  1705. bool changed
  1706. = index + D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT != lastIndex;
  1707. if (changed)
  1708. {
  1709. set(index,
  1710. stateObjectProperties->GetShaderIdentifier(
  1711. zHitGroup->zHitGroupDesc()->HitGroupExport),
  1712. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1713. }
  1714. index += D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
  1715. if (zHitGroup->zSignature()->doesUseGlobalDescriptorHeap())
  1716. {
  1717. if ((changed || globalDescriptorHeap->wasHeapChanged()))
  1718. {
  1719. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1720. = globalDescriptorHeap->zDescriptorHeap()
  1721. ->GetGPUDescriptorHandleForHeapStart();
  1722. set(index, &gpuAddress.ptr, sizeof(__int64));
  1723. }
  1724. index += sizeof(__int64);
  1725. }
  1726. if (zHitGroup->zSignature()->doesUseTextureDescriptorHeap())
  1727. {
  1728. if ((changed || textureDescriptorHeap->wasHeapChanged()))
  1729. {
  1730. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1731. = textureDescriptorHeap->zDescriptorHeap()
  1732. ->GetGPUDescriptorHandleForHeapStart();
  1733. set(index, &gpuAddress.ptr, sizeof(__int64));
  1734. }
  1735. index += sizeof(__int64);
  1736. }
  1737. if (zHitGroup->zSignature()->doesUseSamplerDescriptorHeap())
  1738. {
  1739. if ((changed || samplerDescriptorHeap->wasHeapChanged()))
  1740. {
  1741. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1742. = samplerDescriptorHeap->zDescriptorHeap()
  1743. ->GetGPUDescriptorHandleForHeapStart();
  1744. set(index, &gpuAddress.ptr, sizeof(__int64));
  1745. }
  1746. index += sizeof(__int64);
  1747. }
  1748. hitGroupCount++;
  1749. nextHitGroupOffset += hitGroupRecordSize;
  1750. return nextHitGroupOffset - hitGroupRecordSize
  1751. + D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
  1752. }
  1753. void Framework::DX12ShaderBindingTable::setHitGroupShaderInput(
  1754. int hitGroupOffset, int* offsetPointer, __int64 gpuAddress)
  1755. {
  1756. set(hitGroupOffset + sizeof(__int64) * *offsetPointer,
  1757. &gpuAddress,
  1758. sizeof(__int64));
  1759. }
  1760. void Framework::DX12ShaderBindingTable::endUpdate(
  1761. ID3D12Device5* zDevice, DX12CommandQueue* zQueue)
  1762. {
  1763. int rayTracingIndex = 0;
  1764. int missIndex = 0;
  1765. int callableIndex = 0;
  1766. for (const DX12ShaderFunction* function :
  1767. pipeline->getFunctionsWithoutHitGroups())
  1768. {
  1769. int offset = -1;
  1770. DX12ShaderSignature* signature = function->zSignature();
  1771. if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_RAY_GEN)
  1772. {
  1773. offset = rayTracingIndex * rayGenRecordSize;
  1774. rayTracingIndex++;
  1775. }
  1776. else if (function->getFunctionType() == DX12_SHADER_FUNCTION_TYPE_MISS)
  1777. {
  1778. offset
  1779. = rayGenRecordSize * rayGenCount + missIndex * missRecordSize;
  1780. missIndex++;
  1781. }
  1782. else if (function->getFunctionType()
  1783. == DX12_SHADER_FUNCTION_TYPE_CALLABLE)
  1784. {
  1785. offset = rayGenRecordSize * rayGenCount + missRecordSize * missCount
  1786. + callableIndex * callableRecordSize;
  1787. callableIndex++;
  1788. }
  1789. if (offset >= 0)
  1790. {
  1791. set(offset,
  1792. stateObjectProperties->GetShaderIdentifier(
  1793. function->zExportDesc()->Name),
  1794. D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
  1795. offset += D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT;
  1796. if (function->zSignature()->doesUseGlobalDescriptorHeap())
  1797. {
  1798. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1799. = globalDescriptorHeap->zDescriptorHeap()
  1800. ->GetGPUDescriptorHandleForHeapStart();
  1801. set(offset, &gpuAddress.ptr, sizeof(__int64));
  1802. offset += sizeof(__int64);
  1803. }
  1804. if (function->zSignature()->doesUseTextureDescriptorHeap())
  1805. {
  1806. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1807. = textureDescriptorHeap->zDescriptorHeap()
  1808. ->GetGPUDescriptorHandleForHeapStart();
  1809. set(offset, &gpuAddress.ptr, sizeof(__int64));
  1810. offset += sizeof(__int64);
  1811. }
  1812. if (function->zSignature()->doesUseSamplerDescriptorHeap())
  1813. {
  1814. D3D12_GPU_DESCRIPTOR_HANDLE gpuAddress
  1815. = samplerDescriptorHeap->zDescriptorHeap()
  1816. ->GetGPUDescriptorHandleForHeapStart();
  1817. set(offset, &gpuAddress.ptr, sizeof(__int64));
  1818. offset += sizeof(__int64);
  1819. }
  1820. }
  1821. }
  1822. if (nextHitGroupOffset > tableBufferSize)
  1823. {
  1824. DX12Buffer* newBuffer = new DX12Buffer(1,
  1825. zDevice,
  1826. dynamic_cast<DX12CommandQueue*>(zQueue->getThis()),
  1827. D3D12_RESOURCE_FLAG_NONE);
  1828. newBuffer->setLength(ROUND_UP_POWER_OF_2(nextHitGroupOffset, 256));
  1829. newBuffer->createBufferWithoutData(
  1830. D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_HEAP_TYPE_UPLOAD);
  1831. void* newTableBuffer = 0;
  1832. newBuffer->zBuffer()->Map(0, 0, (void**)&newTableBuffer);
  1833. int sizeToCopy = nextHitGroupOffset;
  1834. int index = 0;
  1835. if (tableBufferSize > 0)
  1836. {
  1837. memcpy(newTableBuffer, tableBuffer, tableBufferSize);
  1838. sizeToCopy -= tableBufferSize;
  1839. index = tableBufferSize;
  1840. }
  1841. for (char* buffer : tempBuffers)
  1842. {
  1843. int bytesToCopy = sizeToCopy < 2048 ? sizeToCopy : 2048;
  1844. memcpy((char*)newTableBuffer + index, buffer, bytesToCopy);
  1845. sizeToCopy -= bytesToCopy;
  1846. index += bytesToCopy;
  1847. if (sizeToCopy == 0)
  1848. {
  1849. break;
  1850. }
  1851. }
  1852. assert(sizeToCopy == 0);
  1853. newBuffer->zBuffer()->Unmap(0, 0);
  1854. if (shaderBindingTableBuffer)
  1855. {
  1856. shaderBindingTableBuffer->zBuffer()->Unmap(0, 0);
  1857. shaderBindingTableBuffer->release();
  1858. }
  1859. shaderBindingTableBuffer = newBuffer;
  1860. }
  1861. else
  1862. {
  1863. shaderBindingTableBuffer->zBuffer()->Unmap(0, 0);
  1864. }
  1865. }
  1866. void Framework::DX12ShaderBindingTable::fillDispatchRaysDesc(
  1867. D3D12_DISPATCH_RAYS_DESC* dispatchRaysDesc)
  1868. {
  1869. dispatchRaysDesc->RayGenerationShaderRecord.SizeInBytes
  1870. = rayGenCount * rayGenRecordSize;
  1871. dispatchRaysDesc->RayGenerationShaderRecord.StartAddress
  1872. = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress();
  1873. dispatchRaysDesc->MissShaderTable.SizeInBytes = missCount * missRecordSize;
  1874. dispatchRaysDesc->MissShaderTable.StartAddress
  1875. = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
  1876. + rayGenCount * rayGenRecordSize;
  1877. dispatchRaysDesc->MissShaderTable.StrideInBytes = missRecordSize;
  1878. dispatchRaysDesc->HitGroupTable.SizeInBytes
  1879. = hitGroupCount * hitGroupRecordSize;
  1880. dispatchRaysDesc->HitGroupTable.StartAddress
  1881. = shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
  1882. + ROUND_UP_POWER_OF_2(rayGenCount * rayGenRecordSize
  1883. + missCount * missRecordSize
  1884. + callableCount * callableRecordSize,
  1885. 64);
  1886. dispatchRaysDesc->HitGroupTable.StrideInBytes = hitGroupRecordSize;
  1887. dispatchRaysDesc->CallableShaderTable.SizeInBytes
  1888. = callableCount * callableRecordSize;
  1889. dispatchRaysDesc->CallableShaderTable.StartAddress
  1890. = callableCount > 0
  1891. ? shaderBindingTableBuffer->zBuffer()->GetGPUVirtualAddress()
  1892. + rayGenCount * rayGenRecordSize + missCount * missRecordSize
  1893. : 0;
  1894. dispatchRaysDesc->CallableShaderTable.StrideInBytes
  1895. = callableCount > 0 ? callableRecordSize : 0;
  1896. }
  1897. DX12Pipeline* Framework::DX12ShaderBindingTable::zPipeline() const
  1898. {
  1899. return pipeline;
  1900. }