DX12Shader.cpp 66 KB

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