DX12Shader.cpp 67 KB

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