GPU 抢占

GPU 抢占模型已在 Windows 8(WDDM 1.2)中更新。 在更新的模型中,操作系统:

  • 不允许内核模式显示驱动程序 (KMD) 禁用 GPU DMA 数据包的抢先调度。
  • 保证在启动 超时检测和恢复 (TDR) 进程之前将抢占请求发送到 GPU。
要求 描述
驱动程序实现 - 仅完整图形和渲染 强制的
WHLK 要求和测试 Device.Graphics...抢占测试Device.Graphics...FlipOnVSyncMmIo

如果 OS 无法成功中断长时间运行的数据包,则:

  • 高优先级 GPU 工作(如桌面窗口管理器(DWM)所需的工作)可能会延迟。 此延迟会导致窗口切换和动画期间出现故障。
  • TDR 进程可能会重复重置 GPU,并最终导致系统 bug 检查发生。

所有 WDDM 1.2 KMD 都必须支持 Windows 8 抢占模型。 但是,在实际操作中,WDDM 1.2 驱动程序也可以通过 DirectX 图形内核子系统调度程序(Dxgkrnl)拒绝 Windows 8 抢占模型,从而保持 Windows 7 的行为。

GPU 抢占接口

KMD 可以使用以下 DDI 来实现 Windows 8 GPU 抢占模型。

驱动程序实现步骤

按照以下常规步骤在 KMD 中实现 Windows 8 GPU 抢占模型:

  1. 针对具有 DXGKDDI_INTERFACE_VERSION>= DXGKDDI_INTERFACE_VERSION_WIN8 的标头编译驱动程序。
  2. 通过将 PreemptionAwareMultiEngineAwareDXGK_VIDSCHCAPS 结构的成员设置为 1 来声明对 Windows 8 GPU 抢占模型的支持。 若要支持 Windows 7 抢占模型,请将 PreemptionAware 设置为零。
  3. D3DKMDT_PREEMPTION_CAPS 结构中,指定支持的抢占粒度级别,该级别通过从 D3DKMDT_GRAPHICS_PREEMPTION_GRANULARITYD3DKMDT_COMPUTE_PREEMPTION_GRANULARITY 枚举中获取的常量值来定义。
  4. 如果硬件支持延迟上下文切换,请将一个零长度的缓冲区提交到 DxgkDdiSubmitCommand 函数,并将 pSubmitCommand->Flags->ContextSwitch 成员设置为 1。 请注意在 DXGK_SUBMITCOMMANDFLAGS 结构的 ContextSwitch 成员下进行的讨论。
  5. 通过调用 DxgkCbCreateContextAllocation 函数来设置 GPU 上下文分配和设备上下文分配。 记下函数备注中给出的特定说明和限制。
  6. 调用 DxgkCbDestroyContextAllocation 函数,以销毁使用 DxgkCbCreateContextAllocation创建的 GPU 上下文分配和设备上下文分配。
  7. 准备 DMA 缓冲区以响应对 DxgkDdiBuildPagingBuffer 函数的调用时,请通过填充 DXGKARG_BUILDPAGINGBUFFER 结构中的 InitContextResource 内部结构来初始化上下文资源。 如果逐出或重新定位上下文资源,则视频内存管理器将保留上下文资源的内容。
  8. 驱动程序必须支持在下一次垂直同步时进行内存映射 I/O 翻转功能。在 Windows 8 中,即使翻转挂起,GPU 调度器也会尝试抢占硬件资源。 因此,为了防止撕裂和呈现伪影,驱动程序必须支持内存映射的 I/O 翻转模型,并且必须将 DXGK_FLIPCAPS 结构的 FlipOnVSyncMmIo 成员设置为 1,并支持 FlipOnVSyncMmIo 下所述的操作。

实现中的内存映射注意事项

按照本指南创建支持 Windows 8 GPU 抢占模型的可靠驱动程序,并提供高质量的用户体验:

  • Dxgkrnl 计划程序发送抢占命令时,请求抢占 GPU 中的中间DMA缓冲区。 具有更精细粒度 DMA 中间缓冲区抢占的硬件设备有望提供更好的客户体验。
  • 允许分页命令围栏ID重复使用:如果抢占请求导致硬件队列中的分页命令被抢占,Dxgkrnl 计划程序将重新提交使用原始围栏ID的被抢占分页命令,并且这些分页命令将在该引擎的任何其他命令之前安排执行。 将使用新分配的围栏 ID 重新提交非分页命令。
  • 提供拆分 DMA 缓冲区的补丁位置列表。 有关详细信息,请参阅 拆分 DMA 缓冲区
  • 可以使用称为绑定泄漏检测的验证模式。 此验证模式遍历修补位置列表,并拒绝未解除绑定或未重新编程为每个拆分数据包分配的数据包。 某些硬件支持虚拟地址,允许额外的间接级别,使这种验证不必要。 在这种情况下,若要指示驱动程序选择退出验证模式,请将 NoDmaPatchingDXGK_VIDSCHCAPS 结构的成员设置为 1。
  • 在 Windows 7 中,Dxgkrnl 计划程序保证按顺序执行与同一呈现命令对应的所有拆分 DMA 数据包,而无需切换到另一个呈现上下文。 在 Windows 8 抢占模型中,调度程序可以在两个拆分数据包之间执行渲染数据包,这两个拆分数据包对应于同一渲染命令,并可能来自不同的上下文。 因此,意识到抢占的驱动程序应以与常规完整数据包提交相同的方式处理拆分/部分 DMA 数据包提交。 具体而言,必须在此类提交的边界处保存或还原 GPU 状态。
  • 在链接显示适配器 (LDA) 模式下广播到多个适配器时,抢占感知驱动程序不得更改拆分 DMA 缓冲区的内容,其中多个物理 GPU 链接到单个、更快、虚拟 GPU。 在 Windows 8 抢占模型中,Dxgkrnl 计划程序不再保证同步执行拆分数据包序列,而无需切换到另一个上下文。 更改拆分 DMA 数据包内容的驱动程序会损害数据包数据的完整性。 具体而言,如果数据包在另一个引擎上执行,它将对 DMA 缓冲区数据的同一副本进行操作。
  • 在 Windows 8 GPU 抢先模型中,Dxgkrnl 调度程序为具有关联“提交时信号”同步基元的数据包启用抢先。 如果设备使用具有基于硬件的等待状态的“提交信号”同步基元,则必须支持在满足等待条件之前抢占等待指令的能力。

硬件认证要求

有关硬件设备在实现此功能时必须满足的要求的信息,请参阅 Device.Graphics…Preemption TestDevice.Graphics…FlipOnVSyncMmIo 的相关 WHLK 文档