DX12GraphicsApi.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  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 "DX12Shader.h"
  12. #include "DX12Texture.h"
  13. #include "DX12TLAS.h"
  14. #include "Globals.h"
  15. #include "Image.h"
  16. #include "Model3D.h"
  17. #include "Model3DList.h"
  18. #include "Screen.h"
  19. #include "TextureList.h"
  20. #include "TextureModel.h"
  21. #include "Window.h"
  22. #include "World3D.h"
  23. using namespace Framework;
  24. DirectX12::DirectX12()
  25. : GraphicsApi(DIRECTX12),
  26. debug(0),
  27. device(0),
  28. infoQueue(0),
  29. directCommandQueue(0),
  30. copyCommandQueue(0),
  31. computeCommandQueue(0),
  32. swapChain(0),
  33. rtvHeap(0),
  34. dsvHeap(0),
  35. depthBuffer(0),
  36. backBufferIndex(0),
  37. tearing(0),
  38. viewPort(0),
  39. allowedRenderArea(0),
  40. vertexBufferView(0),
  41. indexBufferView(0),
  42. signature(0),
  43. uiTexture(0),
  44. texturRegister(new TextureList()),
  45. blasModels(0),
  46. worldTLAS(0),
  47. worldShaderBindingTables(0),
  48. lastTLASId(-1),
  49. lastModelId(-1),
  50. defaultRenderTarget(0)
  51. {
  52. for (int i = 0; i < 2; i++)
  53. backBuffer[i] = 0;
  54. }
  55. DirectX12::~DirectX12()
  56. {
  57. if (blasModels)
  58. {
  59. for (int i = 0; i <= lastModelId; i++)
  60. {
  61. if (blasModels[i]) blasModels[i]->release();
  62. }
  63. delete[] blasModels;
  64. }
  65. if (worldTLAS)
  66. {
  67. for (int i = 0; i <= lastTLASId; i++)
  68. {
  69. if (worldTLAS[i]) worldTLAS[i]->release();
  70. }
  71. delete[] worldTLAS;
  72. }
  73. if (worldShaderBindingTables)
  74. {
  75. for (int i = 0; i <= lastTLASId; i++)
  76. {
  77. if (worldShaderBindingTables[i])
  78. worldShaderBindingTables[i]->release();
  79. }
  80. delete[] worldShaderBindingTables;
  81. }
  82. if (directCommandQueue)
  83. {
  84. directCommandQueue->flush();
  85. directCommandQueue->release();
  86. }
  87. if (copyCommandQueue)
  88. {
  89. copyCommandQueue->flush();
  90. copyCommandQueue->release();
  91. }
  92. if (computeCommandQueue)
  93. {
  94. computeCommandQueue->flush();
  95. computeCommandQueue->release();
  96. }
  97. if (depthBuffer) depthBuffer->Release();
  98. if (dsvHeap) dsvHeap->Release();
  99. texturRegister->release();
  100. if (uiTexture) uiTexture->release();
  101. if (defaultRenderTarget) defaultRenderTarget->release();
  102. if (signature) signature->Release();
  103. delete indexBufferView;
  104. delete vertexBufferView;
  105. delete allowedRenderArea;
  106. delete viewPort;
  107. for (int i = 0; i < 2; i++)
  108. {
  109. if (backBuffer[i]) backBuffer[i]->Release();
  110. }
  111. if (rtvHeap) rtvHeap->Release();
  112. if (swapChain) swapChain->Release();
  113. if (infoQueue) infoQueue->Release();
  114. if (device)
  115. {
  116. device->Release();
  117. getDLLRegister()->releaseDLL("dxgi.dll");
  118. getDLLRegister()->releaseDLL("d3d12.dll");
  119. }
  120. if (debug) debug->Release();
  121. }
  122. void DirectX12::updateBottomLevelAccelerationStructure()
  123. {
  124. bool updateRequired = 0;
  125. for (const Model3DData* model : *modelList->zModels())
  126. {
  127. if (model->wasIndexBufferChanged() || model->wasVertexBufferChanged())
  128. {
  129. updateRequired = true;
  130. break;
  131. }
  132. }
  133. int bufferCount = 0;
  134. if (updateRequired)
  135. {
  136. for (const Model3DData* model : *modelList->zModels())
  137. {
  138. int id = model->getId();
  139. blasModels[id]->calculateBuffers();
  140. bufferCount += blasModels[id]->getBufferCount();
  141. }
  142. directCommandQueue
  143. ->execute(); // TODO: check if this is realy necessary
  144. // here, because maybe the command list is
  145. // executed in the render function anyway
  146. }
  147. }
  148. void Framework::DirectX12::renderKamera(
  149. Cam3D* zKamera, DX12Texture* zTarget, bool guiVisible)
  150. {
  151. // TODO
  152. // directCommandQueue->getCommandList()->RSSetViewports(
  153. // 1, (D3D12_VIEWPORT*)zKamera->zViewPort());
  154. Mat4<float> identity = Mat4<float>::identity();
  155. World3D* w = zKamera->zWorld();
  156. if (w->getId() < 0)
  157. {
  158. w->setId(++lastTLASId);
  159. DX12TLAS** tmp = new DX12TLAS*[lastTLASId + 1];
  160. if (lastTLASId)
  161. {
  162. memcpy(tmp, worldTLAS, sizeof(DX12TLAS*) * lastTLASId);
  163. }
  164. tmp[lastTLASId] = new DX12TLAS(device, directCommandQueue);
  165. delete[] worldTLAS;
  166. worldTLAS = tmp;
  167. DX12ShaderBindingTable** tmpsbts
  168. = new DX12ShaderBindingTable*[lastTLASId + 1];
  169. if (lastTLASId)
  170. {
  171. memcpy(tmpsbts,
  172. worldShaderBindingTables,
  173. sizeof(DX12ShaderBindingTable*) * lastTLASId);
  174. }
  175. tmpsbts[lastTLASId] = pipeline->createShaderBindingTable();
  176. delete[] worldShaderBindingTables;
  177. worldShaderBindingTables = tmpsbts;
  178. }
  179. else if (worldShaderBindingTables[w->getId()]->zPipeline() != pipeline)
  180. {
  181. worldShaderBindingTables[w->getId()]->release();
  182. worldShaderBindingTables[w->getId()]
  183. = pipeline->createShaderBindingTable();
  184. }
  185. DX12TLAS* tlas = worldTLAS[w->getId()];
  186. DX12ShaderBindingTable* sbt = worldShaderBindingTables[w->getId()];
  187. tlas->startUpdate();
  188. sbt->startUpdate();
  189. int objectIndex = 0;
  190. int instanceIndex = 0;
  191. w->render(
  192. [this, &tlas, &objectIndex, &instanceIndex, &identity](Model3D* obj) {
  193. obj->calculateMatrices(identity, matrixBuffer);
  194. int modelId = obj->zModelData()->getId();
  195. DX12BLASModel* blasModel = blasModels[modelId];
  196. ArrayIterator<int> boneIds = blasModel->zBoneIds()->begin();
  197. for (const DX12BLAS* blas : *blasModel->zBLAS())
  198. {
  199. D3D12_RAYTRACING_INSTANCE_DESC* desc = tlas->nextInstanceDesc();
  200. desc->InstanceID = objectIndex;
  201. desc->InstanceContributionToHitGroupIndex = objectIndex;
  202. desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
  203. desc->InstanceMask = 0xFF;
  204. desc->AccelerationStructure
  205. = blas->zResultBuffer()->zBuffer()->GetGPUVirtualAddress();
  206. memcpy(desc->Transform,
  207. &matrixBuffer[boneIds.val()],
  208. sizeof(float) * 12);
  209. // TODO: sbt->setHitGroupShaderInputs(instanceIndex, ...)
  210. boneIds++;
  211. instanceIndex++;
  212. }
  213. objectIndex++;
  214. });
  215. tlas->endUpdate();
  216. // TODO: setup ray gen and miss params
  217. sbt->endUpdate(device);
  218. // TODO: call ray tracing
  219. }
  220. typedef HRESULT(__stdcall* CreateDXGIFactory2Function)(UINT, REFIID, void**);
  221. typedef HRESULT(__stdcall* D3D12CreateDeviceFunction)(
  222. IDXGIAdapter*, D3D_FEATURE_LEVEL, REFIID, void**);
  223. typedef HRESULT(__stdcall* D3D12GetDebugInterfaceFunction)(REFIID, void**);
  224. typedef HRESULT(__stdcall* DXGIGetDebugInterface1Function)(
  225. UINT Flags, REFIID riid, _COM_Outptr_ void** pDebug);
  226. void DirectX12::initialize(
  227. NativeWindow* fenster, Vec2<int> backBufferSize, bool fullScreen)
  228. {
  229. GraphicsApi::initialize(fenster, backBufferSize, fullScreen);
  230. HINSTANCE dxgiDLL = getDLLRegister()->loadDLL("dxgi.dll", "dxgi.dll");
  231. if (!dxgiDLL)
  232. {
  233. WMessageBox(fenster->getWindowHandle(),
  234. new Text("Fehler"),
  235. new Text("dxgi.dll konnte nicht gefunden werden."),
  236. MB_ICONERROR);
  237. return;
  238. }
  239. HINSTANCE d3d12DLL = getDLLRegister()->loadDLL("d3d12.dll", "d3d12.dll");
  240. if (!d3d12DLL)
  241. {
  242. getDLLRegister()->releaseDLL("dxgi.dll");
  243. WMessageBox(fenster->getWindowHandle(),
  244. new Text("Fehler"),
  245. new Text("DirectX 12 konnte nicht gefunden werden."),
  246. MB_ICONERROR);
  247. return;
  248. }
  249. // CreateDXGIFactory2
  250. CreateDXGIFactory2Function createFactory
  251. = (CreateDXGIFactory2Function)GetProcAddress(
  252. dxgiDLL, "CreateDXGIFactory2");
  253. if (!createFactory)
  254. {
  255. getDLLRegister()->releaseDLL("dxgi.dll");
  256. getDLLRegister()->releaseDLL("d3d12.dll");
  257. WMessageBox(fenster->getWindowHandle(),
  258. new Text("Fehler"),
  259. new Text(
  260. "Der Einstiegspunkt CreateDXGIFactory2 fon dxgi.dll konnte "
  261. "nicht gefunden werden."),
  262. MB_ICONERROR);
  263. return;
  264. }
  265. // D3D12CreateDevice
  266. D3D12CreateDeviceFunction createDevice
  267. = (D3D12CreateDeviceFunction)GetProcAddress(
  268. d3d12DLL, "D3D12CreateDevice");
  269. if (!createDevice)
  270. {
  271. getDLLRegister()->releaseDLL("dxgi.dll");
  272. getDLLRegister()->releaseDLL("d3d12.dll");
  273. WMessageBox(fenster->getWindowHandle(),
  274. new Text("Fehler"),
  275. new Text("Der Einstiegspunkt D3D12CreateDevice fon DirectX 12 "
  276. "konnte nicht gefunden werden."),
  277. MB_ICONERROR);
  278. return;
  279. }
  280. // D3D12SerializeVersionedRootSignature
  281. PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE d3d12svrsf
  282. = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)GetProcAddress(
  283. d3d12DLL, "D3D12SerializeVersionedRootSignature");
  284. // D3D12SerializeRootSignature
  285. PFN_D3D12_SERIALIZE_ROOT_SIGNATURE d3d12srsf
  286. = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(
  287. d3d12DLL, "D3D12SerializeRootSignature");
  288. bool debugDXGI = 0;
  289. #ifdef _DEBUG
  290. IDXGIInfoQueue* dxgiInfoQueue;
  291. if (debugDX)
  292. {
  293. // D3D12GetDebugInterface
  294. D3D12GetDebugInterfaceFunction getDebugInterface
  295. = (D3D12GetDebugInterfaceFunction)GetProcAddress(
  296. d3d12DLL, "D3D12GetDebugInterface");
  297. if (SUCCEEDED(getDebugInterface(__uuidof(ID3D12Debug), (void**)&debug)))
  298. debug->EnableDebugLayer();
  299. // DXGIGetDebugInterface1
  300. DXGIGetDebugInterface1Function dxgiDebugInterface
  301. = (DXGIGetDebugInterface1Function)GetProcAddress(
  302. dxgiDLL, "DXGIGetDebugInterface1");
  303. if (SUCCEEDED(dxgiDebugInterface(
  304. 0, __uuidof(IDXGIInfoQueue), (void**)&dxgiInfoQueue)))
  305. debugDXGI = 1;
  306. }
  307. #endif
  308. IDXGIFactory6* factory;
  309. UINT createFactoryFlags = 0;
  310. #if defined(_DEBUG)
  311. if (debugDX && debugDXGI) createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  312. #endif
  313. HRESULT res = createFactory(
  314. createFactoryFlags, __uuidof(IDXGIFactory6), (void**)&factory);
  315. if (FAILED(res))
  316. {
  317. getDLLRegister()->releaseDLL("dxgi.dll");
  318. getDLLRegister()->releaseDLL("d3d12.dll");
  319. Logging::error() << "ERROR DXGI: createFactory returned " << res
  320. << "\n";
  321. WMessageBox(fenster->getWindowHandle(),
  322. new Text("Fehler"),
  323. new Text("createFactory ist Fehlgeschlagen."),
  324. MB_ICONERROR);
  325. return;
  326. }
  327. IDXGIAdapter1* adapter = 0;
  328. for (UINT adapterID = 0; DXGI_ERROR_NOT_FOUND
  329. != factory->EnumAdapterByGpuPreference(adapterID,
  330. DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
  331. __uuidof(IDXGIAdapter1),
  332. (void**)&adapter);
  333. ++adapterID)
  334. {
  335. DXGI_ADAPTER_DESC1 desc;
  336. adapter->GetDesc1(&desc);
  337. if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
  338. {
  339. adapter->Release();
  340. // Don't select the Basic Render Driver adapter.
  341. continue;
  342. }
  343. // Check to see if the adapter supports Direct3D 12, but don't create
  344. // the actual device yet.
  345. if (SUCCEEDED(createDevice(adapter,
  346. D3D_FEATURE_LEVEL_12_1,
  347. _uuidof(ID3D12Device),
  348. nullptr)))
  349. {
  350. char buff[256] = {};
  351. printf_s(buff,
  352. L"Direct3D Adapter (%u): VID:%04X, PID:%04X - %ls\n",
  353. adapterID,
  354. desc.VendorId,
  355. desc.DeviceId,
  356. desc.Description);
  357. Logging::info() << buff;
  358. break;
  359. }
  360. adapter->Release();
  361. }
  362. if (!adapter)
  363. {
  364. if (FAILED(factory->EnumWarpAdapter(
  365. _uuidof(IDXGIAdapter1), (void**)&adapter)))
  366. Logging::error()
  367. << "ERROR: WARP12 not available. Enable the 'Graphics "
  368. "Tools' optional feature";
  369. }
  370. if (!adapter)
  371. {
  372. factory->Release();
  373. getDLLRegister()->releaseDLL("dxgi.dll");
  374. getDLLRegister()->releaseDLL("d3d12.dll");
  375. WMessageBox(fenster->getWindowHandle(),
  376. new Text("Fehler"),
  377. new Text("Es wurde keine passende Grafigkarte gefunden."),
  378. MB_ICONERROR);
  379. return;
  380. }
  381. res = createDevice(adapter,
  382. D3D_FEATURE_LEVEL_12_1,
  383. __uuidof(ID3D12Device5),
  384. (void**)&device);
  385. adapter->Release();
  386. if (FAILED(res))
  387. {
  388. factory->Release();
  389. getDLLRegister()->releaseDLL("dxgi.dll");
  390. getDLLRegister()->releaseDLL("d3d12.dll");
  391. Logging::error() << "ERROR: createDevice returned " << res << "\n";
  392. WMessageBox(fenster->getWindowHandle(),
  393. new Text("Fehler"),
  394. new Text("createDevice ist Fehlgeschlagen."),
  395. MB_ICONERROR);
  396. return;
  397. }
  398. D3D12_FEATURE_DATA_D3D12_OPTIONS5 featureSupportData = {};
  399. device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5,
  400. &featureSupportData,
  401. sizeof(featureSupportData));
  402. if (featureSupportData.RaytracingTier < D3D12_RAYTRACING_TIER_1_0)
  403. {
  404. device->Release();
  405. factory->Release();
  406. getDLLRegister()->releaseDLL("dxgi.dll");
  407. getDLLRegister()->releaseDLL("d3d12.dll");
  408. Logging::error() << "ERROR: Raytracing is not available\n";
  409. WMessageBox(fenster->getWindowHandle(),
  410. new Text("Fehler"),
  411. new Text("Raytracing ist nicht verfügbar. DirectX12 kann nicht "
  412. "verwendet werden."),
  413. MB_ICONERROR);
  414. return;
  415. }
  416. res = device->QueryInterface(__uuidof(ID3D12InfoQueue), (void**)&infoQueue);
  417. if (SUCCEEDED(res))
  418. {
  419. if (debugDX)
  420. {
  421. infoQueue->SetBreakOnSeverity(
  422. D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
  423. infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
  424. infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, TRUE);
  425. }
  426. // Suppress individual messages by their ID
  427. D3D12_MESSAGE_ID DenyIds[] = {
  428. // D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE, //
  429. // I'm really not sure how to avoid this message.
  430. D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE, // This warning occurs when
  431. // using capture frame while
  432. // graphics debugging.
  433. D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE, // This warning occurs
  434. // when using capture
  435. // frame while graphics
  436. // debugging.
  437. };
  438. D3D12_INFO_QUEUE_FILTER NewFilter = {};
  439. NewFilter.DenyList.NumSeverities = 0; //_countof( Severities );
  440. NewFilter.DenyList.pSeverityList = 0; // Severities;
  441. NewFilter.DenyList.NumIDs = _countof(DenyIds);
  442. NewFilter.DenyList.pIDList = DenyIds;
  443. infoQueue->PushStorageFilter(&NewFilter);
  444. }
  445. directCommandQueue = new DX12DirectCommandQueue(device);
  446. copyCommandQueue = new DX12CopyCommandQueue(device);
  447. computeCommandQueue = new DX12ComputeCommandQueue(device);
  448. IDXGIFactory5* fac5 = 0;
  449. factory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&fac5);
  450. if (fac5)
  451. {
  452. res = fac5->CheckFeatureSupport(
  453. DXGI_FEATURE_PRESENT_ALLOW_TEARING, &tearing, sizeof(tearing));
  454. if (FAILED(res)) tearing = 0;
  455. fac5->Release();
  456. }
  457. DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
  458. swapChainDesc.Width = backBufferSize.x;
  459. swapChainDesc.Height = backBufferSize.y;
  460. swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  461. swapChainDesc.Stereo = FALSE;
  462. swapChainDesc.SampleDesc = {1, 0};
  463. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  464. swapChainDesc.BufferCount = 2;
  465. swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
  466. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
  467. swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
  468. swapChainDesc.Flags = tearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
  469. IDXGISwapChain1* tmpSwapChain;
  470. res = factory->CreateSwapChainForHwnd(directCommandQueue->zQueue(),
  471. fenster->getWindowHandle(),
  472. &swapChainDesc,
  473. 0,
  474. 0,
  475. &tmpSwapChain);
  476. if (FAILED(res))
  477. {
  478. factory->Release();
  479. Logging::error() << "ERROR: CreateSwapChainForHwnd returned " << res
  480. << "\n";
  481. WMessageBox(fenster->getWindowHandle(),
  482. new Text("Fehler"),
  483. new Text("CreateSwapChainForHwnd ist Fehlgeschlagen."),
  484. MB_ICONERROR);
  485. return;
  486. }
  487. res = tmpSwapChain->QueryInterface(
  488. __uuidof(IDXGISwapChain4), (void**)&swapChain);
  489. tmpSwapChain->Release();
  490. if (FAILED(res))
  491. {
  492. factory->Release();
  493. Logging::error() << "ERROR: QueryInterface returned " << res << "\n";
  494. WMessageBox(fenster->getWindowHandle(),
  495. new Text("Fehler"),
  496. new Text("QueryInterface ist Fehlgeschlagen."),
  497. MB_ICONERROR);
  498. return;
  499. }
  500. factory->MakeWindowAssociation(
  501. fenster->getWindowHandle(), DXGI_MWA_NO_ALT_ENTER);
  502. D3D12_DESCRIPTOR_HEAP_DESC rtvhdesc = {};
  503. rtvhdesc.NumDescriptors = 2; // back buffer count
  504. rtvhdesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
  505. rtvhdesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
  506. res = device->CreateDescriptorHeap(
  507. &rtvhdesc, __uuidof(ID3D12DescriptorHeap), (void**)&rtvHeap);
  508. if (FAILED(res))
  509. {
  510. factory->Release();
  511. Logging::error() << "ERROR: CreateDescriptorHeap returned " << res
  512. << "\n";
  513. WMessageBox(fenster->getWindowHandle(),
  514. new Text("Fehler"),
  515. new Text("CreateDescriptorHeap ist Fehlgeschlagen."),
  516. MB_ICONERROR);
  517. return;
  518. }
  519. auto rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(
  520. D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
  521. D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle(
  522. rtvHeap->GetCPUDescriptorHandleForHeapStart());
  523. for (int i = 0; i < 2; i++)
  524. {
  525. ID3D12Resource* backBuffer;
  526. res = swapChain->GetBuffer(
  527. i, __uuidof(ID3D12Resource), (void**)&backBuffer);
  528. if (FAILED(res))
  529. {
  530. factory->Release();
  531. Logging::error() << "ERROR: GetBuffer returned " << res << "\n";
  532. WMessageBox(fenster->getWindowHandle(),
  533. new Text("Fehler"),
  534. new Text("GetBuffer ist Fehlgeschlagen."),
  535. MB_ICONERROR);
  536. return;
  537. }
  538. device->CreateRenderTargetView(backBuffer, nullptr, rtvHandle);
  539. this->backBuffer[i] = backBuffer;
  540. rtvHandle.ptr += rtvDescriptorSize;
  541. }
  542. Image* renderTargetImage = new Image();
  543. renderTargetImage->newImage(backBufferSize.x, backBufferSize.y, 0);
  544. defaultRenderTarget = dynamic_cast<DX12Texture*>(
  545. createOrGetTexture("_f_RenderTarget", renderTargetImage, GPU_TO_RAM));
  546. viewPort = new D3D12_VIEWPORT();
  547. viewPort->Width = (float)this->backBufferSize.x;
  548. viewPort->Height = (float)this->backBufferSize.y;
  549. viewPort->MinDepth = 0.0f;
  550. viewPort->MaxDepth = 1.0f;
  551. viewPort->TopLeftX = 0.0f;
  552. viewPort->TopLeftY = 0.0f;
  553. allowedRenderArea = new D3D12_RECT();
  554. allowedRenderArea->left = 0;
  555. allowedRenderArea->top = 0;
  556. allowedRenderArea->right = LONG_MAX;
  557. allowedRenderArea->bottom = LONG_MAX;
  558. Image* renderB = new Image(1);
  559. renderB->setAlpha3D(1);
  560. renderB->newImage(this->backBufferSize.x, this->backBufferSize.y, 0);
  561. uiTexture = createOrGetTexture("_f_Render_Image", renderB, RAM_TO_GPU);
  562. vertexBufferView = new D3D12_VERTEX_BUFFER_VIEW();
  563. vertexBufferView->StrideInBytes = sizeof(Vertex3D);
  564. indexBufferView = new D3D12_INDEX_BUFFER_VIEW();
  565. indexBufferView->Format = DXGI_FORMAT_R32_UINT;
  566. D3D12_CLEAR_VALUE optimizedClearValue = {};
  567. optimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
  568. optimizedClearValue.DepthStencil = {1.0f, 0};
  569. CD3DX12_HEAP_PROPERTIES heapProp
  570. = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
  571. CD3DX12_RESOURCE_DESC heapDesc
  572. = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D32_FLOAT,
  573. this->backBufferSize.x,
  574. this->backBufferSize.y,
  575. 1,
  576. 0,
  577. 1,
  578. 0,
  579. D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
  580. res = device->CreateCommittedResource(&heapProp,
  581. D3D12_HEAP_FLAG_NONE,
  582. &heapDesc,
  583. D3D12_RESOURCE_STATE_DEPTH_WRITE,
  584. &optimizedClearValue,
  585. __uuidof(ID3D12Resource),
  586. (void**)&depthBuffer);
  587. if (FAILED(res))
  588. {
  589. factory->Release();
  590. Logging::error() << "ERROR: CreateCommittedResource returned " << res
  591. << "\n";
  592. WMessageBox(fenster->getWindowHandle(),
  593. new Text("Fehler"),
  594. new Text("CreateCommittedResource ist Fehlgeschlagen."),
  595. MB_ICONERROR);
  596. return;
  597. }
  598. D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
  599. dsvHeapDesc.NumDescriptors = 1;
  600. dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
  601. dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
  602. res = device->CreateDescriptorHeap(
  603. &dsvHeapDesc, __uuidof(ID3D12DescriptorHeap), (void**)&dsvHeap);
  604. if (FAILED(res))
  605. {
  606. factory->Release();
  607. Logging::error() << "ERROR: CreateDescriptorHeap returned " << res
  608. << "\n";
  609. WMessageBox(fenster->getWindowHandle(),
  610. new Text("Fehler"),
  611. new Text("CreateDescriptorHeap ist Fehlgeschlagen."),
  612. MB_ICONERROR);
  613. return;
  614. }
  615. D3D12_DEPTH_STENCIL_VIEW_DESC dsv = {};
  616. dsv.Format = DXGI_FORMAT_D32_FLOAT;
  617. dsv.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
  618. dsv.Texture2D.MipSlice = 0;
  619. dsv.Flags = D3D12_DSV_FLAG_NONE;
  620. device->CreateDepthStencilView(
  621. depthBuffer, &dsv, dsvHeap->GetCPUDescriptorHandleForHeapStart());
  622. D3D12_FEATURE_DATA_ROOT_SIGNATURE featureData = {};
  623. featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1;
  624. if (FAILED(device->CheckFeatureSupport(
  625. D3D12_FEATURE_ROOT_SIGNATURE, &featureData, sizeof(featureData))))
  626. featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0;
  627. D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags
  628. = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT
  629. | D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS
  630. | D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS
  631. | D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS;
  632. D3D12_DESCRIPTOR_RANGE1 range[2];
  633. range[0].NumDescriptors = 5;
  634. range[0].BaseShaderRegister = 0;
  635. range[0].RegisterSpace = 0;
  636. range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
  637. range[0].OffsetInDescriptorsFromTableStart
  638. = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
  639. range[0].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
  640. range[1].NumDescriptors = 1;
  641. range[1].BaseShaderRegister = 0;
  642. range[1].RegisterSpace = 0;
  643. range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
  644. range[1].OffsetInDescriptorsFromTableStart
  645. = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
  646. range[1].Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
  647. D3D12_ROOT_PARAMETER1 rootParameters[1];
  648. rootParameters[0].ParameterType
  649. = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
  650. rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
  651. rootParameters[0].DescriptorTable.NumDescriptorRanges = 2;
  652. rootParameters[0].DescriptorTable.pDescriptorRanges = range;
  653. D3D12_STATIC_SAMPLER_DESC sampler = {};
  654. sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
  655. sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
  656. sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
  657. sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
  658. sampler.MipLODBias = 0;
  659. sampler.MaxAnisotropy = 0;
  660. sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
  661. sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
  662. sampler.MinLOD = 0.0f;
  663. sampler.MaxLOD = D3D12_FLOAT32_MAX;
  664. sampler.ShaderRegister = 0;
  665. sampler.RegisterSpace = 0;
  666. sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
  667. D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDescription;
  668. rootSignatureDescription.Version = D3D_ROOT_SIGNATURE_VERSION_1_1;
  669. rootSignatureDescription.Desc_1_1.NumParameters = 1;
  670. rootSignatureDescription.Desc_1_1.pParameters = rootParameters;
  671. rootSignatureDescription.Desc_1_1.NumStaticSamplers = 1;
  672. rootSignatureDescription.Desc_1_1.pStaticSamplers = &sampler;
  673. rootSignatureDescription.Desc_1_1.Flags = rootSignatureFlags;
  674. ID3DBlob* rootSignature;
  675. ID3DBlob* error;
  676. res = D3DX12SerializeVersionedRootSignature(&rootSignatureDescription,
  677. featureData.HighestVersion,
  678. &rootSignature,
  679. &error,
  680. d3d12svrsf,
  681. d3d12srsf);
  682. if (FAILED(res))
  683. {
  684. factory->Release();
  685. Logging::error()
  686. << "ERROR: D3DX12SerializeVersionedRootSignature returned " << res
  687. << "\n";
  688. WMessageBox(fenster->getWindowHandle(),
  689. new Text("Fehler"),
  690. new Text(
  691. "D3DX12SerializeVersionedRootSignature ist Fehlgeschlagen."),
  692. MB_ICONERROR);
  693. if (error) error->Release();
  694. return;
  695. }
  696. res = device->CreateRootSignature(0,
  697. rootSignature->GetBufferPointer(),
  698. rootSignature->GetBufferSize(),
  699. __uuidof(ID3D12RootSignature),
  700. (void**)&signature);
  701. if (FAILED(res))
  702. {
  703. factory->Release();
  704. Logging::error() << "ERROR: CreateRootSignature returned " << res
  705. << "\n";
  706. WMessageBox(fenster->getWindowHandle(),
  707. new Text("Fehler"),
  708. new Text("CreateRootSignature ist Fehlgeschlagen."),
  709. MB_ICONERROR);
  710. return;
  711. }
  712. rootSignature->Release();
  713. D3D12_RASTERIZER_DESC rdesc;
  714. rdesc.FillMode = D3D12_FILL_MODE_SOLID;
  715. rdesc.CullMode = D3D12_CULL_MODE_BACK;
  716. rdesc.FrontCounterClockwise = 0;
  717. rdesc.DepthBias = 0;
  718. rdesc.DepthBiasClamp = 0.f;
  719. rdesc.SlopeScaledDepthBias = 0.f;
  720. rdesc.DepthClipEnable = 1;
  721. rdesc.MultisampleEnable = 0;
  722. rdesc.AntialiasedLineEnable = 0;
  723. rdesc.ForcedSampleCount = 0;
  724. rdesc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
  725. uiTexture->updateTextur();
  726. directCommandQueue->execute();
  727. factory->Release();
  728. }
  729. void DirectX12::beginFrame(bool fill2D, bool fill3D, int fillColor)
  730. {
  731. D3D12_RESOURCE_BARRIER barrier;
  732. ZeroMemory(&barrier, sizeof(barrier));
  733. barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  734. barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  735. barrier.Transition.pResource = this->backBuffer[backBufferIndex];
  736. barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
  737. barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
  738. barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
  739. // TODO
  740. // directCommandQueue->getCommandList()->ResourceBarrier(1, &barrier);
  741. if (fill2D) uiTexture->zImage()->setColor(fillColor);
  742. if (fill3D)
  743. {
  744. float color[4];
  745. // Setup the color to clear the buffer.
  746. color[0] = ((fillColor >> 16) & 0xFF) / 255.f; // R
  747. color[1] = ((fillColor >> 8) & 0xFF) / 255.f; // G
  748. color[2] = (fillColor & 0xFF) / 255.f; // B
  749. color[3] = ((fillColor >> 24) & 0xFF) / 255.f; // A
  750. auto rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(
  751. D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
  752. D3D12_CPU_DESCRIPTOR_HANDLE rtv
  753. = rtvHeap->GetCPUDescriptorHandleForHeapStart();
  754. rtv.ptr += rtvDescriptorSize * backBufferIndex;
  755. // TODO
  756. // directCommandQueue->getCommandList()->OMSetRenderTargets(1, &rtv, 0,
  757. // 0);
  758. // directCommandQueue->getCommandList()->ClearRenderTargetView(
  759. // rtv, color, 0, 0);
  760. }
  761. uiTexture->updateTextur();
  762. }
  763. void DirectX12::renderKamera(Cam3D* zKamera)
  764. {
  765. renderKamera(zKamera, defaultRenderTarget, true);
  766. }
  767. void Framework::DirectX12::renderKamera(Cam3D* zKamera, Texture* zTarget)
  768. {
  769. renderKamera(zKamera, dynamic_cast<DX12Texture*>(zTarget), false);
  770. }
  771. void DirectX12::presentFrame()
  772. {
  773. // TODO
  774. // directCommandQueue->getCommandList()->RSSetViewports(1, viewPort);
  775. viewAndProj[0] = Mat4<float>::identity();
  776. viewAndProj[1] = Mat4<float>::identity();
  777. D3D12_RESOURCE_BARRIER barrier;
  778. ZeroMemory(&barrier, sizeof(barrier));
  779. barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  780. barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  781. barrier.Transition.pResource = this->backBuffer[backBufferIndex];
  782. barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
  783. barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
  784. barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
  785. // TODO
  786. // directCommandQueue->getCommandList()->ResourceBarrier(1, &barrier);
  787. copyCommandQueue->execute();
  788. directCommandQueue->execute();
  789. swapChain->Present(0, 0);
  790. backBufferIndex = swapChain->GetCurrentBackBufferIndex();
  791. }
  792. Texture* DirectX12::createOrGetTexture(
  793. const char* name, Image* b, TextureDirection dir)
  794. {
  795. if (!device)
  796. {
  797. if (b) b->release();
  798. return 0;
  799. }
  800. if (texturRegister->hasTexture(name))
  801. {
  802. Texture* ret = texturRegister->getTexture(name);
  803. if (b) ret->setImageZ(b);
  804. return ret;
  805. }
  806. Texture* ret
  807. = new DX12Texture(device, copyCommandQueue, directCommandQueue, dir);
  808. if (b) ret->setImageZ(b);
  809. texturRegister->addTexture(dynamic_cast<Texture*>(ret->getThis()), name);
  810. ret->updateTextur();
  811. copyCommandQueue->execute();
  812. directCommandQueue->execute();
  813. return ret;
  814. }
  815. Image* DirectX12::zUIRenderImage() const
  816. {
  817. return uiTexture ? uiTexture->zImage() : 0;
  818. }
  819. DXBuffer* DirectX12::createStructuredBuffer(int eSize)
  820. {
  821. return new DX12Buffer(eSize, device, D3D12_RESOURCE_FLAG_NONE);
  822. }
  823. void Framework::DirectX12::setPipeline(DX12Pipeline* pipeline)
  824. {
  825. if (this->pipeline)
  826. {
  827. this->pipeline->release();
  828. }
  829. this->pipeline = pipeline;
  830. }
  831. bool DirectX12::isAvailable()
  832. {
  833. HINSTANCE dxgiDLL = getDLLRegister()->loadDLL("dxgi.dll", "dxgi.dll");
  834. if (!dxgiDLL) return 0;
  835. HINSTANCE d3d12DLL = getDLLRegister()->loadDLL("d3d12.dll", "d3d12.dll");
  836. if (!d3d12DLL)
  837. {
  838. getDLLRegister()->releaseDLL("dxgi.dll");
  839. return 0;
  840. }
  841. CreateDXGIFactory2Function createFactory
  842. = (CreateDXGIFactory2Function)GetProcAddress(
  843. dxgiDLL, "CreateDXGIFactory2");
  844. if (!createFactory)
  845. {
  846. getDLLRegister()->releaseDLL("dxgi.dll");
  847. getDLLRegister()->releaseDLL("d3d12.dll");
  848. return 0;
  849. }
  850. D3D12CreateDeviceFunction createDevice
  851. = (D3D12CreateDeviceFunction)GetProcAddress(
  852. d3d12DLL, "D3D12CreateDevice");
  853. if (!createDevice)
  854. {
  855. getDLLRegister()->releaseDLL("dxgi.dll");
  856. getDLLRegister()->releaseDLL("d3d12.dll");
  857. return 0;
  858. }
  859. #ifdef _DEBUG
  860. D3D12GetDebugInterfaceFunction getDebugInterface
  861. = (D3D12GetDebugInterfaceFunction)GetProcAddress(
  862. d3d12DLL, "D3D12GetDebugInterface");
  863. ID3D12Debug* debug = 0;
  864. getDebugInterface(__uuidof(ID3D12Debug), (void**)&debug);
  865. debug->EnableDebugLayer();
  866. #endif
  867. IDXGIFactory4* factory;
  868. UINT createFactoryFlags = 0;
  869. #ifdef _DEBUG
  870. createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  871. #endif
  872. HRESULT res = createFactory(
  873. createFactoryFlags, __uuidof(IDXGIFactory4), (void**)&factory);
  874. if (FAILED(res))
  875. {
  876. getDLLRegister()->releaseDLL("dxgi.dll");
  877. getDLLRegister()->releaseDLL("d3d12.dll");
  878. return 0;
  879. }
  880. int index = 0;
  881. do
  882. {
  883. IDXGIAdapter1* current;
  884. res = factory->EnumAdapters1(index++, &current);
  885. if (res == S_OK)
  886. {
  887. DXGI_ADAPTER_DESC1 dxgiAdapterDesc1;
  888. current->GetDesc1(&dxgiAdapterDesc1);
  889. ID3D12Device5* device = 0;
  890. if ((dxgiAdapterDesc1.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0
  891. && SUCCEEDED(createDevice(current,
  892. D3D_FEATURE_LEVEL_12_1,
  893. __uuidof(ID3D12Device5),
  894. (void**)&device)))
  895. {
  896. device->Release();
  897. current->Release();
  898. factory->Release();
  899. #ifdef _DEBUG
  900. debug->Release();
  901. #endif
  902. getDLLRegister()->releaseDLL("dxgi.dll");
  903. getDLLRegister()->releaseDLL("d3d12.dll");
  904. return 1;
  905. }
  906. current->Release();
  907. }
  908. } while (res != DXGI_ERROR_NOT_FOUND);
  909. factory->Release();
  910. getDLLRegister()->releaseDLL("dxgi.dll");
  911. getDLLRegister()->releaseDLL("d3d12.dll");
  912. return 0;
  913. }