Variable Refresh Rate (VRR) in DirectX and DXGI

Variable Refresh Rate (VRR) is a display technology that synchronizes a monitor's refresh rate to the GPU's rendering speed, eliminating screen tearing and reducing input latency without the stutter of traditional VSync. In the Windows ecosystem, developers implement VRR for modern applications through the DirectX Graphics Infrastructure (DXGI) and Direct3D. This article explores how VRR functions and details the programmatic steps required to enable it using modern DXGI swap chains.

What is Variable Refresh Rate (VRR)?

Traditionally, displays refresh at a static rate, such as 60Hz, 120Hz, or 144Hz. If the GPU renders frames faster or slower than this fixed cycle, artifacts occur:

  • Tearing: When the GPU pushes a new frame in the middle of a monitor refresh cycle.
  • Stuttering: When VSync is enabled and the GPU fails to meet the fixed refresh window, forcing the display to repeat the previous frame.

VRR technologies—including NVIDIA G-Sync, AMD FreeSync, and VESA Adaptive-Sync—allow the display to adjust its refresh cycle on the fly to match the GPU's frame generation. The display only refreshes when a new frame is ready to be shown.

The Role of DirectX and DXGI

Historically, VRR was limited to exclusive fullscreen applications. With the evolution of the Windows Display Driver Model (WDDM) and DXGI, VRR can now function across borderless windowed and windowed modes.

DXGI acts as the bridge between Direct3D (DirectX 11 or DirectX 12) and the graphics driver. It governs the swap chain—the collection of buffers used to render and display visual frames. To make VRR work without exclusive fullscreen control, DXGI relies on tearing flags and the Flip presentation model.

How to Enable VRR Through DXGI

Enabling VRR in a DirectX application requires using DXGI 1.5 or newer to implement "tearing support." This informs the operating system and graphics driver that the application can bypass standard VSync behavior in windowed mode, enabling VRR.

1. Adopt the Flip Presentation Model

Legacy swap effects (like DXGI_SWAP_EFFECT_DISCARD) copy buffers through the Desktop Window Manager (DWM), which enforces standard composition and prevents VRR. You must use the modern Flip Model:

  • DXGI_SWAP_EFFECT_FLIP_DISCARD (recommended for Direct3D 12 and modern Direct3D 11)
  • DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL

2. Query for Tearing Support

Before requesting VRR, the application must query the hardware and OS to confirm whether tearing (unlocked presentation) is supported. This is done using IDXGIFactory5:

BOOL allowTearing = FALSE;
ComPtr<IDXGIFactory5> factory5;
if (SUCCEEDED(factory.As(&factory5))) {
    factory5->CheckFeatureSupport(
        DXGI_FEATURE_PRESENT_ALLOW_TEARING, 
        &allowTearing, 
        sizeof(allowTearing)
    );
}

3. Create the Swap Chain with the Tearing Flag

When defining the DXGI_SWAP_CHAIN_DESC1, include the DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING flag if allowTearing returns true:

DXGI_SWAP_CHAIN_DESC1 desc = {};
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
desc.Flags = allowTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
// Configure format, width, height, and buffer count...

4. Present Frames Using the Tearing Flag

To allow the display to synchronize dynamically to the application's render rate, the present call must disable VSync by using a sync interval of 0 and passing the DXGI_PRESENT_ALLOW_TEARING flag:

UINT presentFlags = (allowTearing && !vsyncEnabled) ? DXGI_PRESENT_ALLOW_TEARING : 0;
swapChain->Present(0, presentFlags);

When DXGI_PRESENT_ALLOW_TEARING is passed with a sync interval of 0, the DWM suspends its fixed-rate composition for the window. If the display supports G-Sync, FreeSync, or Adaptive-Sync, it will seamlessly scale its refresh rate to the timing of your Present calls.

System Requirements for DXGI VRR

For the swap chain implementation to activate VRR successfully:

  • The user must have a VRR-capable monitor and compatible GPU drivers (NVIDIA, AMD, or Intel).
  • Windows 10 (Version 1709 or newer) or Windows 11 must be installed.
  • Variable Refresh Rate or "Hardware-accelerated GPU scheduling" must be enabled in Windows Graphics Settings for windowed applications to automatically utilize these features.