显示变量刷新频率

可变刷新率显示需要启用 撕裂 ,这也称为“vsync-off”支持。

可变刷新率显示/Vsync off

通过在创建和显示交换链时设置某些标志来实现对可变刷新率显示的支持。

若要使用此功能,应用用户需要在安装了 KB3156421 或周年更新Windows 10系统上。 此功能适用于所有使用 DXGI_SWAP_EFFECT_FLIP_* 交换效果的 Direct3D 11 和 12 版本。

若要向应用添加 vsync-off 支持,可以参考 Direct3D 12、 D3D12Fullscreen 的完整运行示例 (请参阅 工作示例) 。 示例代码中还有一些未明确指出的要点,但需要注意。

  • ResizeBuffers (或 ResizeBuffers1) 必须具有与 Present (或 Present1) 相同的交换链创建标志 (DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) 传递给它。
  • DXGI_PRESENT_ALLOW_TEARING只能与同步间隔 0 一起使用。 如果 CheckFeatureSupport 报告支持撕裂且应用处于窗口模式(包括无边框全屏模式)时,建议在使用同步间隔 0 时始终传递此撕裂标志。 有关更多详细信息,请参阅 DXGI_PRESENT 常量。
  • 禁用 vsync 不一定会取消帧速率的限制:开发人员还需要确保 “演示 ”调用不受其他计时事件 ((例如 CompositionTarget::Rendering 基于 XAML 的应用) 中的事件)的限制。

下面的代码回顾了需要添加到应用的一些关键部分。

//--------------------------------------------------------------------------------------------------------
// Check Tearing Support
//--------------------------------------------------------------------------------------------------------

// Determines whether tearing support is available for fullscreen borderless windows.

void DXSample::CheckTearingSupport()
{
// Rather than create the 1.5 factory interface directly, we create the 1.4
// interface and query for the 1.5 interface. This will enable the graphics
// debugging tools which might not support the 1.5 factory interface.

    ComPtr<IDXGIFactory4> factory4;
    HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&factory4));
    BOOL allowTearing = FALSE;
    if (SUCCEEDED(hr))
    { 
        ComPtr<IDXGIFactory5> factory5;
        hr = factory4.As(&factory5);
        if (SUCCEEDED(hr))
        {
            hr = factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing));
        }
    }
    m_tearingSupport = SUCCEEDED(hr) && allowTearing;
}

//--------------------------------------------------------------------------------------------------------
// Set up swapchain properly
//--------------------------------------------------------------------------------------------------------

// It is recommended to always use the tearing flag when it is supported.
swapChainDesc.Flags = m_tearingSupport ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;

//--------------------------------------------------------------------------------------------------------
// Present
//--------------------------------------------------------------------------------------------------------

UINT presentFlags = (m_tearingSupport && m_windowedMode) ? DXGI_PRESENT_ALLOW_TEARING : 0;

// Present the frame.
ThrowIfFailed(m_swapChain->Present(0, presentFlags));

DXGI 1.5 改进

DXGI 编程指南