DX12GraphicsApi.cpp 45 KB

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