DX12GraphicsApi.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. #include "GraphicsApi.h"
  2. #include "Globals.h"
  3. #include "DLLRegister.h"
  4. #include "Fenster.h"
  5. #include <d3d11.h>
  6. #include <d3d12.h>
  7. #include <dxgi1_5.h>
  8. using namespace Framework;
  9. DirectX12::DirectX12()
  10. : GraphicsApi( DIRECTX12 ),
  11. device( 0 ),
  12. infoQueue( 0 ),
  13. directCommandQueue( 0 ),
  14. swapChain( 0 ),
  15. rtvHeap( 0 ),
  16. directCommandList( 0 ),
  17. backBufferIndex( 0 ),
  18. tearing( 0 ),
  19. fence( 0 ),
  20. fenceEvent( 0 )
  21. {
  22. for( int i = 0; i < 2; i++ )
  23. {
  24. fenceValue[ i ] = 0;
  25. backBuffer[ i ] = 0;
  26. directCommandAllocator[ i ] = 0;
  27. }
  28. }
  29. DirectX12::~DirectX12()
  30. {
  31. if( directCommandQueue && fence && fenceEvent )
  32. {
  33. unsigned __int64 val = ++fenceValue[ backBufferIndex ];
  34. directCommandQueue->Signal( fence, val );
  35. if( fence->GetCompletedValue() < val )
  36. {
  37. fence->SetEventOnCompletion( val, fenceEvent );
  38. WaitForSingleObject( fenceEvent, INFINITE );
  39. }
  40. }
  41. if( fence )
  42. fence->Release();
  43. if( directCommandList )
  44. directCommandList->Release();
  45. for( int i = 0; i < 2; i++ )
  46. {
  47. if( directCommandAllocator[ i ] )
  48. directCommandAllocator[ i ]->Release();
  49. if( backBuffer[ i ] )
  50. backBuffer[ i ]->Release();
  51. }
  52. if( rtvHeap )
  53. rtvHeap->Release();
  54. if( swapChain )
  55. swapChain->Release();
  56. if( directCommandQueue )
  57. directCommandQueue->Release();
  58. if( infoQueue )
  59. infoQueue->Release();
  60. if( device )
  61. {
  62. device->Release();
  63. getDLLRegister()->releaseDLL( "dxgi.dll" );
  64. getDLLRegister()->releaseDLL( "d3d12.dll" );
  65. }
  66. }
  67. typedef HRESULT( *CreateDXGIFactory2Function )( UINT, REFIID, void ** );
  68. typedef HRESULT( *D3D12CreateDeviceFunction )( IDXGIAdapter *, D3D_FEATURE_LEVEL,
  69. REFIID, void ** );
  70. void DirectX12::initialize( WFenster * fenster, Vec2<int> backBufferSize, bool fullScreen )
  71. {
  72. if( device )
  73. return GraphicsApi::initialize( fenster, backBufferSize, fullScreen );
  74. GraphicsApi::initialize( fenster, backBufferSize, fullScreen );
  75. HINSTANCE dxgiDLL = getDLLRegister()->ladeDLL( "dxgi.dll", "dxgi.dll" );
  76. if( !dxgiDLL )
  77. {
  78. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "dxgi.dll konnte nicht gefunden werden." ), MB_ICONERROR );
  79. return;
  80. }
  81. HINSTANCE d3d12DLL = getDLLRegister()->ladeDLL( "d3d12.dll", "d3d12.dll" );
  82. if( !d3d12DLL )
  83. {
  84. getDLLRegister()->releaseDLL( "dxgi.dll" );
  85. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "DirectX 12 konnte nicht gefunden werden." ), MB_ICONERROR );
  86. return;
  87. }
  88. CreateDXGIFactory2Function createFactory = (CreateDXGIFactory2Function)GetProcAddress( dxgiDLL, "CreateDXGIFactory2" );
  89. if( !createFactory )
  90. {
  91. getDLLRegister()->releaseDLL( "dxgi.dll" );
  92. getDLLRegister()->releaseDLL( "d3d12.dll" );
  93. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "Der Einstiegspunkt CreateDXGIFactory2 fon DXGI konnte nicht gefunden werden." ), MB_ICONERROR );
  94. return;
  95. }
  96. D3D12CreateDeviceFunction createDevice = (D3D12CreateDeviceFunction)GetProcAddress( d3d12DLL, "D3D12CreateDevice" );
  97. if( !createDevice )
  98. {
  99. getDLLRegister()->releaseDLL( "dxgi.dll" );
  100. getDLLRegister()->releaseDLL( "d3d12.dll" );
  101. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "Der Einstiegspunkt D3D12CreateDevice fon DirectX 12 konnte nicht gefunden werden." ), MB_ICONERROR );
  102. return;
  103. }
  104. IDXGIFactory4 *factory;
  105. UINT createFactoryFlags = 0;
  106. #if defined(_DEBUG)
  107. createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  108. #endif
  109. HRESULT res = createFactory( createFactoryFlags, __uuidof( IDXGIFactory4 ), (void **)& factory );
  110. if( FAILED( res ) )
  111. {
  112. getDLLRegister()->releaseDLL( "dxgi.dll" );
  113. getDLLRegister()->releaseDLL( "d3d12.dll" );
  114. std::cout << "ERROR: createFactory returned " << res << "\n";
  115. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "createFactory ist Fehlgeschlagen." ), MB_ICONERROR );
  116. return;
  117. }
  118. int index = 0;
  119. unsigned __int64 maxVideoMemory = 0;
  120. IDXGIAdapter1 *best = 0;
  121. do
  122. {
  123. IDXGIAdapter1 *current;
  124. res = factory->EnumAdapters1( index++, &current );
  125. if( res == S_OK )
  126. {
  127. DXGI_ADAPTER_DESC1 dxgiAdapterDesc1;
  128. current->GetDesc1( &dxgiAdapterDesc1 );
  129. if( ( dxgiAdapterDesc1.Flags &DXGI_ADAPTER_FLAG_SOFTWARE ) == 0 &&
  130. dxgiAdapterDesc1.DedicatedVideoMemory > maxVideoMemory &&
  131. SUCCEEDED( createDevice( current, D3D_FEATURE_LEVEL_12_1, __uuidof( ID3D12Device2 ), 0 ) ) )
  132. {
  133. if( best )
  134. best->Release();
  135. best = current;
  136. maxVideoMemory = dxgiAdapterDesc1.DedicatedVideoMemory;
  137. }
  138. else
  139. current->Release();
  140. }
  141. } while( res != DXGI_ERROR_NOT_FOUND );
  142. res = createDevice( best, D3D_FEATURE_LEVEL_12_1, __uuidof( ID3D12Device2 ), (void **)& device );
  143. best->Release();
  144. if( FAILED( res ) )
  145. {
  146. factory->Release();
  147. getDLLRegister()->releaseDLL( "dxgi.dll" );
  148. getDLLRegister()->releaseDLL( "d3d12.dll" );
  149. std::cout << "ERROR: createDevice returned " << res << "\n";
  150. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "createDevice ist Fehlgeschlagen." ), MB_ICONERROR );
  151. return;
  152. }
  153. res = device->QueryInterface( __uuidof( ID3D12InfoQueue ), (void **)& infoQueue );
  154. if( SUCCEEDED( res ) )
  155. {
  156. infoQueue->SetBreakOnSeverity( D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE );
  157. infoQueue->SetBreakOnSeverity( D3D12_MESSAGE_SEVERITY_ERROR, TRUE );
  158. infoQueue->SetBreakOnSeverity( D3D12_MESSAGE_SEVERITY_WARNING, TRUE );
  159. D3D12_MESSAGE_SEVERITY Severities[] =
  160. {
  161. D3D12_MESSAGE_SEVERITY_INFO
  162. };
  163. // Suppress individual messages by their ID
  164. D3D12_MESSAGE_ID DenyIds[] = {
  165. D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE, // I'm really not sure how to avoid this message.
  166. D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE, // This warning occurs when using capture frame while graphics debugging.
  167. D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE, // This warning occurs when using capture frame while graphics debugging.
  168. };
  169. D3D12_INFO_QUEUE_FILTER NewFilter = {};
  170. NewFilter.DenyList.NumSeverities = _countof( Severities );
  171. NewFilter.DenyList.pSeverityList = Severities;
  172. NewFilter.DenyList.NumIDs = _countof( DenyIds );
  173. NewFilter.DenyList.pIDList = DenyIds;
  174. infoQueue->PushStorageFilter( &NewFilter );
  175. }
  176. D3D12_COMMAND_QUEUE_DESC desc = {};
  177. desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
  178. desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
  179. desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
  180. desc.NodeMask = 0;
  181. res = device->CreateCommandQueue( &desc, __uuidof( ID3D12CommandQueue ), (void **)& directCommandQueue );
  182. if( FAILED( res ) )
  183. {
  184. factory->Release();
  185. std::cout << "ERROR: CreateCommandQueue returned " << res << "\n";
  186. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "CreateCommandQueue ist Fehlgeschlagen." ), MB_ICONERROR );
  187. return;
  188. }
  189. IDXGIFactory5 *fac5 = 0;
  190. factory->QueryInterface( __uuidof( IDXGIFactory5 ), (void **)& fac5 );
  191. if( fac5 )
  192. {
  193. res = fac5->CheckFeatureSupport( DXGI_FEATURE_PRESENT_ALLOW_TEARING, &tearing, sizeof( tearing ) );
  194. if( FAILED( res ) )
  195. tearing = 0;
  196. fac5->Release();
  197. }
  198. DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
  199. swapChainDesc.Width = backBufferSize.x;
  200. swapChainDesc.Height = backBufferSize.y;
  201. swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  202. swapChainDesc.Stereo = FALSE;
  203. swapChainDesc.SampleDesc = { 1, 0 };
  204. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  205. swapChainDesc.BufferCount = 2;
  206. swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
  207. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
  208. swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
  209. swapChainDesc.Flags = tearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
  210. IDXGISwapChain1 *tmpSwapChain;
  211. res = factory->CreateSwapChainForHwnd( directCommandQueue, fenster->getFensterHandle(), &swapChainDesc, 0, 0, &tmpSwapChain );
  212. if( FAILED( res ) )
  213. {
  214. factory->Release();
  215. std::cout << "ERROR: CreateSwapChainForHwnd returned " << res << "\n";
  216. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "CreateSwapChainForHwnd ist Fehlgeschlagen." ), MB_ICONERROR );
  217. return;
  218. }
  219. res = tmpSwapChain->QueryInterface( __uuidof( IDXGISwapChain4 ), (void**)&swapChain );
  220. tmpSwapChain->Release();
  221. if( FAILED( res ) )
  222. {
  223. factory->Release();
  224. std::cout << "ERROR: QueryInterface returned " << res << "\n";
  225. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "QueryInterface ist Fehlgeschlagen." ), MB_ICONERROR );
  226. return;
  227. }
  228. factory->MakeWindowAssociation( fenster->getFensterHandle(), DXGI_MWA_NO_ALT_ENTER );
  229. D3D12_DESCRIPTOR_HEAP_DESC rtvhdesc = {};
  230. rtvhdesc.NumDescriptors = 2;
  231. rtvhdesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
  232. res = device->CreateDescriptorHeap( &rtvhdesc, __uuidof( ID3D12DescriptorHeap ), (void **)& rtvHeap );
  233. if( FAILED( res ) )
  234. {
  235. factory->Release();
  236. std::cout << "ERROR: CreateDescriptorHeap returned " << res << "\n";
  237. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "CreateDescriptorHeap ist Fehlgeschlagen." ), MB_ICONERROR );
  238. return;
  239. }
  240. auto rtvDescriptorSize = device->GetDescriptorHandleIncrementSize( D3D12_DESCRIPTOR_HEAP_TYPE_RTV );
  241. D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle( rtvHeap->GetCPUDescriptorHandleForHeapStart() );
  242. for( int i = 0; i < 2; i++ )
  243. {
  244. ID3D12Resource *backBuffer;
  245. res = swapChain->GetBuffer( i, __uuidof( ID3D12Resource ), (void **)& backBuffer );
  246. if( FAILED( res ) )
  247. {
  248. factory->Release();
  249. std::cout << "ERROR: GetBuffer returned " << res << "\n";
  250. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "GetBuffer ist Fehlgeschlagen." ), MB_ICONERROR );
  251. return;
  252. }
  253. device->CreateRenderTargetView( backBuffer, nullptr, rtvHandle );
  254. this->backBuffer[ i ] = backBuffer;
  255. rtvHandle.ptr += rtvDescriptorSize;
  256. }
  257. res = device->CreateCommandAllocator( D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof( ID3D12CommandAllocator ), (void **)& directCommandAllocator[ 0 ] );
  258. if( FAILED( res ) )
  259. {
  260. factory->Release();
  261. std::cout << "ERROR: CreateCommandAllocator returned " << res << "\n";
  262. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "CreateCommandAllocator ist Fehlgeschlagen." ), MB_ICONERROR );
  263. return;
  264. }
  265. res = device->CreateCommandAllocator( D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof( ID3D12CommandAllocator ), (void **)& directCommandAllocator[ 1 ] );
  266. if( FAILED( res ) )
  267. {
  268. factory->Release();
  269. std::cout << "ERROR: CreateCommandAllocator returned " << res << "\n";
  270. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "CreateCommandAllocator ist Fehlgeschlagen." ), MB_ICONERROR );
  271. return;
  272. }
  273. res = device->CreateCommandList( 0, D3D12_COMMAND_LIST_TYPE_DIRECT, directCommandAllocator[ 0 ], nullptr, __uuidof( ID3D12GraphicsCommandList ), (void **)& directCommandList );
  274. if( FAILED( res ) )
  275. {
  276. factory->Release();
  277. std::cout << "ERROR: CreateCommandList returned " << res << "\n";
  278. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "CreateCommandList ist Fehlgeschlagen." ), MB_ICONERROR );
  279. return;
  280. }
  281. device->CreateFence( 0, D3D12_FENCE_FLAG_NONE, __uuidof( ID3D12Fence ), (void **)&fence );
  282. fenceEvent = CreateEvent( 0, 0, 0, 0 );
  283. if( !fenceEvent )
  284. {
  285. factory->Release();
  286. std::cout << "ERROR: CreateEvent returned 0\n";
  287. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "CreateEvent ist Fehlgeschlagen." ), MB_ICONERROR );
  288. return;
  289. }
  290. factory->Release();
  291. }
  292. void DirectX12::update()
  293. {
  294. if( !device || !swapChain || !fence || !directCommandQueue || !fenceEvent )
  295. return;
  296. unsigned __int64 val = ++fenceValue[ backBufferIndex ];
  297. directCommandQueue->Signal( fence, val );
  298. if( fence->GetCompletedValue() < val )
  299. {
  300. fence->SetEventOnCompletion( val, fenceEvent );
  301. WaitForSingleObject( fenceEvent, INFINITE );
  302. }
  303. HINSTANCE dxgiDLL = getDLLRegister()->ladeDLL( "dxgi.dll", "dxgi.dll" );
  304. if( !dxgiDLL )
  305. {
  306. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "dxgi.dll konnte nicht gefunden werden." ), MB_ICONERROR );
  307. return;
  308. }
  309. CreateDXGIFactory2Function createFactory = (CreateDXGIFactory2Function)GetProcAddress( dxgiDLL, "CreateDXGIFactory2" );
  310. if( !createFactory )
  311. {
  312. getDLLRegister()->releaseDLL( "dxgi.dll" );
  313. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "Der Einstiegspunkt CreateDXGIFactory2 fon DXGI konnte nicht gefunden werden." ), MB_ICONERROR );
  314. return;
  315. }
  316. DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
  317. HRESULT res = swapChain->GetDesc( &swapChainDesc );
  318. if( FAILED( res ) )
  319. {
  320. getDLLRegister()->releaseDLL( "dxgi.dll" );
  321. std::cout << "ERROR: GetDesc returned " << res << "\n";
  322. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "GetDesc ist Fehlgeschlagen." ), MB_ICONERROR );
  323. return;
  324. }
  325. IDXGIFactory4 *factory;
  326. UINT createFactoryFlags = 0;
  327. #if defined(_DEBUG)
  328. createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  329. #endif
  330. res = createFactory( createFactoryFlags, __uuidof( IDXGIFactory4 ), (void **)& factory );
  331. if( FAILED( res ) )
  332. {
  333. getDLLRegister()->releaseDLL( "dxgi.dll" );
  334. std::cout << "ERROR: createFactory returned " << res << "\n";
  335. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "createFactory ist Fehlgeschlagen." ), MB_ICONERROR );
  336. return;
  337. }
  338. for( int i = 0; i < 2; ++i )
  339. {
  340. backBuffer[ i ]->Release();
  341. backBuffer[ i ] = 0;
  342. }
  343. res = swapChain->ResizeBuffers( 2, backBufferSize.x, backBufferSize.y,
  344. swapChainDesc.BufferDesc.Format, swapChainDesc.Flags );
  345. backBufferIndex = swapChain->GetCurrentBackBufferIndex();
  346. auto rtvDescriptorSize = device->GetDescriptorHandleIncrementSize( D3D12_DESCRIPTOR_HEAP_TYPE_RTV );
  347. D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle( rtvHeap->GetCPUDescriptorHandleForHeapStart() );
  348. for( int i = 0; i < 2; i++ )
  349. {
  350. ID3D12Resource *backBuffer;
  351. res = swapChain->GetBuffer( i, __uuidof( ID3D12Resource ), (void **)& backBuffer );
  352. if( FAILED( res ) )
  353. {
  354. getDLLRegister()->releaseDLL( "dxgi.dll" );
  355. factory->Release();
  356. std::cout << "ERROR: GetBuffer returned " << res << "\n";
  357. WMessageBox( fenster->getFensterHandle(), new Text( "Fehler" ), new Text( "GetBuffer ist Fehlgeschlagen." ), MB_ICONERROR );
  358. return;
  359. }
  360. device->CreateRenderTargetView( backBuffer, nullptr, rtvHandle );
  361. this->backBuffer[ i ] = backBuffer;
  362. rtvHandle.ptr += rtvDescriptorSize;
  363. }
  364. getDLLRegister()->releaseDLL( "dxgi.dll" );
  365. factory->Release();
  366. }
  367. void DirectX12::beginFrame( bool fill2D, bool fill3D, int fillColor )
  368. {
  369. D3D12_RESOURCE_BARRIER barrier;
  370. ZeroMemory( &barrier, sizeof( barrier ) );
  371. barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
  372. barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
  373. barrier.Transition.pResource = this->backBuffer[ backBufferIndex ];
  374. barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
  375. barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
  376. barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
  377. directCommandList->ResourceBarrier( 1, &barrier );
  378. if( fill3D )
  379. {
  380. float color[ 4 ];
  381. // Setup the color to clear the buffer.
  382. color[ 0 ] = ( ( fillColor >> 16 ) & 0xFF ) / 255.f; // R
  383. color[ 1 ] = ( ( fillColor >> 8 ) & 0xFF ) / 255.f; // G
  384. color[ 2 ] = ( fillColor & 0xFF ) / 255.f; // B
  385. color[ 3 ] = ( ( fillColor >> 24 ) & 0xFF ) / 255.f; // A
  386. auto rtvDescriptorSize = device->GetDescriptorHandleIncrementSize( D3D12_DESCRIPTOR_HEAP_TYPE_RTV );
  387. D3D12_CPU_DESCRIPTOR_HANDLE rtv = rtvHeap->GetCPUDescriptorHandleForHeapStart();
  388. rtv.ptr += rtvDescriptorSize * backBufferIndex;
  389. directCommandList->ClearRenderTargetView( rtv, color, 0, 0 );
  390. }
  391. }
  392. void DirectX12::renderKamera( Kam3D * zKamera )
  393. {
  394. }
  395. void DirectX12::presentFrame()
  396. {
  397. directCommandList->Close();
  398. directCommandQueue->ExecuteCommandLists( 1, (ID3D12CommandList**)&directCommandList );
  399. // TODO: Render Framework GUI
  400. swapChain->Present( 0, tearing ? DXGI_PRESENT_ALLOW_TEARING : 0 );
  401. directCommandQueue->Signal( fence, ++fenceValue[ backBufferIndex ] );
  402. if( fence->GetCompletedValue() < fenceValue[ backBufferIndex ] )
  403. {
  404. fence->SetEventOnCompletion( fenceValue[ backBufferIndex ], fenceEvent );
  405. WaitForSingleObject( fenceEvent, INFINITE );
  406. }
  407. backBufferIndex = swapChain->GetCurrentBackBufferIndex();
  408. directCommandAllocator[ backBufferIndex ]->Reset();
  409. directCommandList->Reset( directCommandAllocator[ backBufferIndex ], nullptr );
  410. }
  411. Textur *DirectX12::createOrGetTextur( const char *name, Bild * b )
  412. {
  413. return 0;
  414. }
  415. Bild *DirectX12::zUIRenderBild() const
  416. {
  417. return 0;
  418. }
  419. bool DirectX12::isAvailable()
  420. {
  421. HINSTANCE dxgiDLL = getDLLRegister()->ladeDLL( "dxgi.dll", "dxgi.dll" );
  422. if( !dxgiDLL )
  423. return 0;
  424. HINSTANCE d3d12DLL = getDLLRegister()->ladeDLL( "d3d12.dll", "d3d12.dll" );
  425. if( !d3d12DLL )
  426. {
  427. getDLLRegister()->releaseDLL( "dxgi.dll" );
  428. return 0;
  429. }
  430. CreateDXGIFactory2Function createFactory = (CreateDXGIFactory2Function)GetProcAddress( dxgiDLL, "CreateDXGIFactory2" );
  431. if( !createFactory )
  432. {
  433. getDLLRegister()->releaseDLL( "dxgi.dll" );
  434. getDLLRegister()->releaseDLL( "d3d12.dll" );
  435. return 0;
  436. }
  437. D3D12CreateDeviceFunction createDevice = (D3D12CreateDeviceFunction)GetProcAddress( d3d12DLL, "D3D12CreateDevice" );
  438. if( !createDevice )
  439. {
  440. getDLLRegister()->releaseDLL( "dxgi.dll" );
  441. getDLLRegister()->releaseDLL( "d3d12.dll" );
  442. return 0;
  443. }
  444. IDXGIFactory4 *factory;
  445. UINT createFactoryFlags = 0;
  446. #if defined(_DEBUG)
  447. createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
  448. #endif
  449. HRESULT res = createFactory( createFactoryFlags, __uuidof( IDXGIFactory4 ), (void **)& factory );
  450. if( FAILED( res ) )
  451. {
  452. getDLLRegister()->releaseDLL( "dxgi.dll" );
  453. getDLLRegister()->releaseDLL( "d3d12.dll" );
  454. return 0;
  455. }
  456. int index = 0;
  457. do
  458. {
  459. IDXGIAdapter1 *current;
  460. res = factory->EnumAdapters1( index++, &current );
  461. if( res == S_OK )
  462. {
  463. DXGI_ADAPTER_DESC1 dxgiAdapterDesc1;
  464. current->GetDesc1( &dxgiAdapterDesc1 );
  465. if( ( dxgiAdapterDesc1.Flags &DXGI_ADAPTER_FLAG_SOFTWARE ) == 0 &&
  466. SUCCEEDED( createDevice( current, D3D_FEATURE_LEVEL_12_1, __uuidof( ID3D12Device2 ), 0 ) ) )
  467. {
  468. current->Release();
  469. factory->Release();
  470. getDLLRegister()->releaseDLL( "dxgi.dll" );
  471. getDLLRegister()->releaseDLL( "d3d12.dll" );
  472. return 1;
  473. }
  474. current->Release();
  475. }
  476. } while( res != DXGI_ERROR_NOT_FOUND );
  477. factory->Release();
  478. getDLLRegister()->releaseDLL( "dxgi.dll" );
  479. getDLLRegister()->releaseDLL( "d3d12.dll" );
  480. return 0;
  481. }