Understanding MSDN DirectX11 and Directx11.1 Code

When initializing DirectX 11.1 for win32, I followed the example MSDN code. The code declares two Direct3d devices:

ID3D11Device* g_pd3dDevice = nullptr; ID3D11Device1* g_pd3dDevice1 = nullptr; 

and then purchase a device, for example:

 D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); hr = D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if ( hr == E_INVALIDARG ) { hr = D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); } if( FAILED( hr ) ) return hr; 

Then we get the DXGIDevice:

 IDXGIFactory1* dxgiFactory = nullptr; IDXGIDevice* dxgiDevice = nullptr; hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); 

Then we get the adapter:

 IDXGIAdapter* adapter = nullptr; hr = dxgiDevice->GetAdapter(&adapter); 

From the adapter we get the IDXGIFactory1 interface:

  hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) ); 

In the IDXGIFactory1 interface, we request the IDXGIFactory2 interface:

 IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) ); 

If IDXGIFactory2 is available, we request a Direct3D11.1 device interface. Also get the ID3D11DeviceContext1 interface:

 if ( dxgiFactory2 ) { // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**> (&g_pImmediateContext1) ); } 

Then we create a swapchain:

 hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); 

My first question is , why does this code use the DirectX11 device version when creating swapchain? Should we use g_pd3dDevice1 instead of g_pd3dDevice?

My second question , although we could get the DirectX11.1 version of the interfaces, the msdn example code acquired the IDXGISwapChain interface from the IDXGISwapChain1 interface:

 hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) ); 

and use this version of swapchain in the current call:

 g_pSwapChain->Present( 0, 0 ); 

Why is this?

+4
source share
1 answer

You are referring to the Direct3D Win32 Tutorial , which is located on the MSDN Code Gallery . Please note that there is also a version of GitHub .

Disclaimer: this is all that I got from the outdated DirectX SDK , so they are all unofficial samples. Official Windows SDK Samples for the Windows 8 Store or Universal Windows Applications in Windows 10 . Although these samples are unofficial, since I'm the last developer to work with the obsolete DirectX SDK, they are at least reputable.

The first thing to say is that most of the complexity is that the tutorial code works correctly on DirectX 11.0 systems (Windows Vista SP2 + KB971644 , Windows 7 RTM, Windows 7 SP1 without KB2670838), as well as DirectX 11.1 or newer (Windows 7 SP1 + KB2670838 , Windows 8 or newer), This is not required for the Windows 8 Store or universal Windows applications that can rely on never working on DirectX 11.0 systems.

Both instances of the g_pd3dDevice and g_pd3dDevice1 are really the same object, but with different interfaces. Think of QueryInterface as C ++ dynamic_cast . The same goes for g_pSwapChain and g_pSwapChain1 .

The code for capturing a Direct3D 11.1 device and device context, if available, can really be anywhere in the InitDevice function. In Direct3D VS Win32 Game Template I have this after creating the device, but before I create the swap chain so that they do not need to be tied together. I put this code in the swapchain if statement in the tutorial so that it matches two comments: "DirectX 11.1 or later" and "DirectX 11.0", which are different for DXGI 1.1 compared to DXGI 1.2 +.

  // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**> (&g_pImmediateContext1) ); } 

The code in the Win32 tutorial that you are looking at is also much simpler in the VS Win32 Game template, because I use Microsoft::WRL::ComPtr .

I use g_pSwapChain for Present , so I donโ€™t need to have two different code paths for DirectX 11.0 compared to DirectX 11.1. If you are not using the newer DXGI 1.2 methods, you can use the base code here simply.

DXGI 1.0 was released for DirectX 10.0. DXGI 1.1 is for DirectX 11.0. DXGI 1.2 - DirectX 11.1.

See Anatomy of Direct3D 11 Create a Device , Direct3D Win32 Game Visual Studio Template, and DirectX Tool Kit Tutorials .

+2
source

All Articles