DX12Shader.cpp 65 KB

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