DX12GraphicsApi.cpp 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340
  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, tlas);
  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(
  502. Cam3D* zKam, DX12TLAS* zTLAS, int startIndex)
  503. {
  504. ID3D12DescriptorHeap* heaps[]
  505. = {pipeline->zGlobalSignature()->doesUseTextureDescriptorHeap()
  506. ? textureDescriptorHeap->zDescriptorHeap()
  507. : globalDescriptorHeap->zDescriptorHeap(),
  508. samplerDescriptorHeap->zDescriptorHeap()};
  509. directCommandQueue->zCommandList()->SetDescriptorHeaps(2, heaps);
  510. if (pipeline->zGlobalSignature()->gerShaderBindingTableParamCount()
  511. + pipeline->zGlobalSignature()
  512. ->getDescriptorHeapBindings()
  513. .getEntryCount()
  514. > startIndex)
  515. {
  516. if (startIndex == 0)
  517. {
  518. directCommandQueue->zCommandList()->SetComputeRootSignature(
  519. pipeline->zGlobalSignature()->zSignature());
  520. }
  521. if (pipeline->zGlobalSignature()->doesUseGlobalDescriptorHeap())
  522. {
  523. directCommandQueue->zCommandList()->SetComputeRootDescriptorTable(
  524. startIndex++,
  525. globalDescriptorHeap->zDescriptorHeap()
  526. ->GetGPUDescriptorHandleForHeapStart());
  527. }
  528. if (pipeline->zGlobalSignature()->doesUseTextureDescriptorHeap())
  529. {
  530. directCommandQueue->zCommandList()->SetComputeRootDescriptorTable(
  531. startIndex++,
  532. textureDescriptorHeap->zDescriptorHeap()
  533. ->GetGPUDescriptorHandleForHeapStart());
  534. }
  535. if (pipeline->zGlobalSignature()->doesUseSamplerDescriptorHeap())
  536. {
  537. directCommandQueue->zCommandList()->SetComputeRootDescriptorTable(
  538. startIndex++,
  539. samplerDescriptorHeap->zDescriptorHeap()
  540. ->GetGPUDescriptorHandleForHeapStart());
  541. }
  542. }
  543. return startIndex;
  544. }
  545. typedef HRESULT(__stdcall* CreateDXGIFactory2Function)(UINT, REFIID, void**);
  546. typedef HRESULT(__stdcall* D3D12CreateDeviceFunction)(
  547. IDXGIAdapter*, D3D_FEATURE_LEVEL, REFIID, void**);
  548. typedef HRESULT(__stdcall* D3D12GetDebugInterfaceFunction)(REFIID, void**);
  549. typedef HRESULT(__stdcall* DXGIGetDebugInterface1Function)(
  550. UINT Flags, REFIID riid, _COM_Outptr_ void** pDebug);
  551. void DirectX12::initialize(
  552. NativeWindow* fenster, Vec2<int> backBufferSize, bool fullScreen)
  553. {
  554. GraphicsApi::initialize(fenster, backBufferSize, fullScreen);
  555. #ifdef _DEBUG
  556. if (debugDX)
  557. {
  558. HINSTANCE pixDebugger = getDLLRegister()->loadDLL(
  559. "WinPixGpuCapturer.dll",
  560. "C:\\Program Files\\Microsoft PIX\\2603.25\\WinPixGpuCapturer.dll");
  561. }
  562. #endif
  563. HINSTANCE dxgiDLL = getDLLRegister()->loadDLL("dxgi.dll", "dxgi.dll");
  564. if (!dxgiDLL)
  565. {
  566. WMessageBox(fenster->getWindowHandle(),
  567. new Text("Fehler"),
  568. new Text("dxgi.dll konnte nicht gefunden werden."),
  569. MB_ICONERROR);
  570. return;
  571. }
  572. HINSTANCE d3d12DLL = getDLLRegister()->loadDLL("d3d12.dll", "d3d12.dll");
  573. if (!d3d12DLL)
  574. {
  575. getDLLRegister()->releaseDLL("dxgi.dll");
  576. WMessageBox(fenster->getWindowHandle(),
  577. new Text("Fehler"),
  578. new Text("DirectX 12 konnte nicht gefunden werden."),
  579. MB_ICONERROR);
  580. return;
  581. }
  582. pfnD3D12SerializeRootSignature
  583. = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(
  584. d3d12DLL, "D3D12SerializeRootSignature");
  585. if (!pfnD3D12SerializeRootSignature)
  586. {
  587. getDLLRegister()->releaseDLL("dxgi.dll");
  588. getDLLRegister()->releaseDLL("d3d12.dll");
  589. WMessageBox(fenster->getWindowHandle(),
  590. new Text("Fehler"),
  591. new Text(
  592. "Der Einstiegspunkt D3D12SerializeRootSignature fon d3d12.dll "
  593. "konnte nicht gefunden werden."),
  594. MB_ICONERROR);
  595. return;
  596. }
  597. // CreateDXGIFactory2
  598. CreateDXGIFactory2Function createFactory
  599. = (CreateDXGIFactory2Function)GetProcAddress(
  600. dxgiDLL, "CreateDXGIFactory2");
  601. if (!createFactory)
  602. {
  603. getDLLRegister()->releaseDLL("dxgi.dll");
  604. getDLLRegister()->releaseDLL("d3d12.dll");
  605. WMessageBox(fenster->getWindowHandle(),
  606. new Text("Fehler"),
  607. new Text(
  608. "Der Einstiegspunkt CreateDXGIFactory2 fon dxgi.dll konnte "
  609. "nicht gefunden werden."),
  610. MB_ICONERROR);
  611. return;
  612. }
  613. // D3D12CreateDevice
  614. D3D12CreateDeviceFunction createDevice
  615. = (D3D12CreateDeviceFunction)GetProcAddress(
  616. d3d12DLL, "D3D12CreateDevice");
  617. if (!createDevice)
  618. {
  619. getDLLRegister()->releaseDLL("dxgi.dll");
  620. getDLLRegister()->releaseDLL("d3d12.dll");
  621. WMessageBox(fenster->getWindowHandle(),
  622. new Text("Fehler"),
  623. new Text("Der Einstiegspunkt D3D12CreateDevice fon DirectX 12 "
  624. "konnte nicht gefunden werden."),
  625. MB_ICONERROR);
  626. return;
  627. }
  628. // D3D12SerializeVersionedRootSignature
  629. PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE d3d12svrsf
  630. = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)GetProcAddress(
  631. d3d12DLL, "D3D12SerializeVersionedRootSignature");
  632. // D3D12SerializeRootSignature
  633. PFN_D3D12_SERIALIZE_ROOT_SIGNATURE d3d12srsf
  634. = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(
  635. d3d12DLL, "D3D12SerializeRootSignature");
  636. bool debugDXGI = 0;
  637. #ifdef _DEBUG
  638. IDXGIInfoQueue* dxgiInfoQueue;
  639. if (debugDX)
  640. {
  641. // D3D12GetDebugInterface
  642. D3D12GetDebugInterfaceFunction getDebugInterface
  643. = (D3D12GetDebugInterfaceFunction)GetProcAddress(
  644. d3d12DLL, "D3D12GetDebugInterface");
  645. if (SUCCEEDED(getDebugInterface(__uuidof(ID3D12Debug), (void**)&debug)))
  646. debug->EnableDebugLayer();
  647. // DXGIGetDebugInterface1
  648. DXGIGetDebugInterface1Function dxgiDebugInterface
  649. = (DXGIGetDebugInterface1Function)GetProcAddress(
  650. dxgiDLL, "DXGIGetDebugInterface1");
  651. if (SUCCEEDED(dxgiDebugInterface(
  652. 0, __uuidof(IDXGIInfoQueue), (void**)&dxgiInfoQueue)))
  653. debugDXGI = 1;
  654. }
  655. #endif
  656. IDXGIFactory6* factory;
  657. UINT createFactoryFlags = 0;
  658. #if defined(_DEBUG)
  659. if (debugDX && debugDXGI) createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  660. #endif
  661. HRESULT res = createFactory(
  662. createFactoryFlags, __uuidof(IDXGIFactory6), (void**)&factory);
  663. if (FAILED(res))
  664. {
  665. getDLLRegister()->releaseDLL("dxgi.dll");
  666. getDLLRegister()->releaseDLL("d3d12.dll");
  667. Logging::error() << "ERROR DXGI: createFactory returned " << res
  668. << "\n";
  669. WMessageBox(fenster->getWindowHandle(),
  670. new Text("Fehler"),
  671. new Text("createFactory ist Fehlgeschlagen."),
  672. MB_ICONERROR);
  673. return;
  674. }
  675. IDXGIAdapter1* adapter = 0;
  676. for (UINT adapterID = 0; DXGI_ERROR_NOT_FOUND
  677. != factory->EnumAdapterByGpuPreference(adapterID,
  678. DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
  679. __uuidof(IDXGIAdapter1),
  680. (void**)&adapter);
  681. ++adapterID)
  682. {
  683. DXGI_ADAPTER_DESC1 desc;
  684. adapter->GetDesc1(&desc);
  685. if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
  686. {
  687. adapter->Release();
  688. // Don't select the Basic Render Driver adapter.
  689. continue;
  690. }
  691. // Check to see if the adapter supports Direct3D 12, but don't create
  692. // the actual device yet.
  693. if (SUCCEEDED(createDevice(adapter,
  694. D3D_FEATURE_LEVEL_12_1,
  695. _uuidof(ID3D12Device),
  696. nullptr)))
  697. {
  698. char buff[256] = {};
  699. printf_s(buff,
  700. L"Direct3D Adapter (%u): VID:%04X, PID:%04X - %ls\n",
  701. adapterID,
  702. desc.VendorId,
  703. desc.DeviceId,
  704. desc.Description);
  705. Logging::info() << buff;
  706. break;
  707. }
  708. adapter->Release();
  709. }
  710. if (!adapter)
  711. {
  712. if (FAILED(factory->EnumWarpAdapter(
  713. _uuidof(IDXGIAdapter1), (void**)&adapter)))
  714. Logging::error()
  715. << "ERROR: WARP12 not available. Enable the 'Graphics "
  716. "Tools' optional feature";
  717. }
  718. if (!adapter)
  719. {
  720. factory->Release();
  721. getDLLRegister()->releaseDLL("dxgi.dll");
  722. getDLLRegister()->releaseDLL("d3d12.dll");
  723. WMessageBox(fenster->getWindowHandle(),
  724. new Text("Fehler"),
  725. new Text("Es wurde keine passende Grafigkarte gefunden."),
  726. MB_ICONERROR);
  727. return;
  728. }
  729. res = createDevice(adapter,
  730. D3D_FEATURE_LEVEL_12_1,
  731. __uuidof(ID3D12Device5),
  732. (void**)&device);
  733. adapter->Release();
  734. if (FAILED(res))
  735. {
  736. factory->Release();
  737. getDLLRegister()->releaseDLL("dxgi.dll");
  738. getDLLRegister()->releaseDLL("d3d12.dll");
  739. Logging::error() << "ERROR: createDevice returned " << res << "\n";
  740. WMessageBox(fenster->getWindowHandle(),
  741. new Text("Fehler"),
  742. new Text("createDevice ist Fehlgeschlagen."),
  743. MB_ICONERROR);
  744. return;
  745. }
  746. D3D12_FEATURE_DATA_D3D12_OPTIONS5 featureSupportData = {};
  747. device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5,
  748. &featureSupportData,
  749. sizeof(featureSupportData));
  750. if (featureSupportData.RaytracingTier < D3D12_RAYTRACING_TIER_1_0)
  751. {
  752. device->Release();
  753. factory->Release();
  754. getDLLRegister()->releaseDLL("dxgi.dll");
  755. getDLLRegister()->releaseDLL("d3d12.dll");
  756. Logging::error() << "ERROR: Raytracing is not available\n";
  757. WMessageBox(fenster->getWindowHandle(),
  758. new Text("Fehler"),
  759. new Text("Raytracing ist nicht verfügbar. DirectX12 kann nicht "
  760. "verwendet werden."),
  761. MB_ICONERROR);
  762. return;
  763. }
  764. res = device->QueryInterface(__uuidof(ID3D12InfoQueue), (void**)&infoQueue);
  765. if (SUCCEEDED(res))
  766. {
  767. if (debugDX)
  768. {
  769. infoQueue->SetBreakOnSeverity(
  770. D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
  771. infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
  772. infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, TRUE);
  773. }
  774. // Suppress individual messages by their ID
  775. D3D12_MESSAGE_ID DenyIds[] = {
  776. // D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE, //
  777. // I'm really not sure how to avoid this message.
  778. D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE, // This warning occurs when
  779. // using capture frame while
  780. // graphics debugging.
  781. D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE, // This warning occurs
  782. // when using capture
  783. // frame while graphics
  784. // debugging.
  785. };
  786. D3D12_INFO_QUEUE_FILTER NewFilter = {};
  787. NewFilter.DenyList.NumSeverities = 0; //_countof( Severities );
  788. NewFilter.DenyList.pSeverityList = 0; // Severities;
  789. NewFilter.DenyList.NumIDs = _countof(DenyIds);
  790. NewFilter.DenyList.pIDList = DenyIds;
  791. infoQueue->PushStorageFilter(&NewFilter);
  792. }
  793. directCommandQueue = new DX12DirectCommandQueue(device);
  794. settings.minDistance = 0.0f;
  795. settings.maxDistance = 100000.f;
  796. settings.renderGui = 0;
  797. settings.useRays = 0;
  798. rayGenSettingsBuffer = new DX12Buffer(1,
  799. device,
  800. dynamic_cast<DX12CommandQueue*>(directCommandQueue->getThis()),
  801. D3D12_RESOURCE_FLAG_NONE);
  802. rayGenSettingsBuffer->setLength(
  803. ROUND_UP_POWER_OF_2(sizeof(RayGenerationSettings), 256));
  804. rayGenSettingsBuffer->setData(&settings, 1);
  805. rayGenSettingsBuffer->copyToGPU(sizeof(RayGenerationSettings));
  806. IDXGIFactory5* fac5 = 0;
  807. factory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&fac5);
  808. if (fac5)
  809. {
  810. res = fac5->CheckFeatureSupport(
  811. DXGI_FEATURE_PRESENT_ALLOW_TEARING, &tearing, sizeof(tearing));
  812. if (FAILED(res)) tearing = 0;
  813. fac5->Release();
  814. }
  815. DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
  816. swapChainDesc.Width = backBufferSize.x;
  817. swapChainDesc.Height = backBufferSize.y;
  818. swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
  819. swapChainDesc.Stereo = FALSE;
  820. swapChainDesc.SampleDesc = {1, 0};
  821. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  822. swapChainDesc.BufferCount = 2;
  823. swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
  824. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
  825. swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
  826. swapChainDesc.Flags = tearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
  827. IDXGISwapChain1* tmpSwapChain;
  828. res = factory->CreateSwapChainForHwnd(directCommandQueue->zQueue(),
  829. fenster->getWindowHandle(),
  830. &swapChainDesc,
  831. 0,
  832. 0,
  833. &tmpSwapChain);
  834. if (FAILED(res))
  835. {
  836. factory->Release();
  837. Logging::error() << "ERROR: CreateSwapChainForHwnd returned " << res
  838. << "\n";
  839. WMessageBox(fenster->getWindowHandle(),
  840. new Text("Fehler"),
  841. new Text("CreateSwapChainForHwnd ist Fehlgeschlagen."),
  842. MB_ICONERROR);
  843. return;
  844. }
  845. res = tmpSwapChain->QueryInterface(
  846. __uuidof(IDXGISwapChain4), (void**)&swapChain);
  847. tmpSwapChain->Release();
  848. if (FAILED(res))
  849. {
  850. factory->Release();
  851. Logging::error() << "ERROR: QueryInterface returned " << res << "\n";
  852. WMessageBox(fenster->getWindowHandle(),
  853. new Text("Fehler"),
  854. new Text("QueryInterface ist Fehlgeschlagen."),
  855. MB_ICONERROR);
  856. return;
  857. }
  858. factory->MakeWindowAssociation(
  859. fenster->getWindowHandle(), DXGI_MWA_NO_ALT_ENTER);
  860. for (int i = 0; i < 2; i++)
  861. {
  862. ID3D12Resource* backBuffer;
  863. res = swapChain->GetBuffer(
  864. i, __uuidof(ID3D12Resource), (void**)&backBuffer);
  865. if (FAILED(res))
  866. {
  867. factory->Release();
  868. Logging::error() << "ERROR: GetBuffer returned " << res << "\n";
  869. WMessageBox(fenster->getWindowHandle(),
  870. new Text("Fehler"),
  871. new Text("GetBuffer ist Fehlgeschlagen."),
  872. MB_ICONERROR);
  873. return;
  874. }
  875. this->backBuffer[i] = backBuffer;
  876. }
  877. Image* renderTargetImage = new Image();
  878. renderTargetImage->newImage(backBufferSize.x, backBufferSize.y, 0);
  879. defaultRenderTarget = dynamic_cast<DX12Texture*>(
  880. createOrGetTexture("_f_RenderTarget", renderTargetImage, GPU_TO_RAM));
  881. defaultRenderTarget->updateTextur();
  882. Image* renderB = new Image(1);
  883. renderB->setAlpha3D(1);
  884. renderB->newImage(this->backBufferSize.x, this->backBufferSize.y, 0);
  885. uiTexture = createOrGetTexture("_f_Render_Image", renderB, RAM_TO_GPU);
  886. D3D12_FEATURE_DATA_ROOT_SIGNATURE featureData = {};
  887. featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1;
  888. if (FAILED(device->CheckFeatureSupport(
  889. D3D12_FEATURE_ROOT_SIGNATURE, &featureData, sizeof(featureData))))
  890. featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0;
  891. D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags
  892. = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT
  893. | D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS
  894. | D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS
  895. | D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS;
  896. D3D12_DESCRIPTOR_RANGE1 range[2];
  897. range[0].NumDescriptors = 5;
  898. range[0].BaseShaderRegister = 0;
  899. range[0].RegisterSpace = 0;
  900. range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
  901. range[0].OffsetInDescriptorsFromTableStart
  902. = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
  903. range[0].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
  904. range[1].NumDescriptors = 1;
  905. range[1].BaseShaderRegister = 0;
  906. range[1].RegisterSpace = 0;
  907. range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
  908. range[1].OffsetInDescriptorsFromTableStart
  909. = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
  910. range[1].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
  911. D3D12_ROOT_PARAMETER1 rootParameters[1];
  912. rootParameters[0].ParameterType
  913. = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
  914. rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
  915. rootParameters[0].DescriptorTable.NumDescriptorRanges = 2;
  916. rootParameters[0].DescriptorTable.pDescriptorRanges = range;
  917. D3D12_STATIC_SAMPLER_DESC sampler = {};
  918. sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
  919. sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
  920. sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
  921. sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
  922. sampler.MipLODBias = 0;
  923. sampler.MaxAnisotropy = 0;
  924. sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
  925. sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
  926. sampler.MinLOD = 0.0f;
  927. sampler.MaxLOD = D3D12_FLOAT32_MAX;
  928. sampler.ShaderRegister = 0;
  929. sampler.RegisterSpace = 0;
  930. sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
  931. D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDescription;
  932. rootSignatureDescription.Version = D3D_ROOT_SIGNATURE_VERSION_1_1;
  933. rootSignatureDescription.Desc_1_1.NumParameters = 1;
  934. rootSignatureDescription.Desc_1_1.pParameters = rootParameters;
  935. rootSignatureDescription.Desc_1_1.NumStaticSamplers = 1;
  936. rootSignatureDescription.Desc_1_1.pStaticSamplers = &sampler;
  937. rootSignatureDescription.Desc_1_1.Flags = rootSignatureFlags;
  938. ID3DBlob* rootSignature;
  939. ID3DBlob* error;
  940. res = D3DX12SerializeVersionedRootSignature(&rootSignatureDescription,
  941. featureData.HighestVersion,
  942. &rootSignature,
  943. &error,
  944. d3d12svrsf,
  945. d3d12srsf);
  946. if (FAILED(res))
  947. {
  948. factory->Release();
  949. Logging::error()
  950. << "ERROR: D3DX12SerializeVersionedRootSignature returned " << res
  951. << "\n";
  952. WMessageBox(fenster->getWindowHandle(),
  953. new Text("Fehler"),
  954. new Text(
  955. "D3DX12SerializeVersionedRootSignature ist Fehlgeschlagen."),
  956. MB_ICONERROR);
  957. if (error) error->Release();
  958. return;
  959. }
  960. res = device->CreateRootSignature(0,
  961. rootSignature->GetBufferPointer(),
  962. rootSignature->GetBufferSize(),
  963. __uuidof(ID3D12RootSignature),
  964. (void**)&signature);
  965. if (FAILED(res))
  966. {
  967. factory->Release();
  968. Logging::error() << "ERROR: CreateRootSignature returned " << res
  969. << "\n";
  970. WMessageBox(fenster->getWindowHandle(),
  971. new Text("Fehler"),
  972. new Text("CreateRootSignature ist Fehlgeschlagen."),
  973. MB_ICONERROR);
  974. return;
  975. }
  976. rootSignature->Release();
  977. D3D12_RASTERIZER_DESC rdesc;
  978. rdesc.FillMode = D3D12_FILL_MODE_SOLID;
  979. rdesc.CullMode = D3D12_CULL_MODE_BACK;
  980. rdesc.FrontCounterClockwise = 0;
  981. rdesc.DepthBias = 0;
  982. rdesc.DepthBiasClamp = 0.f;
  983. rdesc.SlopeScaledDepthBias = 0.f;
  984. rdesc.DepthClipEnable = 1;
  985. rdesc.MultisampleEnable = 0;
  986. rdesc.AntialiasedLineEnable = 0;
  987. rdesc.ForcedSampleCount = 0;
  988. rdesc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
  989. uiTexture->updateTextur();
  990. directCommandQueue->execute();
  991. factory->Release();
  992. }
  993. void DirectX12::beginFrame(bool fill2D, bool fill3D, int fillColor)
  994. {
  995. cs.lock();
  996. cameraCount = 0;
  997. D3D12_RESOURCE_BARRIER barrier;
  998. ZeroMemory(&barrier, sizeof(barrier));
  999. barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  1000. barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  1001. barrier.Transition.pResource = this->backBuffer[backBufferIndex];
  1002. barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
  1003. barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
  1004. barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
  1005. directCommandQueue->zCommandList()->ResourceBarrier(1, &barrier);
  1006. if (fill2D) uiTexture->zImage()->setColor(fillColor);
  1007. CD3DX12_RESOURCE_BARRIER transition
  1008. = CD3DX12_RESOURCE_BARRIER::Transition(defaultRenderTarget->zResource(),
  1009. D3D12_RESOURCE_STATE_COPY_SOURCE,
  1010. D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
  1011. directCommandQueue->zCommandList()->ResourceBarrier(1, &transition);
  1012. }
  1013. void DirectX12::renderKamera(Cam3D* zKamera)
  1014. {
  1015. cameraCount++;
  1016. renderKamera(zKamera, defaultRenderTarget, true);
  1017. }
  1018. void Framework::DirectX12::renderKamera(Cam3D* zKamera, Texture* zTarget)
  1019. {
  1020. cameraCount++;
  1021. renderKamera(zKamera, dynamic_cast<DX12Texture*>(zTarget), false);
  1022. }
  1023. void DirectX12::presentFrame()
  1024. {
  1025. if (cameraCount == 0)
  1026. {
  1027. if (!defaultKamera)
  1028. {
  1029. defaultKamera = new Cam3D();
  1030. defaultKamera->setWorld(new World3D());
  1031. defaultKamera->setScreenSize(backBufferSize);
  1032. }
  1033. renderKamera(defaultKamera);
  1034. }
  1035. CD3DX12_RESOURCE_BARRIER transition
  1036. = CD3DX12_RESOURCE_BARRIER::Transition(defaultRenderTarget->zResource(),
  1037. D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
  1038. D3D12_RESOURCE_STATE_COPY_SOURCE);
  1039. directCommandQueue->zCommandList()->ResourceBarrier(1, &transition);
  1040. transition
  1041. = CD3DX12_RESOURCE_BARRIER::Transition(backBuffer[backBufferIndex],
  1042. D3D12_RESOURCE_STATE_RENDER_TARGET,
  1043. D3D12_RESOURCE_STATE_COPY_DEST);
  1044. directCommandQueue->zCommandList()->ResourceBarrier(1, &transition);
  1045. directCommandQueue->zCommandList()->CopyResource(
  1046. backBuffer[backBufferIndex], defaultRenderTarget->zResource());
  1047. transition
  1048. = CD3DX12_RESOURCE_BARRIER::Transition(backBuffer[backBufferIndex],
  1049. D3D12_RESOURCE_STATE_COPY_DEST,
  1050. D3D12_RESOURCE_STATE_RENDER_TARGET);
  1051. directCommandQueue->zCommandList()->ResourceBarrier(1, &transition);
  1052. // Indicate that the back buffer will now be used to present.
  1053. transition
  1054. = CD3DX12_RESOURCE_BARRIER::Transition(backBuffer[backBufferIndex],
  1055. D3D12_RESOURCE_STATE_RENDER_TARGET,
  1056. D3D12_RESOURCE_STATE_PRESENT);
  1057. directCommandQueue->zCommandList()->ResourceBarrier(1, &transition);
  1058. directCommandQueue->execute();
  1059. swapChain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
  1060. globalDescriptorHeap->setHeapChanged(0);
  1061. textureDescriptorHeap->setHeapChanged(0);
  1062. samplerDescriptorHeap->setHeapChanged(0);
  1063. backBufferIndex = swapChain->GetCurrentBackBufferIndex();
  1064. cs.unlock();
  1065. }
  1066. Texture* DirectX12::createOrGetTexture(
  1067. const char* name, Image* b, TextureDirection dir)
  1068. {
  1069. if (!device)
  1070. {
  1071. if (b) b->release();
  1072. return 0;
  1073. }
  1074. if (texturRegister->hasTexture(name))
  1075. {
  1076. Texture* ret = texturRegister->getTexture(name);
  1077. if (b) ret->setImageZ(b);
  1078. return ret;
  1079. }
  1080. cs.lock();
  1081. Texture* ret = new DX12Texture(device, directCommandQueue, dir);
  1082. if (b) ret->setImageZ(b);
  1083. texturRegister->addTexture(dynamic_cast<Texture*>(ret->getThis()), name);
  1084. ret->updateTextur();
  1085. if (textureDescriptorHeap)
  1086. {
  1087. textureDescriptorHeap->addTextureInput(
  1088. DX12_SHADER_REGISTER_T_SHADER_RESOURCE, ret);
  1089. textureDescriptorHeap->updateDescriptorHeap(device);
  1090. ret->setBufferChanged(0);
  1091. }
  1092. // directCommandQueue->execute();
  1093. cs.unlock();
  1094. return ret;
  1095. }
  1096. Image* DirectX12::zUIRenderImage() const
  1097. {
  1098. return uiTexture ? uiTexture->zImage() : 0;
  1099. }
  1100. DXBuffer* DirectX12::createStructuredBuffer(int eSize)
  1101. {
  1102. return new DX12Buffer(eSize,
  1103. device,
  1104. dynamic_cast<DX12CommandQueue*>(directCommandQueue->getThis()),
  1105. D3D12_RESOURCE_FLAG_NONE);
  1106. }
  1107. Model3DData* Framework::DirectX12::createModel(const char* name)
  1108. {
  1109. cs.lock();
  1110. Model3DData* result = GraphicsApi::createModel(name);
  1111. lastModelId = result->getId();
  1112. if (result)
  1113. {
  1114. DX12BLASModel** newBlasModels = new DX12BLASModel*[lastModelId + 1];
  1115. if (lastModelId > 0)
  1116. {
  1117. memcpy(newBlasModels,
  1118. blasModels,
  1119. sizeof(DX12BLASModel*) * lastModelId);
  1120. }
  1121. newBlasModels[lastModelId]
  1122. = new DX12BLASModel(result, device, directCommandQueue);
  1123. delete[] blasModels;
  1124. blasModels = newBlasModels;
  1125. }
  1126. cs.unlock();
  1127. return result;
  1128. }
  1129. void Framework::DirectX12::setPipeline(DX12Pipeline* pipeline)
  1130. {
  1131. if (this->pipeline)
  1132. {
  1133. this->pipeline->release();
  1134. }
  1135. this->pipeline = pipeline;
  1136. if (pipeline)
  1137. {
  1138. initializePipeline();
  1139. if (!globalDescriptorHeap
  1140. || globalDescriptorHeap->zPipeline() != pipeline)
  1141. {
  1142. if (globalDescriptorHeap)
  1143. {
  1144. globalDescriptorHeap->release();
  1145. }
  1146. globalDescriptorHeap
  1147. = pipeline->createGlobalDescriptorHeap(GLOBAL_DESCRIPTOR_HEAP);
  1148. initializeGlobalDescriptorHeap();
  1149. }
  1150. if (!textureDescriptorHeap
  1151. || textureDescriptorHeap->zPipeline() != pipeline)
  1152. {
  1153. if (textureDescriptorHeap)
  1154. {
  1155. textureDescriptorHeap->release();
  1156. }
  1157. textureDescriptorHeap
  1158. = pipeline->createGlobalDescriptorHeap(TEXTURE_DESCRIPTOR_HEAP);
  1159. initializeTextureDescriptorHeap();
  1160. }
  1161. if (!samplerDescriptorHeap
  1162. || samplerDescriptorHeap->zPipeline() != pipeline)
  1163. {
  1164. if (samplerDescriptorHeap)
  1165. {
  1166. samplerDescriptorHeap->release();
  1167. }
  1168. samplerDescriptorHeap
  1169. = pipeline->createGlobalDescriptorHeap(SAMPLER_DESCRIPTOR_HEAP);
  1170. initializeSamplerDescriptorHeap();
  1171. }
  1172. }
  1173. }
  1174. bool DirectX12::isAvailable()
  1175. {
  1176. HINSTANCE dxgiDLL = getDLLRegister()->loadDLL("dxgi.dll", "dxgi.dll");
  1177. if (!dxgiDLL) return 0;
  1178. HINSTANCE d3d12DLL = getDLLRegister()->loadDLL("d3d12.dll", "d3d12.dll");
  1179. if (!d3d12DLL)
  1180. {
  1181. getDLLRegister()->releaseDLL("dxgi.dll");
  1182. return 0;
  1183. }
  1184. CreateDXGIFactory2Function createFactory
  1185. = (CreateDXGIFactory2Function)GetProcAddress(
  1186. dxgiDLL, "CreateDXGIFactory2");
  1187. if (!createFactory)
  1188. {
  1189. getDLLRegister()->releaseDLL("dxgi.dll");
  1190. getDLLRegister()->releaseDLL("d3d12.dll");
  1191. return 0;
  1192. }
  1193. D3D12CreateDeviceFunction createDevice
  1194. = (D3D12CreateDeviceFunction)GetProcAddress(
  1195. d3d12DLL, "D3D12CreateDevice");
  1196. if (!createDevice)
  1197. {
  1198. getDLLRegister()->releaseDLL("dxgi.dll");
  1199. getDLLRegister()->releaseDLL("d3d12.dll");
  1200. return 0;
  1201. }
  1202. #ifdef _DEBUG
  1203. D3D12GetDebugInterfaceFunction getDebugInterface
  1204. = (D3D12GetDebugInterfaceFunction)GetProcAddress(
  1205. d3d12DLL, "D3D12GetDebugInterface");
  1206. ID3D12Debug* debug = 0;
  1207. getDebugInterface(__uuidof(ID3D12Debug), (void**)&debug);
  1208. debug->EnableDebugLayer();
  1209. #endif
  1210. IDXGIFactory4* factory;
  1211. UINT createFactoryFlags = 0;
  1212. #ifdef _DEBUG
  1213. createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  1214. #endif
  1215. HRESULT res = createFactory(
  1216. createFactoryFlags, __uuidof(IDXGIFactory4), (void**)&factory);
  1217. if (FAILED(res))
  1218. {
  1219. getDLLRegister()->releaseDLL("dxgi.dll");
  1220. getDLLRegister()->releaseDLL("d3d12.dll");
  1221. return 0;
  1222. }
  1223. int index = 0;
  1224. do
  1225. {
  1226. IDXGIAdapter1* current;
  1227. res = factory->EnumAdapters1(index++, &current);
  1228. if (res == S_OK)
  1229. {
  1230. DXGI_ADAPTER_DESC1 dxgiAdapterDesc1;
  1231. current->GetDesc1(&dxgiAdapterDesc1);
  1232. ID3D12Device5* device = 0;
  1233. if ((dxgiAdapterDesc1.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0
  1234. && SUCCEEDED(createDevice(current,
  1235. D3D_FEATURE_LEVEL_12_1,
  1236. __uuidof(ID3D12Device5),
  1237. (void**)&device)))
  1238. {
  1239. device->Release();
  1240. current->Release();
  1241. factory->Release();
  1242. #ifdef _DEBUG
  1243. debug->Release();
  1244. #endif
  1245. getDLLRegister()->releaseDLL("dxgi.dll");
  1246. getDLLRegister()->releaseDLL("d3d12.dll");
  1247. return 1;
  1248. }
  1249. current->Release();
  1250. }
  1251. } while (res != DXGI_ERROR_NOT_FOUND);
  1252. factory->Release();
  1253. getDLLRegister()->releaseDLL("dxgi.dll");
  1254. getDLLRegister()->releaseDLL("d3d12.dll");
  1255. return 0;
  1256. }
  1257. bool Framework::DirectX12::renderGuiBefore3D() const
  1258. {
  1259. return true;
  1260. }