DX12GraphicsApi.cpp 44 KB

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