我目前面临 DXGI 交换链 (DirectX 11) 的问题。我的 C++ 应用程序显示(实时)视频,我的目标是最大限度地减少延迟。我没有要处理的用户输入。
DXGI_SWAP_EFFECT_FLIP_DISCARD
交换链(我之前使用过 BitBlt - 请参阅为了获得最佳性能,请使用 DXGI 翻转模型 了解更多详细信息)。我使用以下标志:
//Swapchain Init:
sc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
sc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT | DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
//Present:
m_pDXGISwapChain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
在一台计算机上,交换链(窗口)进入“硬件:独立翻转”模式,只要我前面没有其他窗口,我就有非常低的延迟。在我尝试过的所有其他计算机上,我陷入了“组合:翻转”模式,延迟较高(约 25-30 毫秒以上)。软件(二进制)完全相同。我正在使用 PresentMon 检查这一点。
我发现有趣的是,在独立翻转模式工作的计算机上,它在没有 ALLOW_TEARING 标志的情况下也处于活动状态 - 据我了解,它们应该是必需的。顺便说一句,我在这种情况下也看到了撕裂,但这是一个不同的问题。
我已经尝试比较 Windows 10 版本、图形驱动程序和驱动程序设置。 GPU 是适用于所有系统的 Quadro RTX 4000。我无法发现系统之间有任何差异。
我真的很感激任何关于独立翻转模式的附加先决条件的提示,我可能在文档中错过了这些提示。感谢您的帮助!
更新1:我将“工作”系统从 Nvidia 驱动程序 511.09 更新到 473.47(最新稳定版)。之后我得到了与其他系统相同的行为(没有ind.flip)。回到511.09后又可以了。所以司机似乎有影响力。不过,在我最初的测试中,其他系统也有 511.09。
更新2:处理完所有DirectX调试输出后,它仍然无法按预期工作。我仅在真正的全屏模式或窗口模式下才设法进入独立翻转模式,其中窗口没有装饰并且实际上覆盖了整个屏幕。不幸的是,使用VS的图形工具我从未进入独立翻转,无法在这里做进一步的分析。但有趣的是,当使用图形工具调试时,PresentMon 显示组合翻转,但图形工具中的图形分析器仅显示 DISCARD 作为 SwapChain 的 SwapEffect。我本来期望 FLIP_DISCARD 因为我明确使用了 DXGI_SWAP_EFFECT_FLIP_DISCARD。
Composed: Flip
IS 也是翻转模型,所以你没有做任何特别错误的事情。
但是为了让 directflip 也参与并让您的应用程序驱动 DWM(正如您的文章中所述),普通非全屏窗口需要可用的多平面覆盖。这需要硬件(因此也需要驱动程序)支持。
自从 Skylake 发布以来,Intel 就应该有这个功能,AMD 不确定,而 nvidia 驱动程序应该在 461.09 中添加它(在 Turing+ GPU 上,你的就是)。
您从未提及您的特定 Windows 版本,但经过一番搜索后,我发现在绿卡上这是一个基本因素(就像监控位深度或使用 NIS 一样)。自从 2021 年推出以来,似乎在实施过程中出现了很多问题。所以我可以猜测您所看到的不同行为(希望在最新的驱动程序中得到解决)只是由于幕后的任何实验所致。
我敢打赌,如果您检查 dxdiag 扩展日志中的行
MPO MaxPlanes
,您的工作案例和非工作案例之间的情况会有所不同。
附注我认为您已经理解了 ALLOW_TEARING 的要点。这告诉翻转窗口它不必垂直同步(因此它需要翻转模式),反之亦然不是其启用的要求。