DirectX9:present() 和实际屏幕更新之间的延迟

DirectX9: delay between present() and actual screen update

我的问题是关于在 DirectX9 中调用当前方法和屏幕上出现更新之间的延迟。

在 Windows 系统上,我使用 DirectX9 打开了一个 window 并以简单的方式更新它(更改整个 window 的颜色,然后调用 IDirect3DSwapChain9 的 present方法)。我在垂直空白间隔期间使用标志 D3DPRESENT_DONOTWAIT 调用交换链的 present 方法。只有一个缓冲区与交换链相关联。 我还通过连接到屏幕中央的光电二极管获得外部测量值,了解我使用的 CRT 屏幕何时实际改变颜色。我以亚毫秒的精度和延迟获得了这个测量值。

我发现变化恰好出现在调用 present() 后的第三次刷新中。因此,当我在垂直空白的末尾调用 present() 时,就在屏幕刷新之前,更改将在调用 present 之后恰好 2*screen_duration + 0.5*refresh_duration 出现在屏幕上().

我的问题很笼统:

一个附加问题:

这里有很多变量在起作用,尤其是因为 DirectX 9 本身是遗留的并且在 Windows 的现代版本上有效地模拟了。

You might want to read Accurately Profiling Direct3D API Calls (Direct3D 9), although that article doesn't directly address presentation.

在 Windows Vista 或更高版本上,一旦您调用 Present 翻转前后缓冲区,它就会传递给桌面 Windows 管理器进行组合和最终显示。这里有很多因素在起作用,包括 GPU 供应商、驱动程序版本、OS 版本、Windows 设置、第 3 方驱动程序 'value add' 功能、full-screen 与窗口模式,等等

简而言之:您的里程可能会有所不同 (YMMV),所以不要指望您的计时会超出您的直接设置。

如果您的应用程序需要准确知道 present 发生的时间而不是更常见的 "best effort",我建议转向 DirectX9Ex、DirectX 11 或 DirectX 12 并利用 DXGI frame statistics .

以防有人遇到类似问题:我发现了我的屏幕更新恰好出现在调用 present() 后第三次刷新的原因。事实证明,Windows OS 默认情况下在呈现它们之前恰好排队 3 帧,因此更改会出现在第三次刷新时。就目前而言,这只能由以 Directx10(和 Directx9Ex)开头的应用程序 "fixed";对于 Directx9 和更早版本,必须使用显卡驱动程序或 Windows 注册表来减少这种排队。