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 来检测帧掉落。 实际上,他们可以执行以下操作。

  1. 呈现到后台缓冲区
  2. 呼叫演示
  3. 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构
  4. 将下一帧呈现到后台缓冲区
  5. 呼叫演示
  6. 重复步骤 4 和 5 一次或多次
  7. 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构
  8. 比较两个存储的 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。

应用程序代码如下所示。

  1. 将帧 A 呈现到后台缓冲区
  2. 调用 Present,PresentCount = 1
  3. 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构
  4. 分别呈现接下来的 4 帧,B、C、D、E
  5. 调用 Present 4 次,PresentCounts 分别 = 2、3、7、8
  6. 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构
  7. 比较两个存储的 D3DPRESENTSTATS 结构中的 PresentRefreshCount 的值。 如果差值为 2,即两个 GetPresentStats API 调用之间已过 2 个 vblank 间隔,则最后显示的帧应为帧 C。由于应用程序 (监视器) 刷新率提供一次非常 vblank 间隔,因此显示帧 A 到显示帧 C 之间的时间应为 2 vblank。
  8. 比较两个存储的 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 间隔内立即处理该帧,实际上在屏幕上根本不可见。 下面是上一个示例中最后一步之后的应用程序使用示例。

  1. 将下一帧呈现到后台缓冲区
  2. 从 PresentRefreshCount 发现下一帧已晚
  3. 将“演示间隔”设置为“D3DPRESENT_FORCEIMMEDIATE
  4. 在下一帧上调用“演示”

应用程序可以以相同的方式同步视频和音频流,因为 GetPresentStatistics 的行为在该方案中不会更改。

D3D9Ex 翻转模式为窗口应用程序和全屏 9Ex 应用程序提供帧统计信息。

Windows Vista: 使用 DWM API 检索现有统计信息。

关闭桌面窗口管理器后,使用翻转模式的窗口模式 9Ex 应用程序将收到准确性有限的统计信息。

Windows Vista:

如果应用程序速度不够快,无法跟上监视器的刷新速率,可能是由于硬件速度缓慢或系统资源不足,则应用程序可能会遇到图形故障。 故障是所谓的视觉打盹。 如果将监视器设置为以 60 Hz 刷新,并且应用程序只能管理 30 fps,则一半的帧会出现故障。

应用程序可以通过跟踪 SynchRefreshCount 来检测故障。 例如,应用程序可能会执行以下操作序列。

  1. 呈现到后台缓冲区。
  2. 调用 Present。
  3. 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构。
  4. 将下一帧呈现到后台缓冲区。
  5. 调用 Present。
  6. 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构。
  7. 比较两个存储的 D3DPRESENTSTATS 结构的 SyncRefreshCount 的值。 如果差异大于 1,则跳过帧。

要求

要求
标头
D3d9types.h

另请参阅

Direct3D 结构