In this case, we would like to create a swap chain for a window, so we use the CreateSwapChainForHwnd
function of IDXGIFactory4
to create a swapchain for the window we would like our frames to be rendered to.
IDXGISwapChain1* swapChain;
result = renderer->dxgiFactory->lpVtbl->CreateSwapChainForHwnd(
renderer->dxgiFactory,
(IUnknown*)renderer->device,
window,
&(DXGI_SWAP_CHAIN_DESC1){
.Width = 0,
.Height = 0,
.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
.Stereo = FALSE,
.SampleDesc = {
.Count = 1,
},
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
.BufferCount = FRAME_BUFFER_COUNT,
.Scaling = DXGI_SCALING_STRETCH,
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED,
.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH,
},
NULL,
NULL,
&swapChain
);
if ( !SUCCEEDED ( result ) )
RETURN_ERROR(-1, "CreateSwapChainForHwnd failed (0x%08X)", result );
result = swapChain->lpVtbl->QueryInterface (
swapChain,
&IID_IDXGISwapChain3,
&renderer->dxgiSwapChain
);
if ( !SUCCEEDED ( result ) )
RETURN_ERROR(-1, "QueryInterface failed (0x%08X)", result );
ID3D11Texture2D* tex;
result = renderer->dxgiSwapChain->lpVtbl->GetBuffer (
renderer->dxgiSwapChain,
0,
&IID_ID3D11Texture2D,
&tex
);
if ( !SUCCEEDED ( result ) )
RETURN_ERROR(-1, "GetBuffers failed (0x%08X)", result );
result = renderer->device->lpVtbl->CreateRenderTargetView (
renderer->device,
(ID3D11Resource*)tex,
&(D3D11_RENDER_TARGET_VIEW_DESC){
.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D,
},
&renderer->rtv
);
if ( !SUCCEEDED ( result ) )
RETURN_ERROR(-1, "CreateRenderTargetView failed (0x%08X)", result );
tex->lpVtbl->Release ( tex );
We specify 0 for the Width
and Height
properties in DXGI_SWAP_CHAIN_DESC1
to create a swap chain of the same size as the window, and specify DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
to be allowed to switch between full screen and windowed later. We also specify the amount of buffers in the swap chain using BufferCount
.
In BufferUsage
we must specify DXGI_USAGE_RENDER_TARGET_OUTPUT
in order to be allowed to render to it. In addition, DXGI_USAGE_SHADER_INPUT
if use as a texture is desired, but we will not require this behaviour.
The SwapEffect
field can include a variety of swap methods, as seen here. The flip methods should be preferred if available, as there is less latency and overhead involved in the flip swap effects than with the other swap methods available. Do note the limited availability of flip modes however; DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
is only supported in Windows 8 and up, while DXGI_SWAP_EFFECT_FLIP_DISCARD
is only supported since Windows 10.