D3DPRESENTSTATS 结构
介绍与 PresentEx 调用相关的交换链统计信息。
语法
typedef struct _D3DPRESENTSTATS {
UINT PresentCount;
UINT PresentRefreshCount;
UINT SyncRefreshCount;
LARGE_INTEGER SyncQPCTime;
LARGE_INTEGER SyncGPUTime;
} D3DPRESENTSTATS;
成员
-
PresentCount
-
类型: UINT
-
当前输出到屏幕的显示设备发出的成功演示调用的运行计数。 此参数实际上是上一次 Present 调用的 Present ID,不一定是当前 API 调用的总数。
-
PresentRefreshCount
-
类型: UINT
-
屏幕上显示最后一个 Present 的 vblank 计数,vblank 计数每 vblank 间隔递增一次。
-
SyncRefreshCount
-
类型: UINT
-
计划程序上次通过调用 QueryPerformanceCounter 对计算机时间进行采样时的 vblank 计数。
-
SyncQPCTime
-
类型: LARGE_INTEGER
-
计划程序的最后一次采样计算机时间,通过调用 QueryPerformanceCounter 获取。
-
SyncGPUTime
-
类型: LARGE_INTEGER
-
不使用此值。
备注
当 9Ex 应用程序采用翻转模式 (D3DSWAPEFFECT_FLIPEX) 时,应用程序可以通过在任意时间点调用 GetPresentStatistics 来检测帧掉落。 实际上,他们可以执行以下操作。
- 呈现到后台缓冲区
- 呼叫演示
- 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构
- 将下一帧呈现到后台缓冲区
- 呼叫演示
- 重复步骤 4 和 5 一次或多次
- 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构
- 比较两个存储的 D3DPRESENTSTATS 结构中的 PresentRefreshCount 的值。 应用程序可以根据 PresentRefreshCount 增量和帧呈现的 PresentCount 分配的假设,计算特定 PresentCount 参数的相应 PresentRefreshCount。 如果上次采样的 PresentRefreshCount 与 PresentCount (即如果 PresentRefreshCount 已递增,但 PresentCount 没有递增,则存在帧删除)
应用程序可以通过在) 的任何两个时间点调用 GetPresentStats API,对 PresentCount 和 GetPresentStats (的任何两个实例进行采样来确定是否删除了帧。 例如,以与监视器刷新率相同的速率呈现的媒体应用程序 (监视器刷新速率为 60Hz,应用程序每隔 1/60 秒呈现一个帧,) 想要呈现帧 A、B、C、D、E,每个帧对应于 present ID (PresentCount) 1、2、3、7、8。
应用程序代码如下所示。
- 将帧 A 呈现到后台缓冲区
- 调用 Present,PresentCount = 1
- 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构
- 分别呈现接下来的 4 帧,B、C、D、E
- 调用 Present 4 次,PresentCounts 分别 = 2、3、7、8
- 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构
- 比较两个存储的 D3DPRESENTSTATS 结构中的 PresentRefreshCount 的值。 如果差值为 2,即两个 GetPresentStats API 调用之间已过 2 个 vblank 间隔,则最后显示的帧应为帧 C。由于应用程序 (监视器) 刷新率提供一次非常 vblank 间隔,因此显示帧 A 到显示帧 C 之间的时间应为 2 vblank。
- 比较两个存储的 D3DPRESENTSTATS 结构中的 PresentCount 的值。 如果第一个 PresentCount 为 1 (对应于帧 A) ,第二个 PresentCount 为 3 (对应于帧 C) ,则未删除任何帧。 如果第二个 PresentCount 为 3(对应于帧 D),则应用程序知道已删除一个帧。
请注意,无论 FLIPEX 模式 PresentEx 调用的状态如何,都将在调用 GetPresentStatistics 后进行处理。
Windows Vista: Present 调用将排队,然后在处理 GetPresentStats 调用之前进行处理。
当应用程序检测到某些帧的呈现落后时,它可以跳过这些帧并更正演示文稿以重新与 vblank 同步。 为此,应用程序根本无法呈现后期帧,并开始使用队列中的下一个正确帧进行渲染。 但是,如果应用程序已经开始呈现后期帧,则可以在 D3D9Ex 中使用名为 D3DPRESENT_FORCEIMMEDIATE 的新 Present 参数。 标志将在 Present API 调用的参数中传递,并指示运行时将在下一个 vblank 间隔内立即处理该帧,实际上在屏幕上根本不可见。 下面是上一个示例中最后一步之后的应用程序使用示例。
- 将下一帧呈现到后台缓冲区
- 从 PresentRefreshCount 发现下一帧已晚
- 将“演示间隔”设置为“D3DPRESENT_FORCEIMMEDIATE
- 在下一帧上调用“演示”
应用程序可以以相同的方式同步视频和音频流,因为 GetPresentStatistics 的行为在该方案中不会更改。
D3D9Ex 翻转模式为窗口应用程序和全屏 9Ex 应用程序提供帧统计信息。
Windows Vista: 使用 DWM API 检索现有统计信息。
关闭桌面窗口管理器后,使用翻转模式的窗口模式 9Ex 应用程序将收到准确性有限的统计信息。
Windows Vista:
如果应用程序速度不够快,无法跟上监视器的刷新速率,可能是由于硬件速度缓慢或系统资源不足,则应用程序可能会遇到图形故障。 故障是所谓的视觉打盹。 如果将监视器设置为以 60 Hz 刷新,并且应用程序只能管理 30 fps,则一半的帧会出现故障。
应用程序可以通过跟踪 SynchRefreshCount 来检测故障。 例如,应用程序可能会执行以下操作序列。
- 呈现到后台缓冲区。
- 调用 Present。
- 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构。
- 将下一帧呈现到后台缓冲区。
- 调用 Present。
- 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构。
- 比较两个存储的 D3DPRESENTSTATS 结构的 SyncRefreshCount 的值。 如果差异大于 1,则跳过帧。
要求
要求 | 值 |
---|---|
标头 |
|
另请参阅