增强现实/虚拟现实

高级 API 性能:交换链

 

交换链是如何将渲染数据输出到屏幕的不可或缺的一部分。它们通常由一组输出就绪型缓冲区组成,每个缓冲区都可以旋转渲染为一个缓冲区。在渲染到交换链的某个缓冲区的同时,交换链中的其他缓冲区通常被读取以进行显示输出。

本文介绍了在 NVIDIA GPU 上使用交换链时的最佳实践。要在您的应用中获得稳定的高帧率,请参阅我们的高级 API 性能提示

在寻求提高渲染性能时,通常会专注于渲染管线中更频繁优化的部分。但是,交换链通常会被忽略,从而将潜在性能和延迟放在桌面上。

以下建议和注意事项可让您更深入地了解确保最佳交换链性能的最佳方法。

推荐

  • 使用翻转模式交换链。这对于利用多平面叠加支持尤为重要,因为在窗口模式下运行时,多平面叠加支持可提供全屏性能和延迟。
  • 使用SetFullScreenState(TRUE)(无边框)全屏窗口和非窗口翻转模型交换链,可切换到真正的即时独立翻转模式。
    • 这是唯一支持无限帧速率的模式,在调用 Direct 3D 12 时,该模式会导致 Direct 3D 12 出现撕裂,Present(0,0).
    • 如需为支持可变刷新率的显示器提供适当的无限帧率支持,您还必须使用DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING交换链标志,以及DXGI_PRESENT_ALLOW_TEARING Present标志
  • 使用DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH会有意识地显示出来。
    • 如果窗口大小与当前屏幕分辨率相匹配,则无需使用该标志即可实现无限帧率(请参阅前面的注释)
    • 如果设置了此标志,请尝试使用 ResizeTarget 更改分辨率,然后再调用SetFullScreenState(TRUE)工作正常,帧速率将无限
    • 如果未设置此标志,请尝试使用ResizeTarget然后再调用SetFullScreenState(TRUE)不会导致显示分辨率发生变化。您的目标已扩展到当前分辨率,且帧率受限。
  • 如果不处于全屏状态(真正的即时独立翻转模式),请仔细控制交换链中的延迟和缓冲区数量,以获得所需的帧速率和延迟。
    • 使用IDXGISwapChain2::SetMaximumFrameLatency(MaxLatency)来设置所需的延迟,MaxLatency是一定数量的帧(按队列中的帧数计算)Present调用)。
    • 要做到这一点,您必须使用DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT设置的标志。
    • DXGI 开始阻塞Present在您拥有MaxLatency当前调用的数量。
    • 在此窗口状态下,同步间隔为 0Presentcall 可确保所呈现的帧是可供下次进行桌面合成时使用的最新帧(将窗口渲染的帧与桌面的其余部分结合使用),并且丢弃之前完成的所有帧,转而使用最新的帧。在合成发生之前不会显示任何渲染帧,这发生在VSYNC时间。这个最新完成的帧是所显示的
  • 使用的交换链缓冲区比打算排队的最大帧数多约 1-2 倍(就命令分配器、动态数据和关联的帧围栏而言)。通过将最大帧延迟设置为交换链缓冲区的这个数量,IDXGISwapChain2::SetMaximumFrameLatency(MaxLatency).
    • 这可确保您可以从应用程序逻辑中以最佳方式明确限制队列中的帧和延迟,而不是依靠操作系统在意外的时间阻止或阻止它。

不推荐

  • 忘记了这一点,默认情况下,在 DXGI 开始阻塞之前,每个交换链限制为三个排队帧Present.这意味着,如果当前有三个 Present 调用,它将在第四次 Present 调用中阻塞Present呼叫排队。
    • 设置DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT交换链创建和使用的标志IDXGISwapChain2::SetMaximumFrameLatency来修改此默认值,
  • 忘记通话ResizeBuffers切换到真正的即时独立翻转模式后,SetFullScreenState(TRUE).

致谢

感谢 Cody Robson、Kumaresan Gnanasekaran、Adrian Muntianu 和 Meenal Nachnani 提供的建议和帮助。

 

Tags