Swap Chains

Swap chains control the back buffer rotation, forming the basis of graphics animation.


The programming model for swap chains in D3D12 is not identical to that in earlier versions of D3D. The programming convenience, for example, of supporting automatic resource rotation that was present in D3D10 and D3D11 is not now supported. Automatic resource rotation enabled apps to render the same API object while the actual surface being rendered changes each frame. The behavior of swap chains is changed with D3D12 to enable other features of D3D12 to have low CPU overhead.

Buffer lifetime

Apps are allowed to store pre-created descriptors which reference back buffers This is enabled by ensuring that the set of buffers owned by a swap chain never changes for the lifetime of the swap chain. The set of buffers returned by IDXGISwapChain::GetBuffer does not change until certain APIs are called:

The order of buffers returned by GetBuffer never changes.

IDXGISwapChain3::GetCurrentBackBufferIndex returns the index of the current back buffer to the app.

Swap effects

The only supported swap effect is FLIP_SEQUENTIAL, which requires the buffer count to be greater than one.

Transitioning between windowed and full-screen modes

D3D12 maintains the restriction that applications must call ResizeBuffers after transitioning between windowed and full-screen modes (D3D11 flip-model swap chains have the same restrictions).

The IDXGISwapChain::SetFullscreenState transitions do not change the set of app-visible buffers in the swap chain. Only the ResizeBuffers and ResizeTarget calls create or destroy app-visible buffers.

When IDXGISwapChain1::Present1 is called, the back buffer to be presented must be in the D3D12_RESOURCE_STATE_PRESENT state. Present will fail with DXGI_ERROR_INVALID_CALL if this is not the case.

Full-screen swap chains continue to have the restriction that SetFullscreenState(FALSE, NULL) must be called before the final release of the swap chain. SetFullscreenState(FALSE) succeeds on swap chains running on D3D12 devices.

Present operations occur on the default 3D queue associated with the device., and apps are free to concurrently present multiple swap chains, and record and execute command lists.


The following example code would be present in the main rendering loop:

        CComPtr<IDXGISwapChain3> spSwapChain3;
        UINT backBufferIndex = spSwapChain3->GetCurrentBackBufferIndex();

        CComPtr<ID3D12Resource>         spBackBuffer;
        m_spSwapChain->GetBuffer(backBufferIndex, IID_PPV_ARGS(&spBackBuffer));

        // record and execute a command list referencing spBackBuffer
        m_spSwapChain->Present1(0, 0);

Creating swap chains

When using the CreateSwapChainForHwnd, CreateSwapChainForCoreWindow, or CreateSwapChainForComposition calls, note that the pDevice parameter actually requires a pointer to a direct command queue in Direct3D 12, and not a device.


DirectX advanced learning video tutorials : Unthrottled Framerate