Windows 图形显示驱动开发-WDDM 3.2-用户模式工作提交(二)

用户模式工作提交 API

添加了以下用户模式 API,以支持用户模式工作提交。

  • D3DKMTCreateDoorbell 为 D3D HWQueue 创建一个Ring,用于用户模式工作提交。
  • D3DKMTConnectDoorbell 将先前创建的Ring连接到 D3D HWQueue,用于用户模式工作提交。
  • D3DKMTDestroyDoorbell 销毁先前创建的Ring。
  • D3DKMTNotifyWorkSubmission 通知 KMD 在 HWQueue 上提交了新工作。 此功能的重点是一个低延迟的工作提交路径,其中 KMD 不参与或不知道何时提交工作。 当在 HWQueue 上提交工作时需要通知 KMD 的情况下,此 API 非常有用。 驱动程序应在特定且不常见的方案中使用此机制,因为它涉及到每次提交工作时从 UMD 到 KMD 的往返,从而违背了低延迟用户模式提交模型的目的。
Ring内存和环形缓冲区分配的驻留模型

UMD 负责在创建Ring之前使环形缓冲区和环形缓冲区控制分配驻留。

  • UMD 管理环形缓冲区的生命周期和环形缓冲区控制分配。 即使相应的Ring被销毁,Dxgkrnl 也不会隐式地销毁这些分配。 UMD 负责分配和销毁这些分配。 但是,为了防止恶意用户模式程序在Ring处于活动状态时销毁这些分配,Dxgkrnl 确实会在Ring的生命周期内对这些分配进行引用。
  • Dxgkrnl 销毁环形缓冲区分配的唯一方案是在设备终止期间。 Dxgkrnl 销毁与设备关联的所有 HWQueue、Ring和环形缓冲区分配。
  • 只要环形缓冲区分配处于活动状态,环形缓冲区 CPUVA 始终有效,并且可供 UMD 访问,而与Ring连接状态无关。 也就是说,环形缓冲区驻留与Ring无关。
  • 当 KMD 进行 DXG 回调以断开Ring时(即,调用状态为 D3DDDI_DOORBELL_STATUS_DISCONNECTED_RETRY 的 DxgkCbDisconnectDoorbell),Dxgkrnl 将Ring CPUVA 旋转到一个虚拟页面。 它不会收回或取消映射环形缓冲区分配。
  • 在任何设备丢失的情况下(TDR/GPU 停止/分页等),Dxgkrnl 会断开Ring并将状态标记为 D3DDDI_DOORBELL_STATUS_DISCONNECTED_ABORT。 用户模式负责销毁 HWQueue、Ring、环形缓冲区并重新创建它们。 此要求类似于在此方案中销毁和重新创建其他设备资源的方式。
硬件上下文挂起

当 OS 挂起硬件上下文时,Dxgkrnl 会保持Ring连接处于活动状态,并常驻环形缓冲区(工作队列)分配。 通过这种方式,UMD 可以继续排队工作到上下文;当上下文被挂起时,这项工作不会被安排。 一旦上下文被恢复和计划,GPU 的上下文管理处理器 (CMP) 就会观察新的写入指针和工作提交。

此逻辑类似于当前的内核模式提交逻辑,其中 UMD 可以使用挂起的上下文调用 D3DKMTSubmitCommand。 Dxgkrnl 将这个新命令排队到 HwQueue,但直到以后才能被安排。在硬件上下文挂起和恢复期间,会发生以下事件序列。

挂起硬件上下文:

Dxgkrnl 调用 DxgkddiSuspendContext。

KMD 从 HW 计划程序列表中删除上下文的所有 HWQueue。
Ring仍处于连接状态,环形缓冲区/环形缓冲区控制分配仍处于驻留状态。 UMD 可以将新命令写入此上下文的 HWQueue,但 GPU 不会处理它们,这类似于当前内核模式命令提交到挂起的上下文。

如果 KMD 选择破坏挂起的 HWQueue 的Ring,则 UMD 将断开其连接。 UMD 可以尝试重新连接Ring,KMD 将为该队列分配一个新的Ring。 其目的不是使 UMD 停滞,而是允许它继续提交工作;一旦上下文恢复,HW 引擎最终可以处理这些工作。

恢复硬件上下文:
Dxgkrnl 调用 DxgkddiResumeContext。
KMD 将上下文的所有 HWQueue 添加到 HW 计划程序的列表。

引擎 F 状态转换

在传统的内核模式工作提交中,Dxgkrnl 负责向 HWQueue 提交新命令,并监视来自 KMD 的完成中断。 因此,Dxgkrnl 可以完整地了解引擎何时处于活动状态和空闲状态。

在用户模式工作提交中,Dxgkrnl 使用 TDR 超时节奏监视 GPU 引擎是否正在进行。因此,如果值得在两秒的 TDR 超时时间之前启动到 F1 状态的转换,KMD 可以请求 OS 执行此操作。

为了促进这一做法,作出了以下改动:

DXGK_INTERRUPT_GPU_ENGINE_STATE_CHANGE 中断类型被添加到 DXGK_INTERRUPT_TYPE。 KMD 使用此中断通知 Dxgkrnl 引擎状态转换,这些转换需要 GPU 电源操作或超时恢复,例如 Active -> TransitionToF1 和 Active -> Hung。

EngineStateChange 中断数据结构被添加到 DXGKARGCB_NOTIFY_INTERRUPT_DATA。

添加了 DXGK_ENGINE_STATE 枚举来表示 EngineStateChange 的引擎状态转换。

当 KMD 引发 DXGK_INTERRUPT_GPU_ENGINE_STATE_CHANGE 中断时,EngineStateChange.NewState 设置为 DXGK_ENGINE_STATE_TRANSITION_TO_F1,Dxgkrnl 会断开此引擎上 HWQueue 的所有Ring的连接,然后启动 F0 到 F1 电源组件转换。

当 UMD 试图在 F1 状态下向 GPU 引擎提交新工作时,需要重新连接Ring,这反过来又会导致 Dxgkrnl 启动转换回 F0 电源状态。

引擎 D 状态转换

在 D0 到 D3 设备电源状态转换期间,Dxgkrnl 挂起 HWQueue,断开Ring(将Ring CPUVA 旋转到虚拟页面),并将 DoorbellStatusCpuVirtualAddress Ring状态更新为 D3DDDI_DOORBELL_STATUS_DISCONNECTED_RETRY。

如果 UMD 在 GPU 处于 D3 时调用 D3DKMTConnectDoorbell,则会强制 Dxgkrnl 将 GPU 唤醒到 D0。 Dxgkrnl 还负责恢复 HWQueue,并将Ring CPUVA 旋转到物理Ring位置。

事件发生的顺序如下。

  • 发生 D0 到 D3 GPU 断电:
  • 对于 GPU 上的所有 HW 上下文,Dxgkrnl 调用 DxgkddiSuspendContext。 KMD 从 HW 计划程序列表中删除这些上下文。
  • Dxgkrnl 断开所有Ring的连接。
  • 如有必要,Dxgkrnl 可能会从 VRAM 中逐出所有环形缓冲区/环形缓冲区控制分配。 一旦所有上下文都被挂起并从硬件计划程序的列表中删除,硬件就不会引用任何被逐出的内存。
  • 当 GPU 处于 D3 状态时,UMD 会将新命令写入 HWQueue:
  • UMD 看到Ring已断开连接,因此调用 D3DKMTConnectDoorbell。
  • Dxgkrnl 启动 D0 转换。
  • Dxgkrnl 使所有环形缓冲区/环形缓冲区控制分配都驻留(如果它们被逐出)。
  • Dxgkrnl 调用 KMD 的 DxgkddiCreateDoorbell 函数,以请求 KMD 为此 HWQueue 建立Ring连接。
  • Dxgkrnl 为所有 HWContext 调用 DxgkddiResumeContext。 KMD 将相应的队列添加到 HW 计划程序列表。
相关推荐
染指11101 小时前
35.x64汇编写法(二)
汇编·windows·x64游戏·x64汇编·游戏攻防
新兴AI民工2 小时前
windows上的visual studio2022的项目使用jenkins自动打包
windows·jenkins·visual studio
WarPigs2 小时前
Visual Studio问题记录
ide·windows·visual studio
love530love3 小时前
【笔记】旧版MSYS2 环境中 Rust 升级问题及解决过程
开发语言·人工智能·windows·笔记·python·rust·virtualenv
Java Fans5 小时前
如何在Windows本机安装Python并确保与Python.NET兼容
开发语言·windows·python
Abigail_chow16 小时前
EXCEL如何快速批量给两字姓名中间加空格
windows·microsoft·excel·学习方法·政务
love530love17 小时前
【笔记】在 MSYS2(MINGW64)中正确安装 Rust
运维·开发语言·人工智能·windows·笔记·python·rust
代码搬运媛19 小时前
“packageManager“: “[email protected]“ 配置如何正确启动项目?
windows·webpack
小道士写程序19 小时前
Qt 5.12 上读取 .xlsx 文件(Windows 平台)
开发语言·windows·qt
异常君1 天前
Windows 与 Linux 虚拟内存机制对比:设计理念与实现差异
java·linux·windows