DX12GraphicsApi.cpp 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339
  1. #include "DX12GraphicsApi.h"
  2. #include <d3d11.h>
  3. #include <d3d12.h>
  4. #include <dxgi1_6.h>
  5. #include <dxgidebug.h>
  6. #include "Camera3D.h"
  7. #include "d3dx12.h"
  8. #include "DLLRegister.h"
  9. #include "DX12BLASModel.h"
  10. #include "DX12CommandQueue.h"
  11. #include "DX12DefaultAnyHitShader.h"
  12. #include "DX12DefaultHitShader.h"
  13. #include "DX12DefaultMissShader.h"
  14. #include "DX12DefaultRayGenShader.h"
  15. #include "DX12SamplerState.h"
  16. #include "DX12Shader.h"
  17. #include "DX12Texture.h"
  18. #include "DX12TLAS.h"
  19. #include "Globals.h"
  20. #include "Image.h"
  21. #include "Model3D.h"
  22. #include "Model3DList.h"
  23. #include "Screen.h"
  24. #include "TextureList.h"
  25. #include "TextureModel.h"
  26. #include "Window.h"
  27. #include "World3D.h"
  28. using namespace Framework;
  29. class DX12RenderingData : public Framework::ReferenceCounter
  30. {
  31. public:
  32. int lastObjectIndex;
  33. int lastBlasCount;
  34. int* lastHitGroupIndices;
  35. DX12RenderingData()
  36. : Framework::ReferenceCounter(),
  37. lastObjectIndex(-1),
  38. lastBlasCount(0),
  39. lastHitGroupIndices(0)
  40. {}
  41. ~DX12RenderingData()
  42. {
  43. if (lastHitGroupIndices) delete[] lastHitGroupIndices;
  44. }
  45. };
  46. DirectX12::DirectX12()
  47. : GraphicsApi(DIRECTX12),
  48. debug(0),
  49. infoQueue(0),
  50. directCommandQueue(0),
  51. swapChain(0),
  52. backBufferIndex(0),
  53. tearing(0),
  54. signature(0),
  55. uiTexture(0),
  56. texturRegister(new TextureList()),
  57. blasModels(0),
  58. worldTLAS(0),
  59. worldShaderBindingTables(0),
  60. lastTLASId(-1),
  61. lastModelId(-1),
  62. defaultRenderTarget(0),
  63. defaultKamera(0),
  64. cameraCount(0),
  65. rayGenSettingsBuffer(0),
  66. device(0),
  67. pfnD3D12SerializeRootSignature(0),
  68. pipeline(0),
  69. globalDescriptorHeap(0),
  70. textureDescriptorHeap(0),
  71. samplerDescriptorHeap(0),
  72. defaultHitGroup(0),
  73. defaultRayGenerationShaderFunction(0),
  74. defaultSamplerState(0),
  75. sbtTextureIdBufferOffset(0),
  76. sbtIndexBufferOffset(0),
  77. sbtVertexDataBufferOffset(0),
  78. sbtPolygonSizeBufferOffset(0)
  79. {
  80. for (int i = 0; i < 2; i++)
  81. backBuffer[i] = 0;
  82. }
  83. DirectX12::~DirectX12()
  84. {
  85. if (blasModels)
  86. {
  87. for (int i = 0; i <= lastModelId; i++)
  88. {
  89. if (blasModels[i]) blasModels[i]->release();
  90. }
  91. delete[] blasModels;
  92. }
  93. if (worldTLAS)
  94. {
  95. for (int i = 0; i <= lastTLASId; i++)
  96. {
  97. if (worldTLAS[i]) worldTLAS[i]->release();
  98. }
  99. delete[] worldTLAS;
  100. }
  101. if (worldShaderBindingTables)
  102. {
  103. for (int i = 0; i <= lastTLASId; i++)
  104. {
  105. if (worldShaderBindingTables[i])
  106. worldShaderBindingTables[i]->release();
  107. }
  108. delete[] worldShaderBindingTables;
  109. }
  110. if (globalDescriptorHeap)
  111. {
  112. globalDescriptorHeap->release();
  113. }
  114. if (textureDescriptorHeap)
  115. {
  116. textureDescriptorHeap->release();
  117. }
  118. if (samplerDescriptorHeap)
  119. {
  120. samplerDescriptorHeap->release();
  121. }
  122. if (pipeline)
  123. {
  124. pipeline->release();
  125. }
  126. if (directCommandQueue)
  127. {
  128. directCommandQueue->flush();
  129. directCommandQueue->release();
  130. }
  131. if (rayGenSettingsBuffer)
  132. {
  133. rayGenSettingsBuffer->release();
  134. }
  135. if (defaultSamplerState)
  136. {
  137. defaultSamplerState->release();
  138. }
  139. texturRegister->release();
  140. if (uiTexture) uiTexture->release();
  141. if (defaultKamera) defaultKamera->release();
  142. if (defaultRenderTarget) defaultRenderTarget->release();
  143. if (signature) signature->Release();
  144. for (int i = 0; i < 2; i++)
  145. {
  146. if (backBuffer[i]) backBuffer[i]->Release();
  147. }
  148. if (swapChain) swapChain->Release();
  149. if (infoQueue) infoQueue->Release();
  150. if (device)
  151. {
  152. device->Release();
  153. getDLLRegister()->releaseDLL("dxgi.dll");
  154. getDLLRegister()->releaseDLL("d3d12.dll");
  155. }
  156. if (debug) debug->Release();
  157. }
  158. void DirectX12::updateBottomLevelAccelerationStructure()
  159. {
  160. cs.lock();
  161. bool updateRequired = 0;
  162. for (const Model3DData* model : *modelList->zModels())
  163. {
  164. if (model->wasIndexBufferChanged() || model->wasVertexBufferChanged())
  165. {
  166. updateRequired = true;
  167. break;
  168. }
  169. }
  170. int bufferCount = 0;
  171. if (updateRequired)
  172. {
  173. for (const Model3DData* model : *modelList->zModels())
  174. {
  175. int id = model->getId();
  176. blasModels[id]->calculateBuffers();
  177. bufferCount += blasModels[id]->getBufferCount();
  178. }
  179. }
  180. cs.unlock();
  181. }
  182. void Framework::DirectX12::renderKamera(
  183. Cam3D* zKamera, DX12Texture* zTarget, bool guiVisible)
  184. {
  185. updateBottomLevelAccelerationStructure();
  186. if (guiVisible)
  187. {
  188. uiTexture->updateTextur();
  189. }
  190. if (!pipeline)
  191. {
  192. setPipeline(new DX12Pipeline());
  193. }
  194. for (Texture* texture : *texturRegister->zTextures())
  195. {
  196. if (texture->hasBufferChanged())
  197. {
  198. textureDescriptorHeap->updateTextureInput(texture->getId(),
  199. DX12_SHADER_REGISTER_T_SHADER_RESOURCE,
  200. (DX12Texture*)texture);
  201. texture->setBufferChanged(0);
  202. }
  203. }
  204. directCommandQueue->zCommandList()->RSSetViewports(
  205. 1, (D3D12_VIEWPORT*)zKamera->zViewPort());
  206. World3D* w = zKamera->zWorld();
  207. if (w->getId() < 0)
  208. {
  209. w->setId(++lastTLASId);
  210. DX12TLAS** tmp = new DX12TLAS*[lastTLASId + 1];
  211. if (lastTLASId)
  212. {
  213. memcpy(tmp, worldTLAS, sizeof(DX12TLAS*) * lastTLASId);
  214. }
  215. tmp[lastTLASId] = new DX12TLAS(device, directCommandQueue);
  216. delete[] worldTLAS;
  217. worldTLAS = tmp;
  218. DX12ShaderBindingTable** tmpsbts
  219. = new DX12ShaderBindingTable*[lastTLASId + 1];
  220. if (lastTLASId)
  221. {
  222. memcpy(tmpsbts,
  223. worldShaderBindingTables,
  224. sizeof(DX12ShaderBindingTable*) * lastTLASId);
  225. }
  226. tmpsbts[lastTLASId] = pipeline->createShaderBindingTable();
  227. delete[] worldShaderBindingTables;
  228. worldShaderBindingTables = tmpsbts;
  229. }
  230. else if (worldShaderBindingTables[w->getId()]->zPipeline() != pipeline)
  231. {
  232. worldShaderBindingTables[w->getId()]->release();
  233. worldShaderBindingTables[w->getId()]
  234. = pipeline->createShaderBindingTable();
  235. }
  236. DX12TLAS* tlas = worldTLAS[w->getId()];
  237. DX12ShaderBindingTable* sbt = worldShaderBindingTables[w->getId()];
  238. tlas->startUpdate();
  239. sbt->startUpdate();
  240. // descriptor heaps must be set before filling the shader binding table with
  241. // hit groups
  242. sbt->setGlobalDescriptorHeap(globalDescriptorHeap);
  243. sbt->setTextureDescriptorHeap(textureDescriptorHeap);
  244. sbt->setSamplerDescriptorHeap(samplerDescriptorHeap);
  245. int objectIndex = 0;
  246. renderWorld(w, tlas, sbt, objectIndex);
  247. tlas->endUpdate();
  248. settings.inverseProjection = zKamera->getInverseProjectionMatrix();
  249. settings.inverseView = zKamera->getInverseViewMatrix();
  250. settings.minDistance = zKamera->getMinDistance();
  251. settings.maxDistance = zKamera->getMaxDistance();
  252. settings.useRays = 1;
  253. settings.renderGui = (int)guiVisible;
  254. rayGenSettingsBuffer->setData(&settings, 1);
  255. rayGenSettingsBuffer->copyToGPU(sizeof(settings));
  256. if (defaultRayGenerationShaderFunction)
  257. {
  258. globalDescriptorHeap->updateTextureInput(
  259. 0, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, zTarget);
  260. globalDescriptorHeap->updateTLASInput(
  261. 3, DX12_SHADER_REGISTER_T_SHADER_RESOURCE, tlas);
  262. }
  263. sbt->endUpdate(device, directCommandQueue);
  264. D3D12_DISPATCH_RAYS_DESC desc;
  265. sbt->fillDispatchRaysDesc(&desc);
  266. desc.Width = zTarget->zImage()->getWidth();
  267. desc.Height = zTarget->zImage()->getHeight();
  268. desc.Depth = 1;
  269. // order of definition in DX12DescriptorHeapType must be matched
  270. fillGlobalShaderParams(zKamera);
  271. directCommandQueue->zCommandList()->SetPipelineState1(
  272. pipeline->zPipelineState());
  273. directCommandQueue->zCommandList()->DispatchRays(&desc);
  274. }
  275. void Framework::DirectX12::renderWorld(World3D* zWorld,
  276. DX12TLAS* zTLAS,
  277. DX12ShaderBindingTable* zSBT,
  278. int& objectIndex)
  279. {
  280. Mat4<float> identity = Mat4<float>::identity();
  281. zWorld->render([this, &zTLAS, &objectIndex, &identity, &zSBT](
  282. Model3D* obj) {
  283. DX12RenderingData* renderingData
  284. = dynamic_cast<DX12RenderingData*>(obj->zRenderingData());
  285. if (!renderingData)
  286. {
  287. renderingData = new DX12RenderingData();
  288. obj->setRenderingData(renderingData);
  289. }
  290. int modelId = obj->zModelData()->getId();
  291. DX12BLASModel* blasModel = blasModels[modelId];
  292. bool changed
  293. = obj->getLastTickReturn()
  294. || renderingData->lastObjectIndex != objectIndex
  295. || renderingData->lastBlasCount != blasModel->getBufferCount()
  296. || obj->zModelData()->wasIndexBufferChanged()
  297. || obj->zModelData()->wasVertexBufferChanged();
  298. renderingData->lastObjectIndex = objectIndex;
  299. if (changed)
  300. {
  301. obj->calculateMatrices(identity, matrixBuffer);
  302. blasModel->calculateBuffers();
  303. }
  304. if (renderingData->lastBlasCount < blasModel->getBufferCount())
  305. {
  306. if (renderingData->lastHitGroupIndices)
  307. {
  308. delete[] renderingData->lastHitGroupIndices;
  309. }
  310. renderingData->lastHitGroupIndices
  311. = new int[blasModel->getBufferCount()];
  312. memset(renderingData->lastHitGroupIndices,
  313. -1,
  314. sizeof(int) * blasModel->getBufferCount());
  315. renderingData->lastBlasCount = blasModel->getBufferCount();
  316. }
  317. ArrayIterator<int> boneIds = blasModel->zBoneIds()->begin();
  318. int instanceIndex = 0;
  319. for (const DX12BLAS* blas : *blasModel->zBLAS())
  320. {
  321. if (changed)
  322. {
  323. D3D12_RAYTRACING_INSTANCE_DESC* desc
  324. = zTLAS->nextInstanceDesc();
  325. desc->InstanceID = objectIndex;
  326. desc->InstanceContributionToHitGroupIndex = objectIndex;
  327. desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
  328. desc->InstanceMask = 0xFF * (obj->getSize() > 0);
  329. desc->AccelerationStructure
  330. = blas->zResultBuffer()->zBuffer()->GetGPUVirtualAddress();
  331. memcpy(desc->Transform,
  332. &matrixBuffer[boneIds.val()],
  333. sizeof(float) * 12);
  334. }
  335. else
  336. {
  337. zTLAS->nextInstanceDesc();
  338. }
  339. boneIds++;
  340. fillShaderBindingTable(zSBT,
  341. obj,
  342. objectIndex,
  343. blas,
  344. renderingData->lastHitGroupIndices[instanceIndex]);
  345. instanceIndex++;
  346. objectIndex++;
  347. }
  348. });
  349. }
  350. void Framework::DirectX12::initializePipeline()
  351. {
  352. if (pipeline->getShaders().getEntryCount() == 0)
  353. { // add default shaders
  354. pipeline->zGlobalSignature()->addRegisterUsageLinkedToDescriptorHeap(
  355. 0, DX12_SHADER_REGISTER_S_SAMPLER, 0, 0, SAMPLER_DESCRIPTOR_HEAP);
  356. pipeline->zGlobalSignature()->addRegisterUsageLinkedToDescriptorHeap(0,
  357. DX12_SHADER_REGISTER_T_SHADER_RESOURCE,
  358. 0,
  359. 1,
  360. TEXTURE_DESCRIPTOR_HEAP,
  361. 1);
  362. DX12Shader* rayGenShader = new DX12Shader(
  363. DX12DefaultRayGenShaderBytes, sizeof(DX12DefaultRayGenShaderBytes));
  364. // RayGen from RayGen.hlsl
  365. DX12ShaderSignature* rayGenSignature = new DX12ShaderSignature();
  366. rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
  367. 0, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, 0);
  368. rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
  369. 1, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, 1);
  370. rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
  371. 2, DX12_SHADER_REGISTER_B_CONST_BUFFER, 0);
  372. rayGenSignature->addRegisterUsageLinkedToDescriptorHeap(
  373. 3, DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 0);
  374. defaultRayGenerationShaderFunction = new DX12ShaderFunction(
  375. "RayGen", rayGenSignature, DX12_SHADER_FUNCTION_TYPE_RAY_GEN);
  376. rayGenShader->addFunction(defaultRayGenerationShaderFunction);
  377. pipeline->addShader(rayGenShader);
  378. DX12Shader* missShader = new DX12Shader(
  379. DX12DefaultMissShaderBytes, sizeof(DX12DefaultMissShaderBytes));
  380. // Miss from Miss.hlsl
  381. missShader->addFunction(new DX12ShaderFunction(
  382. "Miss", new DX12ShaderSignature(), DX12_SHADER_FUNCTION_TYPE_MISS));
  383. pipeline->addShader(missShader);
  384. DX12ShaderSignature* hitSignature = new DX12ShaderSignature();
  385. sbtTextureIdBufferOffset
  386. = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
  387. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 2);
  388. sbtIndexBufferOffset
  389. = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
  390. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 3);
  391. sbtVertexDataBufferOffset
  392. = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
  393. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 4);
  394. sbtPolygonSizeBufferOffset
  395. = hitSignature->addRegisterUsageLinkedToShaderBindingTable(
  396. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 1, 5);
  397. DX12Shader* anyHitShader = new DX12Shader(
  398. DX12DefaultAnyHitShaderBytes, sizeof(DX12DefaultAnyHitShaderBytes));
  399. DX12ShaderFunction* anyHitFunction = new DX12ShaderFunction(
  400. "AnyHit", hitSignature, DX12_SHADER_FUNCTION_TYPE_ANY_HIT);
  401. // AnyHit from AnyHit.hlsl
  402. anyHitShader->addFunction(anyHitFunction);
  403. pipeline->addShader(anyHitShader);
  404. DX12Shader* hitShader = new DX12Shader(
  405. DX12DefaultHitShaderBytes, sizeof(DX12DefaultHitShaderBytes));
  406. // ClosestHit from Hit.hlsl
  407. DX12ShaderFunction* closestHitFunction
  408. = new DX12ShaderFunction("ClosestHit",
  409. dynamic_cast<DX12ShaderSignature*>(hitSignature->getThis()),
  410. DX12_SHADER_FUNCTION_TYPE_CLOSEST_HIT);
  411. hitShader->addFunction(closestHitFunction);
  412. pipeline->addShader(hitShader);
  413. defaultHitGroup = new DX12ShaderHitGroup("HitGroup");
  414. defaultHitGroup->setAttributeSize(8);
  415. defaultHitGroup->setPayloadSize(20 * DEFAULT_MAX_TRANSPARENT_HITS + 4);
  416. defaultHitGroup->setAnyHitShaderFunction(anyHitFunction);
  417. defaultHitGroup->setClosestHitShaderFunction(closestHitFunction);
  418. pipeline->addHitGroup(defaultHitGroup);
  419. pipeline->setMaxRecursionDepth(10);
  420. }
  421. pipeline->createPipelineState(device, pfnD3D12SerializeRootSignature);
  422. }
  423. void Framework::DirectX12::initializeGlobalDescriptorHeap()
  424. {
  425. globalDescriptorHeap->addTextureInput(
  426. DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, defaultRenderTarget);
  427. globalDescriptorHeap->addTextureInput(
  428. DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, uiTexture);
  429. globalDescriptorHeap->addBufferInput(
  430. DX12_SHADER_REGISTER_B_CONST_BUFFER, rayGenSettingsBuffer);
  431. globalDescriptorHeap->addTLASInput(
  432. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, 0);
  433. globalDescriptorHeap->updateDescriptorHeap(device);
  434. }
  435. void Framework::DirectX12::initializeTextureDescriptorHeap()
  436. {
  437. for (Texture* tex : *texturRegister->zTextures())
  438. {
  439. textureDescriptorHeap->addTextureInput(
  440. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, tex);
  441. tex->setBufferChanged(0);
  442. }
  443. textureDescriptorHeap->updateDescriptorHeap(device);
  444. }
  445. void Framework::DirectX12::initializeSamplerDescriptorHeap()
  446. {
  447. if (!defaultSamplerState)
  448. {
  449. defaultSamplerState = new DX12SamplerState();
  450. (*defaultSamplerState)->Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
  451. (*defaultSamplerState)->AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
  452. (*defaultSamplerState)->AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
  453. (*defaultSamplerState)->AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
  454. (*defaultSamplerState)->MipLODBias = 0;
  455. (*defaultSamplerState)->MaxAnisotropy = 1;
  456. (*defaultSamplerState)->ComparisonFunc = D3D12_COMPARISON_FUNC_NONE;
  457. (*defaultSamplerState)->BorderColor[0] = 0.f;
  458. (*defaultSamplerState)->BorderColor[1] = 0.f;
  459. (*defaultSamplerState)->BorderColor[2] = 0.f;
  460. (*defaultSamplerState)->BorderColor[3] = 0.f;
  461. (*defaultSamplerState)->MinLOD = 0.0f;
  462. (*defaultSamplerState)->MaxLOD = D3D12_FLOAT32_MAX;
  463. }
  464. samplerDescriptorHeap->addSamplerInput(defaultSamplerState);
  465. samplerDescriptorHeap->updateDescriptorHeap(device);
  466. }
  467. void Framework::DirectX12::fillShaderBindingTable(
  468. DX12ShaderBindingTable* zShaderBindingTable,
  469. Model3D* zModel,
  470. int instanceIndex,
  471. const DX12BLAS* zBLAS,
  472. int& lastHitGroupIndex)
  473. {
  474. if (defaultHitGroup)
  475. {
  476. int hitGroupOffset = zShaderBindingTable->addHitGroup(
  477. defaultHitGroup, lastHitGroupIndex);
  478. bool changed = hitGroupOffset != lastHitGroupIndex;
  479. lastHitGroupIndex = hitGroupOffset;
  480. if (changed)
  481. { // TODO: check if the buffers are valid and have been recreated
  482. zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
  483. sbtIndexBufferOffset,
  484. zBLAS->zIndexBuffer()->zBuffer()->GetGPUVirtualAddress());
  485. zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
  486. sbtVertexDataBufferOffset,
  487. zBLAS->zVertexDataBuffer()->zBuffer()->GetGPUVirtualAddress());
  488. zModel->zTexture()->updateTextureIndexBuffer(this);
  489. zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
  490. sbtTextureIdBufferOffset,
  491. dynamic_cast<DX12Buffer*>(
  492. zModel->zTexture()->zTextureIndexBuffer())
  493. ->zBuffer()
  494. ->GetGPUVirtualAddress());
  495. zShaderBindingTable->setHitGroupShaderInput(hitGroupOffset,
  496. sbtPolygonSizeBufferOffset,
  497. zBLAS->zPolygonSizeBuffer()->zBuffer()->GetGPUVirtualAddress());
  498. }
  499. }
  500. }
  501. int Framework::DirectX12::fillGlobalShaderParams(Cam3D* zKam, int startIndex)
  502. {
  503. ID3D12DescriptorHeap* heaps[]
  504. = {pipeline->zGlobalSignature()->doesUseTextureDescriptorHeap()
  505. ? textureDescriptorHeap->zDescriptorHeap()
  506. : globalDescriptorHeap->zDescriptorHeap(),
  507. samplerDescriptorHeap->zDescriptorHeap()};
  508. directCommandQueue->zCommandList()->SetDescriptorHeaps(2, heaps);
  509. if (pipeline->zGlobalSignature()->gerShaderBindingTableParamCount()
  510. + pipeline->zGlobalSignature()
  511. ->getDescriptorHeapBindings()
  512. .getEntryCount()
  513. > startIndex)
  514. {
  515. if (startIndex == 0)
  516. {
  517. directCommandQueue->zCommandList()->SetComputeRootSignature(
  518. pipeline->zGlobalSignature()->zSignature());
  519. }
  520. if (pipeline->zGlobalSignature()->doesUseGlobalDescriptorHeap())
  521. {
  522. directCommandQueue->zCommandList()->SetComputeRootDescriptorTable(
  523. startIndex++,
  524. globalDescriptorHeap->zDescriptorHeap()
  525. ->GetGPUDescriptorHandleForHeapStart());
  526. }
  527. if (pipeline->zGlobalSignature()->doesUseTextureDescriptorHeap())
  528. {
  529. directCommandQueue->zCommandList()->SetComputeRootDescriptorTable(
  530. startIndex++,
  531. textureDescriptorHeap->zDescriptorHeap()
  532. ->GetGPUDescriptorHandleForHeapStart());
  533. }
  534. if (pipeline->zGlobalSignature()->doesUseSamplerDescriptorHeap())
  535. {
  536. directCommandQueue->zCommandList()->SetComputeRootDescriptorTable(
  537. startIndex++,
  538. samplerDescriptorHeap->zDescriptorHeap()
  539. ->GetGPUDescriptorHandleForHeapStart());
  540. }
  541. }
  542. return startIndex;
  543. }
  544. typedef HRESULT(__stdcall* CreateDXGIFactory2Function)(UINT, REFIID, void**);
  545. typedef HRESULT(__stdcall* D3D12CreateDeviceFunction)(
  546. IDXGIAdapter*, D3D_FEATURE_LEVEL, REFIID, void**);
  547. typedef HRESULT(__stdcall* D3D12GetDebugInterfaceFunction)(REFIID, void**);
  548. typedef HRESULT(__stdcall* DXGIGetDebugInterface1Function)(
  549. UINT Flags, REFIID riid, _COM_Outptr_ void** pDebug);
  550. void DirectX12::initialize(
  551. NativeWindow* fenster, Vec2<int> backBufferSize, bool fullScreen)
  552. {
  553. GraphicsApi::initialize(fenster, backBufferSize, fullScreen);
  554. #ifdef _DEBUG
  555. if (debugDX)
  556. {
  557. HINSTANCE pixDebugger = getDLLRegister()->loadDLL(
  558. "WinPixGpuCapturer.dll",
  559. "C:\\Program Files\\Microsoft PIX\\2603.25\\WinPixGpuCapturer.dll");
  560. }
  561. #endif
  562. HINSTANCE dxgiDLL = getDLLRegister()->loadDLL("dxgi.dll", "dxgi.dll");
  563. if (!dxgiDLL)
  564. {
  565. WMessageBox(fenster->getWindowHandle(),
  566. new Text("Fehler"),
  567. new Text("dxgi.dll konnte nicht gefunden werden."),
  568. MB_ICONERROR);
  569. return;
  570. }
  571. HINSTANCE d3d12DLL = getDLLRegister()->loadDLL("d3d12.dll", "d3d12.dll");
  572. if (!d3d12DLL)
  573. {
  574. getDLLRegister()->releaseDLL("dxgi.dll");
  575. WMessageBox(fenster->getWindowHandle(),
  576. new Text("Fehler"),
  577. new Text("DirectX 12 konnte nicht gefunden werden."),
  578. MB_ICONERROR);
  579. return;
  580. }
  581. pfnD3D12SerializeRootSignature
  582. = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(
  583. d3d12DLL, "D3D12SerializeRootSignature");
  584. if (!pfnD3D12SerializeRootSignature)
  585. {
  586. getDLLRegister()->releaseDLL("dxgi.dll");
  587. getDLLRegister()->releaseDLL("d3d12.dll");
  588. WMessageBox(fenster->getWindowHandle(),
  589. new Text("Fehler"),
  590. new Text(
  591. "Der Einstiegspunkt D3D12SerializeRootSignature fon d3d12.dll "
  592. "konnte nicht gefunden werden."),
  593. MB_ICONERROR);
  594. return;
  595. }
  596. // CreateDXGIFactory2
  597. CreateDXGIFactory2Function createFactory
  598. = (CreateDXGIFactory2Function)GetProcAddress(
  599. dxgiDLL, "CreateDXGIFactory2");
  600. if (!createFactory)
  601. {
  602. getDLLRegister()->releaseDLL("dxgi.dll");
  603. getDLLRegister()->releaseDLL("d3d12.dll");
  604. WMessageBox(fenster->getWindowHandle(),
  605. new Text("Fehler"),
  606. new Text(
  607. "Der Einstiegspunkt CreateDXGIFactory2 fon dxgi.dll konnte "
  608. "nicht gefunden werden."),
  609. MB_ICONERROR);
  610. return;
  611. }
  612. // D3D12CreateDevice
  613. D3D12CreateDeviceFunction createDevice
  614. = (D3D12CreateDeviceFunction)GetProcAddress(
  615. d3d12DLL, "D3D12CreateDevice");
  616. if (!createDevice)
  617. {
  618. getDLLRegister()->releaseDLL("dxgi.dll");
  619. getDLLRegister()->releaseDLL("d3d12.dll");
  620. WMessageBox(fenster->getWindowHandle(),
  621. new Text("Fehler"),
  622. new Text("Der Einstiegspunkt D3D12CreateDevice fon DirectX 12 "
  623. "konnte nicht gefunden werden."),
  624. MB_ICONERROR);
  625. return;
  626. }
  627. // D3D12SerializeVersionedRootSignature
  628. PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE d3d12svrsf
  629. = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)GetProcAddress(
  630. d3d12DLL, "D3D12SerializeVersionedRootSignature");
  631. // D3D12SerializeRootSignature
  632. PFN_D3D12_SERIALIZE_ROOT_SIGNATURE d3d12srsf
  633. = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(
  634. d3d12DLL, "D3D12SerializeRootSignature");
  635. bool debugDXGI = 0;
  636. #ifdef _DEBUG
  637. IDXGIInfoQueue* dxgiInfoQueue;
  638. if (debugDX)
  639. {
  640. // D3D12GetDebugInterface
  641. D3D12GetDebugInterfaceFunction getDebugInterface
  642. = (D3D12GetDebugInterfaceFunction)GetProcAddress(
  643. d3d12DLL, "D3D12GetDebugInterface");
  644. if (SUCCEEDED(getDebugInterface(__uuidof(ID3D12Debug), (void**)&debug)))
  645. debug->EnableDebugLayer();
  646. // DXGIGetDebugInterface1
  647. DXGIGetDebugInterface1Function dxgiDebugInterface
  648. = (DXGIGetDebugInterface1Function)GetProcAddress(
  649. dxgiDLL, "DXGIGetDebugInterface1");
  650. if (SUCCEEDED(dxgiDebugInterface(
  651. 0, __uuidof(IDXGIInfoQueue), (void**)&dxgiInfoQueue)))
  652. debugDXGI = 1;
  653. }
  654. #endif
  655. IDXGIFactory6* factory;
  656. UINT createFactoryFlags = 0;
  657. #if defined(_DEBUG)
  658. if (debugDX && debugDXGI) createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  659. #endif
  660. HRESULT res = createFactory(
  661. createFactoryFlags, __uuidof(IDXGIFactory6), (void**)&factory);
  662. if (FAILED(res))
  663. {
  664. getDLLRegister()->releaseDLL("dxgi.dll");
  665. getDLLRegister()->releaseDLL("d3d12.dll");
  666. Logging::error() << "ERROR DXGI: createFactory returned " << res
  667. << "\n";
  668. WMessageBox(fenster->getWindowHandle(),
  669. new Text("Fehler"),
  670. new Text("createFactory ist Fehlgeschlagen."),
  671. MB_ICONERROR);
  672. return;
  673. }
  674. IDXGIAdapter1* adapter = 0;
  675. for (UINT adapterID = 0; DXGI_ERROR_NOT_FOUND
  676. != factory->EnumAdapterByGpuPreference(adapterID,
  677. DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
  678. __uuidof(IDXGIAdapter1),
  679. (void**)&adapter);
  680. ++adapterID)
  681. {
  682. DXGI_ADAPTER_DESC1 desc;
  683. adapter->GetDesc1(&desc);
  684. if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
  685. {
  686. adapter->Release();
  687. // Don't select the Basic Render Driver adapter.
  688. continue;
  689. }
  690. // Check to see if the adapter supports Direct3D 12, but don't create
  691. // the actual device yet.
  692. if (SUCCEEDED(createDevice(adapter,
  693. D3D_FEATURE_LEVEL_12_1,
  694. _uuidof(ID3D12Device),
  695. nullptr)))
  696. {
  697. char buff[256] = {};
  698. printf_s(buff,
  699. L"Direct3D Adapter (%u): VID:%04X, PID:%04X - %ls\n",
  700. adapterID,
  701. desc.VendorId,
  702. desc.DeviceId,
  703. desc.Description);
  704. Logging::info() << buff;
  705. break;
  706. }
  707. adapter->Release();
  708. }
  709. if (!adapter)
  710. {
  711. if (FAILED(factory->EnumWarpAdapter(
  712. _uuidof(IDXGIAdapter1), (void**)&adapter)))
  713. Logging::error()
  714. << "ERROR: WARP12 not available. Enable the 'Graphics "
  715. "Tools' optional feature";
  716. }
  717. if (!adapter)
  718. {
  719. factory->Release();
  720. getDLLRegister()->releaseDLL("dxgi.dll");
  721. getDLLRegister()->releaseDLL("d3d12.dll");
  722. WMessageBox(fenster->getWindowHandle(),
  723. new Text("Fehler"),
  724. new Text("Es wurde keine passende Grafigkarte gefunden."),
  725. MB_ICONERROR);
  726. return;
  727. }
  728. res = createDevice(adapter,
  729. D3D_FEATURE_LEVEL_12_1,
  730. __uuidof(ID3D12Device5),
  731. (void**)&device);
  732. adapter->Release();
  733. if (FAILED(res))
  734. {
  735. factory->Release();
  736. getDLLRegister()->releaseDLL("dxgi.dll");
  737. getDLLRegister()->releaseDLL("d3d12.dll");
  738. Logging::error() << "ERROR: createDevice returned " << res << "\n";
  739. WMessageBox(fenster->getWindowHandle(),
  740. new Text("Fehler"),
  741. new Text("createDevice ist Fehlgeschlagen."),
  742. MB_ICONERROR);
  743. return;
  744. }
  745. D3D12_FEATURE_DATA_D3D12_OPTIONS5 featureSupportData = {};
  746. device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5,
  747. &featureSupportData,
  748. sizeof(featureSupportData));
  749. if (featureSupportData.RaytracingTier < D3D12_RAYTRACING_TIER_1_0)
  750. {
  751. device->Release();
  752. factory->Release();
  753. getDLLRegister()->releaseDLL("dxgi.dll");
  754. getDLLRegister()->releaseDLL("d3d12.dll");
  755. Logging::error() << "ERROR: Raytracing is not available\n";
  756. WMessageBox(fenster->getWindowHandle(),
  757. new Text("Fehler"),
  758. new Text("Raytracing ist nicht verfügbar. DirectX12 kann nicht "
  759. "verwendet werden."),
  760. MB_ICONERROR);
  761. return;
  762. }
  763. res = device->QueryInterface(__uuidof(ID3D12InfoQueue), (void**)&infoQueue);
  764. if (SUCCEEDED(res))
  765. {
  766. if (debugDX)
  767. {
  768. infoQueue->SetBreakOnSeverity(
  769. D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
  770. infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
  771. infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, TRUE);
  772. }
  773. // Suppress individual messages by their ID
  774. D3D12_MESSAGE_ID DenyIds[] = {
  775. // D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE, //
  776. // I'm really not sure how to avoid this message.
  777. D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE, // This warning occurs when
  778. // using capture frame while
  779. // graphics debugging.
  780. D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE, // This warning occurs
  781. // when using capture
  782. // frame while graphics
  783. // debugging.
  784. };
  785. D3D12_INFO_QUEUE_FILTER NewFilter = {};
  786. NewFilter.DenyList.NumSeverities = 0; //_countof( Severities );
  787. NewFilter.DenyList.pSeverityList = 0; // Severities;
  788. NewFilter.DenyList.NumIDs = _countof(DenyIds);
  789. NewFilter.DenyList.pIDList = DenyIds;
  790. infoQueue->PushStorageFilter(&NewFilter);
  791. }
  792. directCommandQueue = new DX12DirectCommandQueue(device);
  793. settings.minDistance = 0.0f;
  794. settings.maxDistance = 100000.f;
  795. settings.renderGui = 0;
  796. settings.useRays = 0;
  797. rayGenSettingsBuffer = new DX12Buffer(1,
  798. device,
  799. dynamic_cast<DX12CommandQueue*>(directCommandQueue->getThis()),
  800. D3D12_RESOURCE_FLAG_NONE);
  801. rayGenSettingsBuffer->setLength(
  802. ROUND_UP_POWER_OF_2(sizeof(RayGenerationSettings), 256));
  803. rayGenSettingsBuffer->setData(&settings, 1);
  804. rayGenSettingsBuffer->copyToGPU(sizeof(RayGenerationSettings));
  805. IDXGIFactory5* fac5 = 0;
  806. factory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&fac5);
  807. if (fac5)
  808. {
  809. res = fac5->CheckFeatureSupport(
  810. DXGI_FEATURE_PRESENT_ALLOW_TEARING, &tearing, sizeof(tearing));
  811. if (FAILED(res)) tearing = 0;
  812. fac5->Release();
  813. }
  814. DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
  815. swapChainDesc.Width = backBufferSize.x;
  816. swapChainDesc.Height = backBufferSize.y;
  817. swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
  818. swapChainDesc.Stereo = FALSE;
  819. swapChainDesc.SampleDesc = {1, 0};
  820. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  821. swapChainDesc.BufferCount = 2;
  822. swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
  823. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
  824. swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
  825. swapChainDesc.Flags = tearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
  826. IDXGISwapChain1* tmpSwapChain;
  827. res = factory->CreateSwapChainForHwnd(directCommandQueue->zQueue(),
  828. fenster->getWindowHandle(),
  829. &swapChainDesc,
  830. 0,
  831. 0,
  832. &tmpSwapChain);
  833. if (FAILED(res))
  834. {
  835. factory->Release();
  836. Logging::error() << "ERROR: CreateSwapChainForHwnd returned " << res
  837. << "\n";
  838. WMessageBox(fenster->getWindowHandle(),
  839. new Text("Fehler"),
  840. new Text("CreateSwapChainForHwnd ist Fehlgeschlagen."),
  841. MB_ICONERROR);
  842. return;
  843. }
  844. res = tmpSwapChain->QueryInterface(
  845. __uuidof(IDXGISwapChain4), (void**)&swapChain);
  846. tmpSwapChain->Release();
  847. if (FAILED(res))
  848. {
  849. factory->Release();
  850. Logging::error() << "ERROR: QueryInterface returned " << res << "\n";
  851. WMessageBox(fenster->getWindowHandle(),
  852. new Text("Fehler"),
  853. new Text("QueryInterface ist Fehlgeschlagen."),
  854. MB_ICONERROR);
  855. return;
  856. }
  857. factory->MakeWindowAssociation(
  858. fenster->getWindowHandle(), DXGI_MWA_NO_ALT_ENTER);
  859. for (int i = 0; i < 2; i++)
  860. {
  861. ID3D12Resource* backBuffer;
  862. res = swapChain->GetBuffer(
  863. i, __uuidof(ID3D12Resource), (void**)&backBuffer);
  864. if (FAILED(res))
  865. {
  866. factory->Release();
  867. Logging::error() << "ERROR: GetBuffer returned " << res << "\n";
  868. WMessageBox(fenster->getWindowHandle(),
  869. new Text("Fehler"),
  870. new Text("GetBuffer ist Fehlgeschlagen."),
  871. MB_ICONERROR);
  872. return;
  873. }
  874. this->backBuffer[i] = backBuffer;
  875. }
  876. Image* renderTargetImage = new Image();
  877. renderTargetImage->newImage(backBufferSize.x, backBufferSize.y, 0);
  878. defaultRenderTarget = dynamic_cast<DX12Texture*>(
  879. createOrGetTexture("_f_RenderTarget", renderTargetImage, GPU_TO_RAM));
  880. defaultRenderTarget->updateTextur();
  881. Image* renderB = new Image(1);
  882. renderB->setAlpha3D(1);
  883. renderB->newImage(this->backBufferSize.x, this->backBufferSize.y, 0);
  884. uiTexture = createOrGetTexture("_f_Render_Image", renderB, RAM_TO_GPU);
  885. D3D12_FEATURE_DATA_ROOT_SIGNATURE featureData = {};
  886. featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1;
  887. if (FAILED(device->CheckFeatureSupport(
  888. D3D12_FEATURE_ROOT_SIGNATURE, &featureData, sizeof(featureData))))
  889. featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0;
  890. D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags
  891. = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT
  892. | D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS
  893. | D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS
  894. | D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS;
  895. D3D12_DESCRIPTOR_RANGE1 range[2];
  896. range[0].NumDescriptors = 5;
  897. range[0].BaseShaderRegister = 0;
  898. range[0].RegisterSpace = 0;
  899. range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
  900. range[0].OffsetInDescriptorsFromTableStart
  901. = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
  902. range[0].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
  903. range[1].NumDescriptors = 1;
  904. range[1].BaseShaderRegister = 0;
  905. range[1].RegisterSpace = 0;
  906. range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
  907. range[1].OffsetInDescriptorsFromTableStart
  908. = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
  909. range[1].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
  910. D3D12_ROOT_PARAMETER1 rootParameters[1];
  911. rootParameters[0].ParameterType
  912. = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
  913. rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
  914. rootParameters[0].DescriptorTable.NumDescriptorRanges = 2;
  915. rootParameters[0].DescriptorTable.pDescriptorRanges = range;
  916. D3D12_STATIC_SAMPLER_DESC sampler = {};
  917. sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
  918. sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
  919. sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
  920. sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
  921. sampler.MipLODBias = 0;
  922. sampler.MaxAnisotropy = 0;
  923. sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
  924. sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
  925. sampler.MinLOD = 0.0f;
  926. sampler.MaxLOD = D3D12_FLOAT32_MAX;
  927. sampler.ShaderRegister = 0;
  928. sampler.RegisterSpace = 0;
  929. sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
  930. D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDescription;
  931. rootSignatureDescription.Version = D3D_ROOT_SIGNATURE_VERSION_1_1;
  932. rootSignatureDescription.Desc_1_1.NumParameters = 1;
  933. rootSignatureDescription.Desc_1_1.pParameters = rootParameters;
  934. rootSignatureDescription.Desc_1_1.NumStaticSamplers = 1;
  935. rootSignatureDescription.Desc_1_1.pStaticSamplers = &sampler;
  936. rootSignatureDescription.Desc_1_1.Flags = rootSignatureFlags;
  937. ID3DBlob* rootSignature;
  938. ID3DBlob* error;
  939. res = D3DX12SerializeVersionedRootSignature(&rootSignatureDescription,
  940. featureData.HighestVersion,
  941. &rootSignature,
  942. &error,
  943. d3d12svrsf,
  944. d3d12srsf);
  945. if (FAILED(res))
  946. {
  947. factory->Release();
  948. Logging::error()
  949. << "ERROR: D3DX12SerializeVersionedRootSignature returned " << res
  950. << "\n";
  951. WMessageBox(fenster->getWindowHandle(),
  952. new Text("Fehler"),
  953. new Text(
  954. "D3DX12SerializeVersionedRootSignature ist Fehlgeschlagen."),
  955. MB_ICONERROR);
  956. if (error) error->Release();
  957. return;
  958. }
  959. res = device->CreateRootSignature(0,
  960. rootSignature->GetBufferPointer(),
  961. rootSignature->GetBufferSize(),
  962. __uuidof(ID3D12RootSignature),
  963. (void**)&signature);
  964. if (FAILED(res))
  965. {
  966. factory->Release();
  967. Logging::error() << "ERROR: CreateRootSignature returned " << res
  968. << "\n";
  969. WMessageBox(fenster->getWindowHandle(),
  970. new Text("Fehler"),
  971. new Text("CreateRootSignature ist Fehlgeschlagen."),
  972. MB_ICONERROR);
  973. return;
  974. }
  975. rootSignature->Release();
  976. D3D12_RASTERIZER_DESC rdesc;
  977. rdesc.FillMode = D3D12_FILL_MODE_SOLID;
  978. rdesc.CullMode = D3D12_CULL_MODE_BACK;
  979. rdesc.FrontCounterClockwise = 0;
  980. rdesc.DepthBias = 0;
  981. rdesc.DepthBiasClamp = 0.f;
  982. rdesc.SlopeScaledDepthBias = 0.f;
  983. rdesc.DepthClipEnable = 1;
  984. rdesc.MultisampleEnable = 0;
  985. rdesc.AntialiasedLineEnable = 0;
  986. rdesc.ForcedSampleCount = 0;
  987. rdesc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
  988. uiTexture->updateTextur();
  989. directCommandQueue->execute();
  990. factory->Release();
  991. }
  992. void DirectX12::beginFrame(bool fill2D, bool fill3D, int fillColor)
  993. {
  994. cs.lock();
  995. cameraCount = 0;
  996. D3D12_RESOURCE_BARRIER barrier;
  997. ZeroMemory(&barrier, sizeof(barrier));
  998. barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  999. barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  1000. barrier.Transition.pResource = this->backBuffer[backBufferIndex];
  1001. barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
  1002. barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
  1003. barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
  1004. directCommandQueue->zCommandList()->ResourceBarrier(1, &barrier);
  1005. if (fill2D) uiTexture->zImage()->setColor(fillColor);
  1006. CD3DX12_RESOURCE_BARRIER transition
  1007. = CD3DX12_RESOURCE_BARRIER::Transition(defaultRenderTarget->zResource(),
  1008. D3D12_RESOURCE_STATE_COPY_SOURCE,
  1009. D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
  1010. directCommandQueue->zCommandList()->ResourceBarrier(1, &transition);
  1011. }
  1012. void DirectX12::renderKamera(Cam3D* zKamera)
  1013. {
  1014. cameraCount++;
  1015. renderKamera(zKamera, defaultRenderTarget, true);
  1016. }
  1017. void Framework::DirectX12::renderKamera(Cam3D* zKamera, Texture* zTarget)
  1018. {
  1019. cameraCount++;
  1020. renderKamera(zKamera, dynamic_cast<DX12Texture*>(zTarget), false);
  1021. }
  1022. void DirectX12::presentFrame()
  1023. {
  1024. if (cameraCount == 0)
  1025. {
  1026. if (!defaultKamera)
  1027. {
  1028. defaultKamera = new Cam3D();
  1029. defaultKamera->setWorld(new World3D());
  1030. defaultKamera->setScreenSize(backBufferSize);
  1031. }
  1032. renderKamera(defaultKamera);
  1033. }
  1034. CD3DX12_RESOURCE_BARRIER transition
  1035. = CD3DX12_RESOURCE_BARRIER::Transition(defaultRenderTarget->zResource(),
  1036. D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
  1037. D3D12_RESOURCE_STATE_COPY_SOURCE);
  1038. directCommandQueue->zCommandList()->ResourceBarrier(1, &transition);
  1039. transition
  1040. = CD3DX12_RESOURCE_BARRIER::Transition(backBuffer[backBufferIndex],
  1041. D3D12_RESOURCE_STATE_RENDER_TARGET,
  1042. D3D12_RESOURCE_STATE_COPY_DEST);
  1043. directCommandQueue->zCommandList()->ResourceBarrier(1, &transition);
  1044. directCommandQueue->zCommandList()->CopyResource(
  1045. backBuffer[backBufferIndex], defaultRenderTarget->zResource());
  1046. transition
  1047. = CD3DX12_RESOURCE_BARRIER::Transition(backBuffer[backBufferIndex],
  1048. D3D12_RESOURCE_STATE_COPY_DEST,
  1049. D3D12_RESOURCE_STATE_RENDER_TARGET);
  1050. directCommandQueue->zCommandList()->ResourceBarrier(1, &transition);
  1051. // Indicate that the back buffer will now be used to present.
  1052. transition
  1053. = CD3DX12_RESOURCE_BARRIER::Transition(backBuffer[backBufferIndex],
  1054. D3D12_RESOURCE_STATE_RENDER_TARGET,
  1055. D3D12_RESOURCE_STATE_PRESENT);
  1056. directCommandQueue->zCommandList()->ResourceBarrier(1, &transition);
  1057. directCommandQueue->execute();
  1058. swapChain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
  1059. globalDescriptorHeap->setHeapChanged(0);
  1060. textureDescriptorHeap->setHeapChanged(0);
  1061. samplerDescriptorHeap->setHeapChanged(0);
  1062. backBufferIndex = swapChain->GetCurrentBackBufferIndex();
  1063. cs.unlock();
  1064. }
  1065. Texture* DirectX12::createOrGetTexture(
  1066. const char* name, Image* b, TextureDirection dir)
  1067. {
  1068. if (!device)
  1069. {
  1070. if (b) b->release();
  1071. return 0;
  1072. }
  1073. if (texturRegister->hasTexture(name))
  1074. {
  1075. Texture* ret = texturRegister->getTexture(name);
  1076. if (b) ret->setImageZ(b);
  1077. return ret;
  1078. }
  1079. cs.lock();
  1080. Texture* ret = new DX12Texture(device, directCommandQueue, dir);
  1081. if (b) ret->setImageZ(b);
  1082. texturRegister->addTexture(dynamic_cast<Texture*>(ret->getThis()), name);
  1083. ret->updateTextur();
  1084. if (textureDescriptorHeap)
  1085. {
  1086. textureDescriptorHeap->addTextureInput(
  1087. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, ret);
  1088. textureDescriptorHeap->updateDescriptorHeap(device);
  1089. ret->setBufferChanged(0);
  1090. }
  1091. // directCommandQueue->execute();
  1092. cs.unlock();
  1093. return ret;
  1094. }
  1095. Image* DirectX12::zUIRenderImage() const
  1096. {
  1097. return uiTexture ? uiTexture->zImage() : 0;
  1098. }
  1099. DXBuffer* DirectX12::createStructuredBuffer(int eSize)
  1100. {
  1101. return new DX12Buffer(eSize,
  1102. device,
  1103. dynamic_cast<DX12CommandQueue*>(directCommandQueue->getThis()),
  1104. D3D12_RESOURCE_FLAG_NONE);
  1105. }
  1106. Model3DData* Framework::DirectX12::createModel(const char* name)
  1107. {
  1108. cs.lock();
  1109. Model3DData* result = GraphicsApi::createModel(name);
  1110. lastModelId = result->getId();
  1111. if (result)
  1112. {
  1113. DX12BLASModel** newBlasModels = new DX12BLASModel*[lastModelId + 1];
  1114. if (lastModelId > 0)
  1115. {
  1116. memcpy(newBlasModels,
  1117. blasModels,
  1118. sizeof(DX12BLASModel*) * lastModelId);
  1119. }
  1120. newBlasModels[lastModelId]
  1121. = new DX12BLASModel(result, device, directCommandQueue);
  1122. delete[] blasModels;
  1123. blasModels = newBlasModels;
  1124. }
  1125. cs.unlock();
  1126. return result;
  1127. }
  1128. void Framework::DirectX12::setPipeline(DX12Pipeline* pipeline)
  1129. {
  1130. if (this->pipeline)
  1131. {
  1132. this->pipeline->release();
  1133. }
  1134. this->pipeline = pipeline;
  1135. if (pipeline)
  1136. {
  1137. initializePipeline();
  1138. if (!globalDescriptorHeap
  1139. || globalDescriptorHeap->zPipeline() != pipeline)
  1140. {
  1141. if (globalDescriptorHeap)
  1142. {
  1143. globalDescriptorHeap->release();
  1144. }
  1145. globalDescriptorHeap
  1146. = pipeline->createGlobalDescriptorHeap(GLOBAL_DESCRIPTOR_HEAP);
  1147. initializeGlobalDescriptorHeap();
  1148. }
  1149. if (!textureDescriptorHeap
  1150. || textureDescriptorHeap->zPipeline() != pipeline)
  1151. {
  1152. if (textureDescriptorHeap)
  1153. {
  1154. textureDescriptorHeap->release();
  1155. }
  1156. textureDescriptorHeap
  1157. = pipeline->createGlobalDescriptorHeap(TEXTURE_DESCRIPTOR_HEAP);
  1158. initializeTextureDescriptorHeap();
  1159. }
  1160. if (!samplerDescriptorHeap
  1161. || samplerDescriptorHeap->zPipeline() != pipeline)
  1162. {
  1163. if (samplerDescriptorHeap)
  1164. {
  1165. samplerDescriptorHeap->release();
  1166. }
  1167. samplerDescriptorHeap
  1168. = pipeline->createGlobalDescriptorHeap(SAMPLER_DESCRIPTOR_HEAP);
  1169. initializeSamplerDescriptorHeap();
  1170. }
  1171. }
  1172. }
  1173. bool DirectX12::isAvailable()
  1174. {
  1175. HINSTANCE dxgiDLL = getDLLRegister()->loadDLL("dxgi.dll", "dxgi.dll");
  1176. if (!dxgiDLL) return 0;
  1177. HINSTANCE d3d12DLL = getDLLRegister()->loadDLL("d3d12.dll", "d3d12.dll");
  1178. if (!d3d12DLL)
  1179. {
  1180. getDLLRegister()->releaseDLL("dxgi.dll");
  1181. return 0;
  1182. }
  1183. CreateDXGIFactory2Function createFactory
  1184. = (CreateDXGIFactory2Function)GetProcAddress(
  1185. dxgiDLL, "CreateDXGIFactory2");
  1186. if (!createFactory)
  1187. {
  1188. getDLLRegister()->releaseDLL("dxgi.dll");
  1189. getDLLRegister()->releaseDLL("d3d12.dll");
  1190. return 0;
  1191. }
  1192. D3D12CreateDeviceFunction createDevice
  1193. = (D3D12CreateDeviceFunction)GetProcAddress(
  1194. d3d12DLL, "D3D12CreateDevice");
  1195. if (!createDevice)
  1196. {
  1197. getDLLRegister()->releaseDLL("dxgi.dll");
  1198. getDLLRegister()->releaseDLL("d3d12.dll");
  1199. return 0;
  1200. }
  1201. #ifdef _DEBUG
  1202. D3D12GetDebugInterfaceFunction getDebugInterface
  1203. = (D3D12GetDebugInterfaceFunction)GetProcAddress(
  1204. d3d12DLL, "D3D12GetDebugInterface");
  1205. ID3D12Debug* debug = 0;
  1206. getDebugInterface(__uuidof(ID3D12Debug), (void**)&debug);
  1207. debug->EnableDebugLayer();
  1208. #endif
  1209. IDXGIFactory4* factory;
  1210. UINT createFactoryFlags = 0;
  1211. #ifdef _DEBUG
  1212. createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  1213. #endif
  1214. HRESULT res = createFactory(
  1215. createFactoryFlags, __uuidof(IDXGIFactory4), (void**)&factory);
  1216. if (FAILED(res))
  1217. {
  1218. getDLLRegister()->releaseDLL("dxgi.dll");
  1219. getDLLRegister()->releaseDLL("d3d12.dll");
  1220. return 0;
  1221. }
  1222. int index = 0;
  1223. do
  1224. {
  1225. IDXGIAdapter1* current;
  1226. res = factory->EnumAdapters1(index++, &current);
  1227. if (res == S_OK)
  1228. {
  1229. DXGI_ADAPTER_DESC1 dxgiAdapterDesc1;
  1230. current->GetDesc1(&dxgiAdapterDesc1);
  1231. ID3D12Device5* device = 0;
  1232. if ((dxgiAdapterDesc1.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0
  1233. && SUCCEEDED(createDevice(current,
  1234. D3D_FEATURE_LEVEL_12_1,
  1235. __uuidof(ID3D12Device5),
  1236. (void**)&device)))
  1237. {
  1238. device->Release();
  1239. current->Release();
  1240. factory->Release();
  1241. #ifdef _DEBUG
  1242. debug->Release();
  1243. #endif
  1244. getDLLRegister()->releaseDLL("dxgi.dll");
  1245. getDLLRegister()->releaseDLL("d3d12.dll");
  1246. return 1;
  1247. }
  1248. current->Release();
  1249. }
  1250. } while (res != DXGI_ERROR_NOT_FOUND);
  1251. factory->Release();
  1252. getDLLRegister()->releaseDLL("dxgi.dll");
  1253. getDLLRegister()->releaseDLL("d3d12.dll");
  1254. return 0;
  1255. }
  1256. bool Framework::DirectX12::renderGuiBefore3D() const
  1257. {
  1258. return true;
  1259. }