Windows 图形显示驱动开发-WDDM 3.0功能- 从KMD发出CPU CPU 事件信号

从内核模式驱动程序发出 CPU 事件信号

在某些情况下,内核模式驱动程序 (KMD) 需要向 CPU 事件发出信号,以通知用户模式驱动程序 (UMD) 某些内容:例如:

当 KMD 检测到其某个对象处于错误状态并需要通知 UMD 时。
在 GPU 调试期间,KMD 需要与 UMD 通信,发生了某些事件。 对于具有 GPU 控制面板的 IHV,通过 KMD 向 CPU 事件发出信号允许 KMD 通知控制面板应用有关内部事件的信息。
通常,UMD 可以创建 CPU 事件,并将其 NT 句柄传递到转义专用数据中的 KMD。 此方法在 GPU 半虚拟化 (GPU-PV) 方案中不起作用,因为 NT 句柄不能跨虚拟机边界使用。

从 Windows 11 版本 21H2 (WDDM 3.0) 开始,WDDM API 已扩展,允许 UMD 创建可由 KMD 发出信号的 CPU 事件对象。 当 UMD 在主机上运行或使用 GPU-PV 在虚拟机中运行时,此功能都有效。

功能流

UMD 创建 CPU 事件。

  • UMD 使用 D3DDDI_CPU_NOTIFICATION 类型创建 GPU 同步对象。 在调用 D3DKMTCreateSynchronizationObject 时,通过设置 SignalByKmd 标志,使创建的对象对 KMD 可见。
  • Dxgkrnl 调用 DXGKDDI_CREATECPUEVENT ,以允许 KMD 创建自己的对象。
  • UMD 调用具有D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE已知转义类型的 D3DKMTEscape,以通知 KMD 同步对象的预期使用情况。
  • Dxgkrnl 调用 DXGKDDI_ESCAPE 将专用数据传递给 KMD。
  • 在某些时候,KMD 使用 CpuEventObject 标志调用DXGKCB_SIGNALEVENT,以向 CPU 事件对象发出信号。
  • UMD 调用 D3DKMTDestroySynchronizationObject 来销毁 CPU 事件对象。
  • Dxgkrnl 调用 DXGKDDI_DESTROYCPUEVENT 来销毁 CPU 事件对象。 在此 之后不应调用DXGKCB_SIGNALEVENT。

同步对象不能插入上下文队列。 它只能由 KMD 使用 DXGKCB_SIGNALEVENT发出信号。

用于处理 CPU 事件同步对象的用户模式 API

创建 KMD CPU 事件对象

KMD CPU 事件对象是使用以下项调用 D3D12DDICB_CREATESYNCHRONIZATIONOBJECT2 作为 GPU 同步对象创建的:

  • 类型 设置为 D3DDDI_CPU_NOTIFICATION。
  • 设置为SignalByKmd 的标志指定由 KMD 向对象发出信号。 仅当D3DDDI_CPU_NOTIFICATION D3DDDI_SYNCHRONIZATIONOBJECTINFO2的 Type 成员时,才能设置此标志。

设置 SignalByKmd 标志后,将调用 DXGKDDI_CREATECPUEVENT 以创建 KMD CPU 事件对象。 请注意,创建同步对象时必须指定设备句柄。

同步对象不能用于信号和等待 API (D3DKMTSignalSynchronizationObject、 D3DKMTWaitForSynchronizatioObject) 。 它只能由 KMD 发出信号,UMD 可以等待相应的 CPU 事件。

用于定义 KMD CPU 事件同步对象的用法的 UMD 转义

已知转义已添加到 D3DDDI_DRIVERESCAPETYPE。 D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE 用于通知 KMD 有关 KMD CPU 事件对象的预期使用情况。 已知转义通过设置 DXGKARG_ESCAPE::Flags.DriverKnownEscape = 1 来定义。 已知转义会从安全虚拟机发送到主机。

以下代码片段是一个用法示例。

D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE Command = {};
Command.EscapeType = D3DDDI_DRIVERESCAPETYPE_CPUEVENTUSAGE;
Command.hSyncObject = SyncObjectHandle;
Command.Usage[0] = 1;

D3DKMT_ESCAPE Args = {};
Args.hAdapter = AdapterHandle;
Args.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
Args.Flags.DriverKnownEscape = 1;
Args.Flags.NoAdapterSynchronization = 1; // Prevent waking up the device from D3
Args.pPrivateDriverData = &Command;
Args.PrivateDriverDataSize = sizeof(Command);

NTSTATUS Status = D3DKMTEscape(&Args);

Dxgkrnl 将使用以下项调用 DXGKDDI_ESCAPE :

  • hDevice 设置为用于创建同步对象的微型端口设备句柄
  • pPrivateDriverData 指向 D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE 结构
  • PrivateDriverDataSize 设置为 sizeof(D3DDDI_DRIVERESCAPE_CPUEVENTUSAGE)

创建和销毁 KMD CPU 事件对象

以下 DDI 用于创建和销毁 KMD CPU 事件同步对象:

  • DXGKDDI_CREATECPUEVENT
  • DXGKDDI_DESTROYCPUEVENT从 KMD 向 CPU 事件对象发出信号

 从 KMD 向 CPU 事件对象发出信号

为了向 CPU 事件 对象发出信号 ,KMD 在 IRQL <= DISPATCH_LEVEL 调用DXGKCB_SIGNALEVENT,并设置 如下DXGKARGCB_SIGNALEVENT 结构值:

  • hDxgkProcess 等于 0。
  • hEvent 等于传入到DXGKDDI_CREATECPUEVENT的 Dxgkrnl CPU 事件对象句柄。
  • CpuEventObject 必须为 1。
  • 保留 必须为 0。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值