如果您的目标是 Windows Vista 或更高版本,则答案取决于您的应用程序运行的模式。
如果它是一个窗口应用程序(或窗口全屏),刷新率是根据用户设置和其他因素通过桌面窗口管理器 (DWM) 控制的。使用DwmGetCompositionTimingInfo并查看 DWM_TIMING_INFO::rateRefresh 以获取监视器刷新率。
如果应用程序是真正的全屏,那么您创建的全屏交换链会覆盖系统默认值。但是,您选择的刷新率 (DXGI_SWAP_CHAIN_FULLSCREEN_DESC::RefreshRate) 应该与显示器支持的刷新率之一匹配。您可以使用IDXGIOutput::GetDisplayModeList获取支持的刷新率列表。以下是如何执行此操作的示例:
UINT numModes = 0;
dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, NULL);
DXGI_MODE_DESC* modes = new DXGI_MODE_DESC[numModes];
dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, modes);
// see modes[i].RefreshRate
无论如何,如果你是三重缓冲的,你不应该看到故障。您应该尽可能快地呈现,操作系统会准时呈现。如果您将三重缓冲与自定义托管帧时序相结合,则可以保证您实际上不会获得三重缓冲,并且在 vblank 阶段出现漂移的任何时候都会出现故障(即使您有一个完美的值也会逐渐发生)刷新率)。如果您想坚持使用三重缓冲,只需尽可能快地呈现,让操作系统负责呈现时间。如果您使用自己的计时来驱动 Present()(例如,为了获得低延迟响应),您应该在另一个线程上调用IDXGIOutput::WaitForVBlank以帮助同步帧计时。如果你最终这样做,你也应该使用IDXGISwapChain::GetFrameStatistics以确保您从任何虚假故障中恢复,否则您最终会落后一帧。
祝你好运!