D3DPRESENTSTATS 结构

描述与 PresentEx 调用相关的交换链统计信息。

语法

typedef struct _D3DPRESENTSTATS {
  UINT          PresentCount;
  UINT          PresentRefreshCount;
  UINT          SyncRefreshCount;
  LARGE_INTEGER SyncQPCTime;
  LARGE_INTEGER SyncGPUTime;
} D3DPRESENTSTATS;

成员

PresentCount

类型: UINT

运行当前输出到屏幕的显示设备发出的成功演示调用计数。 此参数实际上是上一次 Present 调用的 Present ID,不一定是已进行的 Present 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 没有,则存在帧删除。)

应用程序可以通过采样 PresentCount 的任何两个实例和 GetPresentStats (来确定帧是否已删除,方法是在任意两个时间点调用 GetPresentStats API) 。 例如,以与监视器刷新速率相同的媒体应用程序 ((例如,监视器刷新速率为 60Hz),应用程序每隔 1/60 秒显示一个帧,) 希望呈现帧 A、B、C、D、E,每个帧对应于 PresentCount (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 是对应于帧 C) 的 3 (,则尚未删除任何帧。 如果第二个 PresentCount 为 3,对应于帧 D,则应用程序知道一个帧已被删除。

请注意,无论 FLIPEX 模式 PresentEx 调用的状态如何,都会在调用 GetPresentStatistics 后进行处理。

Windows Vista:当前调用将排队,然后在处理 GetPresentStats 调用之前进行处理。

当应用程序检测到某些帧的呈现落后时,它可以跳过这些帧并更正演示文稿以与 vblank 重新同步。 为此,应用程序根本无法呈现后期帧,并且无法在队列中的下一个正确帧开始呈现。 但是,如果应用程序已启动后期帧的呈现,则可以在名为 D3DPRESENT_FORCEIMMEDIATE 的 D3D9Ex 中使用新的 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. 呼叫演示。
  3. 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构。
  4. 将下一帧呈现到后缓冲区。
  5. 呼叫演示。
  6. 调用 GetPresentStats 并存储生成的 D3DPRESENTSTATS 结构。
  7. 比较两个存储的 D3DPRESENTSTATS 结构中的 SyncRefreshCount 的值。 如果差异大于一个,则跳过帧。

要求

要求 Value
标头
D3d9types.h

另请参阅

Direct3D 结构