Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

directX creating the swapchain

Tags:

c++

directx

In my book there i code to create swap chain.

IDXGIDevice * dxgiDevice = 0;
mD3dDevice->QueryInterface( __uuidof( IDXGIDevice ),( void ** ) & dxgiDevice );

IDXGIAdapter * dxgiAdapter = 0;
dxgiDevice->GetParent( __uuidof( IDXGIAdapter ),( void ** ) & dxgiAdapter );

IDXGIFactory * dxgiFactory = 0;
dxgiAdapter->GetParent( __uuidof( IDXGIFactory ),( void ** ) & dxgiFactory );

dxgiFactory->CreateSwapChain( mD3dDevice, & sd, & mSwapChain );

For this code there is no explanation, i check few mor books and there is too, noo explanation for this code.

Please help mi with this. I realy dont understand what doing GetParent method. idxgiDevice extend idxgiObject. parent for idxgiDevice is idxgiObject, why they use pointer to idxgiFacory as a parametr.

And i dont know that i understand the queryInterface good

Please help mi with this

like image 853
user3818006 Avatar asked Dec 08 '22 05:12

user3818006


1 Answers

This code is for creating the swap chain with DirectX 11 or later version of the interfaces, and this pattern is specifically designed to ensure that the DXGI factory instance you use is the one that was actually used when you created the Direct3D 11 device.

Basically, when you first created the Direct3D 11 device, you had the option of providing the IDXGIAdapter instance to use. Most people pass nullptr or NULL here and just let it create a device on the default adapter in the system. To finish setting up the swap chain, however, you need the DXGI factory instance. You could in theory create one yourself using DXGICreateFactory1 but you could easily mess up and get the 'wrong one' by using DXGICreateFactory or maybe DXGICreateFactory2 with the wrong flags.

Instead, the safest thing to do is get the IDXGIDevice from your ID3D11Device using the standard COM IUnknown::QueryInterface:

IDXGIDevice * dxgiDevice = 0;
HRESULT hr = mD3dDevice->QueryInterface( __uuidof( IDXGIDevice ),( void ** ) & dxgiDevice );
if ( SUCCEEDED(hr) )

Then get the IDXGIAdapter from the IDXGIDevice using IDXGIObject::GetParent:

IDXGIAdapter * dxgiAdapter = 0;
hr = dxgiDevice->GetParent( __uuidof( IDXGIAdapter ),( void ** ) & dxgiAdapter );
if ( SUCCEEDED(hr) )

Then get the IDXGIFactory from the IDXGIAdapter using IDXGIObject::GetParent again:

IDXGIFactory * dxgiFactory = 0;
hr = dxgiAdapter->GetParent( __uuidof( IDXGIFactory ),( void ** ) & dxgiFactory );
if ( SUCCEEDED(hr) )

Now you have the IDXGIFactory associated with your Direct3D 11 device no matter how it was created. Remember that COM reference counting means you have references to all these objects now you have to cleanup:

dxgiFactory->Release();
dxgiAdapter->Release();
dxgiDevice->Release();

Note that IDXGIFactory::CreateSwapChain is the DirectX 11.0 way of creating the swap chain, and you'd get basically the same results if you had used D3D11CreateDeviceAndSwapChain rather than D3D11CreateDevice in the first place. For DirectX 11.1 or later systems, you would consider using IDXGIFactory2::CreateSwapChainForHwnd instead for Win32 desktop apps. For Windows Store apps, Windows phone 8, and Xbox One, you'd always use IDXGIFactory2::CreateSwapChainForCoreWindow.

For a Win32 desktop application, you'd follow the code above with something like:

IDXGIFactory2* dxgiFactory2 = 0;
hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) );
if ( SUCCEEDED(hr) )
{
    // This system has DirectX 11.1 or later installed, so we can use this interface
    dxgiFactory2->CreateSwapChainForHwnd( /* parameters */ );
    dxgiFactory2->Release();
}
else
{
    // This system only has DirectX 11.0 installed
     dxgiFactory->CreateSwapChain( /* parameters */ );
}

See Anatomy of Direct3D 11 Create Device and the Direct3D tutorial sample Win32 desktop app version.

DirectX12 usage explicitly disallows this code pattern. For more details, see this blog post.

like image 99
Chuck Walbourn Avatar answered Dec 10 '22 19:12

Chuck Walbourn