使用 DxgkDdiSetInterruptTargetPresentId 禁用两阶段 VSync
如果 OS 对 DxgkDdiSetInterruptTargetPresentId 的调用在平面上设置一个 InterruptTargetPresentId,这将导致在此 VidPnSource 上完全禁用 VSync(即,此平面是使 VSync 保持启用的最后一个平面),并且如今此平面正在禁用 VSync,KMD 应禁用 VSync 中断,但在硬件启用(DXGK_VSYNC_DISABLE_KEEP_PHASE) 中保存 VSync 阶段。 在肯定时间段(通常相当于两个 VSync 周期)之后,OS 将使用 DXGK_VSYNC_DISABLE_NO_PHASE 调用 DxgkDdiControlInterruptXxx。 此调用可确保 KMD 有机会禁用 VSync 阶段和 VSync 时钟,以节省最大功率并维护与非硬件翻转队列体系的性能奇偶校验。
排队翻转取消
在全屏状态转换或应用步伐退出等情况下,大概需要取消将来排队翻转。 为了处理这些情况,引入了以下驱动步伐回调和相干结构:
- DXGKDDI_CANCELFLIPS
- DXGKARG_CANCELFLIPS
- DXGK_CANCELFLIPS_PLANE
KMD 在 DRIVER_INITIALIZATION_DATA 中提供一个指向其 DxgkDdiCancelFlips 函数的指针。
OS 指定在调用 DxgkDdiCancelFlips 时要取消的排队翻转范围,KMD 向 OS 报告它能够同步取消的翻转范围。
以下示例说明了在单个平面上翻转取消的机制和同步案例。 OS 在 Windows 11 版本 22H2 中不支持异步取消。想象一下,以下翻转正在排队到硬件翻转队列:
- PresentId N
- time t0 PresentId N+1
- time t1 PresentId N+2
- time t2 PresentId N+3
- time t3 PresentId N+4
- time t4
然后,OS 决定取消翻转 N+2、N+3 和 N+4,因此它调用 DxgkDdiCancelFlips,并将 PresentIdCancelRequested 设置为 N+2。
当 KMD 检查硬件翻转队列状态时,它会确定:
- 翻转 N+2 已发送到显示硬件,无法在呼叫时取消。
- 可以同步从硬件翻转队列中删除 N+3 和 N+4,而不会产生副作用。
因此,KMD 将 PresentIdCancelled 设置为 N+3 ,并照常完成 N+2 。
OS 将 N+3 和 N+4 标记为已取消,它将 N、N+1、N+2 视为正在飞行。 引发下一个 VSync 中断时,翻转队列日志将像往常一样指示 N、N+1、N+2 时间戳。
同步取消的翻转的范围必须是一连的,如果不是零,则假定包罗提交到 KMD 的最后一个当前 ID。 换言之,在两个同步取消翻转范围内都不能有间隙。
取消多个平面上的互锁翻转
通过调用具有多个平面和 PresentId 的 DxgkDdiSetVidPnSourceAddress 来提交互锁翻转。 OS 和 KMD 之间的协定如下:
- 这组平面必须在同一个 VSync 中可见。
- 不允许显示硬件仅在一个 VSync 上显示这些平面的子集,而在下一个 VSync 上显示其余平面。
在硬件翻转队列模子中,通过在对 DxgkDdiCancelFlips 的调用中通报多个平面和 PresentId 来取消这种互锁翻转。 在这种情况下通报的平面集必须与挂起的互锁翻转哀求相对应,并且 KMD 关于全部互锁 PresentId 的决定必须相同:
DxgkDdiCancelFlips 在设备中断级别 (DIRQL) 调用,以便与 DxgkDdiSetVidPnSourceAddress 和 VSync 中断同步。
获取排队翻转的当前统计信息
由于硬件翻转队列方法是为了克制在每个 VSync 上唤醒 CPU,因此需要有一种机制来保存最后几个排队翻转的帧显示时间。
支持硬件翻转队列的图形驱动步伐必须为每个运动 VidPnSource 的给定 MPO 平面将信息写入 OS 提供的翻转队列日志缓冲区或取消的翻转。
OS 包管提供翻转队列日志指针(在调用 DxgkDdiSetFlipQueueLogBuffer)之前,第一个 DxgkDdiSetVidPnSourceAddress 调用每个运动 VidPnSource 的给定 MPO 平面。 当翻转队列没有任何未完成的哀求时,允许 OS 烧毁翻转队列日志缓冲区。 在这种情况下,它将在下一个 DxgkDdiSetVidPnSourceAddress 调用之前提供新的日志指针。 翻转队列日志是循环的。 写入 [NumberOfEntries-1] 条目后,下一个日志条目为 [0]。
在一批排队的翻转完成后,KMD 必须包管已完成翻转的翻转队列日志在这两个时间点中的最早更新:
- 一个用于需要引发中断的翻转的 VSync 中断处理步伐。
- 相应来自 OS 的显式 DxgkDdiUpdateFlipQueueLog 哀求。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |