window 显示驱动开发-线程和同步级别为零级

在零级线程处理和同步中,WDDM 允许以可重入的方式对显示微型端口驱动程序进行零级 DxgkDdi*Xxx 调用。 也就是说,多个线程可以通过调用零级 DDI 同时进入驱动程序。

驱动程序应预期系统中的任何线程会传入,并应相应地保护该线程的数据。

尽管驱动程序中可以同时运行两个或多个线程,但不能有两个线程属于单个进程。

级别零是默认的线程和同步级别,包括以下函数:

  • DxgkDdiCheckMultiPlaneOverlaySupport3 (或 DxgkDdiCheckMultiPlaneOverlaySupport2/DxgkDdiCheckMultiPlaneOverlaySupport)
  • DxgkDdiCloseAllocation
  • DxgkDdiCollectDbgInfo。 此函数应收集各种故障的调试信息,并且可以随时在高 IRQL (调用,也就是说, DxgkDdiCollectDbgInfo 运行所在的 IRQL 通常) 未定义。 在所有情况下, DxgkDdiCollectDbgInfo 都必须验证所需调试信息和正确同步的可用性。 但是,如果 pCollectDbgInfo 参数指向的 DXGKARG_COLLECTDBGINFO 结构的 Reason 成员设置为 VIDEO_TDR_TIMEOUT_DETECTED 或 VIDEO_ENGINE_TIMEOUT_DETECTED,则驱动程序必须确保 DxgkDdiCollectDbgInfo 可分页、在 IRQL = PASSIVE_LEVEL 运行并支持零级同步。
  • DxgkDdiControlEtwLogging
  • DxgkDdiCreateAllocation
  • DxgkDdiCreateContext
  • DxgkDdiCreateDevice
  • DxgkDdiDescribeAllocation
  • DxgkDdiDestroyAllocation
  • DxgkDdiDestroyContext
  • DxgkDdiDestroyDevice
  • DxgkDdiDpcRoutine
  • DxgkDdiEnumVidPnCofuncModality
  • DxgkDdiGetScanLine
  • DxgkDdiGetStandardAllocationDriverData
  • DxgkDdiInterruptRoutine
  • DxgkDdiIsSupportedVidPn
  • DxgkDdiMiracastCreateContext
  • DxgkDdiMiracastDestroyContext
  • DxgkDdiMiracastIoControl
  • DxgkDdiMiracastQueryCaps
  • DxgkDdiOpenAllocation
  • DxgkDdiPresent
  • DxgkDdiQueryAdapterInfo
  • DxgkDdiQueryCurrentFence
  • DxgkDdiRecommendFunctionalVidPn
  • DxgkDdiRecommendVidPnTopology
  • DxgkDdiRender
  • DxgkDdiRenderKm
  • DxgkDdiResetDevice

1. 零级同步的核心特性

(1) 可重入性(Reentrancy)

  • 多个线程可同时调用零级 DDI 函数,但 同一进程的两个线程不能同时进入驱动程序(跨进程允许并发)。
  • 驱动程序必须 自行保护共享数据(如全局状态、硬件寄存器等),避免竞争条件。

(2) 默认同步级别

  • 零级是 默认级别,适用于大多数常规 DDI 调用。
  • 相比 Level 1/2/3,零级同步限制最少,但要求驱动程序 自行管理线程安全。

(3) IRQL 限制

  • 大多数零级函数可以在 任意 IRQL(中断请求级别)运行,但某些特殊情况(如 DxgkDdiCollectDbgInfo 处理超时)必须在 PASSIVE_LEVEL(低 IRQL)执行。

2. 零级包含的主要函数

以下是常见的零级 DDI 函数:

函数 描述
DxgkDdiCheckMultiPlaneOverlaySupport[2/3] 检查硬件是否支持多平面覆盖(MPO)
DxgkDdiCloseAllocation 关闭分配的资源(如显存)
DxgkDdiCollectDbgInfo 调试信息收集(关键函数,见下文)

3. 特殊函数:DxgkDdiCollectDbgInfo

(1) 一般情况

  • 可以在 任意 IRQL 调用(包括 DISPATCH_LEVEL 或更高)。
  • 必须验证数据可用性(如内存是否可分页)。
  • 必须同步访问共享资源(如日志缓冲区)。

(2) 超时检测(TDR/Engine Timeout)

当 DXGKARG_COLLECTDBGINFO.Reason 为以下值时:

  • VIDEO_TDR_TIMEOUT_DETECTED(GPU 超时)
  • VIDEO_ENGINE_TIMEOUT_DETECTED(引擎超时)

驱动必须:

  • 在 PASSIVE_LEVEL(低 IRQL)运行(可分页代码)。
  • 支持零级同步(允许多线程进入)。
  • 避免死锁(不能持有自旋锁等不可睡眠的锁)。

4. 线程安全实现建议

由于零级允许可重入调用,驱动程序必须:

使用适当的同步机制:

  • 自旋锁(Spin Lock):适用于高 IRQL(如 DISPATCH_LEVEL)。
  • 互斥体(Mutex):适用于 PASSIVE_LEVEL(可分页代码)。
  • 原子操作(Atomic Operations):适用于简单状态更新(如引用计数)。

避免全局状态污染:

  • 使用 线程局部存储(TLS) 或 上下文结构体 隔离不同线程的数据。

5. 典型应用场景

多线程资源管理:

  • 线程A调用 DxgkDdiCloseAllocation 释放资源,同时线程B调用 DxgkDdiCheckMultiPlaneOverlaySupport3 检查 MPO 支持。

调试信息收集:

  • 系统在 GPU 超时(TDR)时调用 DxgkDdiCollectDbgInfo,同时其他线程可能仍在提交命令。

6. 总结

特性 零级(Level 0) 一级(Level 1) 二级(Level 2) 三级(Level 3)
可重入性 ✅ 允许(跨进程) ❌ 类内禁止 ❌ 单线程 ❌ 单线程
默认级别 ✅ 是 ❌ 否 ❌ 否 ❌ 否
IRQL 限制 大多数任意 IRQL 通常 PASSIVE_LEVEL 硬件空闲时 硬件空闲时
同步要求 驱动自行管理 类内互斥 WDDM 保证单线程 WDDM 保证单线程

零级同步适用于大多数常规操作,但驱动程序必须自行处理线程安全!

相关推荐
沃普天科技几秒前
USB显示器驱动板触摸收款机显示器收银机点菜机广告机
驱动开发·游戏·计算机外设·电脑·ar·音视频·硬件工程
云烟成雨TD2 分钟前
Spring AI Alibaba 1.x 系列【56】SAA Admin 平台功能介绍
java·人工智能·spring
Gauss松鼠会2 分钟前
GaussDB(DWS) 资源监控Topsql
java·网络·数据库·算法·oracle·性能优化·gaussdb
夏日听雨眠2 分钟前
数据结构(快速排序)
java·数据结构·算法
薇茗4 分钟前
【初阶数据结构】 升沉有序的平仄 排序 3
c语言·开发语言·数据结构·算法·排序算法·文件归并排序
字节高级特工6 分钟前
C++11(一) 革新:右值引用与移动语义
java·开发语言·c++·人工智能·后端
郝学胜-神的一滴7 分钟前
系统设计 012:从用户系统出发,吃透缓存、数据库与高并发设计
java·数据库·python·缓存·php·软件构建
AI科技星10 分钟前
强哥德巴赫猜想(1+1)终极证明(2026 年5月 21 日)
开发语言·人工智能·算法·计算机视觉·量子计算
人道领域11 分钟前
【LeetCode刷题日记】654.最大二叉树:递归算法详解
java·算法·leetcode
青云计划11 分钟前
Synchronized 锁升级:从偏向锁到重量级锁的性能进化之路
java·后端