当前位置: 首页 > article >正文

Windows 图形显示驱动开发-WDDM 3.0功能- 硬件翻转队列(四)

使用 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 请求。

http://www.kler.cn/a/592402.html

相关文章:

  • K-均值聚类
  • Python 实现高效的实体扩展算法
  • 正点原子[第三期]Arm(iMX6U)Linux移植学习笔记-6.2uboot启动流程-lowlevel_init,s_init,_main函数执行
  • Windows 11右键菜单栏如何修改为Windows 10风格【完整教程】以及如何恢复Win11菜单栏风格
  • 技术改变生活:探索新科技的力量与影响
  • element-plus中Dropdown下拉菜单组件的使用
  • 论文解读:含可靠置信度的视频超分辨显微成像(频域卷积+贝叶斯深度学习)
  • vscode 配置服务器远程连接
  • 构建下一代AI Agent:自动化开发与行业落地全解析
  • langgraph简单Demo(使用langserve实现外部调用)
  • 该错误是由于`KuhnMunkres`类未定义`history`属性导致的
  • 记一次服务器中木马导致cpu占用高的问题
  • scrollIntoView 的behavior都有哪些属性
  • 知识蒸馏:从软标签压缩到推理能力迁移的工程实践(基于教师-学生模型的高效压缩技术与DeepSeek合成数据创新) (1)
  • 机器学习和深度学习中参数概览
  • 基于Python+Django的二手房信息管理系统
  • 替代Qt中信号与槽的完整例子。
  • 【NeurIPS 2021】Autoformer、源码论文对照(下)
  • Dear ImGui for Unity 常见问题解决方案
  • C++ 头文件说明