window显示驱动开发—显示适配器的子设备
显示适配器的子设备是由显示微端口驱动程序枚举为子设备的显示适配器上的设备。 显示适配器的所有子设备都位于船上;连接到显示适配器的监视器和其他外部设备不被视为子设备。
显示微型端口驱动程序的 DxgkDdiQueryChildRelations 函数负责枚举显示适配器的子设备。 在枚举期间,显示微端口驱动程序为每个子设备分配一个类型和热插即用检测(HPD)感知值。 类型是 DXGK_CHILD_DEVICE_TYPE 枚举器之一:
- 视频输出类型 (TypeVideoOutput)
- TypeOther
HPD 感知值是 DXGK_CHILD_DEVICE_HPD_AWARENESS 枚举值之一:
- HpdAwarenessAlwaysConnected
- HpdAwarenessInterruptible
- HpdAwarenessPolled
下表提供了具有各种类型和 HPD 感知值的设备的一些示例。
HpdAwareness | 视频输出 | 其他 |
---|---|---|
AlwaysConnected | 台式计算机上的集成 LCD 面板的输出 | 电视调音器 交叉条开关 MPEG2 编解码器 |
中断 | DVI HDMI 便携式计算机上的集成 LCD 面板的输出 | |
调查 | S-video HD15 |
操作系统使用其中的一种策略,根据 HPD 感知值,以确定外部设备是否连接到子设备。 下表简要介绍了作系统如何确定具有各种 HPD 感知值的设备的连接状态。
HpdAwareness | 操作系统如何确定连接状态 |
---|---|
AlwaysConnected | 操作系统知道子设备始终存在。 任何外部设备都从未连接到子设备或从子设备断开连接。 |
Interruptible | 当外部显示设备连接到或断开与子设备的连接时,操作系统会收到通知。 (当盖子打开时,可移植计算机上的显示面板被视为已连接,当盖子关闭时断开连接。 |
轮询 | 操作系统询问外部显示设备是否连接到子设备。 |
核心概念解析
1. 什么是“显示适配器的子设备”?
您给出的定义非常关键:“位于板上”。这意味着这些子设备是物理集成在显卡(显示适配器)硬件本身上的组件,而不是外部连接的东西。
- 是子设备:显卡上的视频输出端口(如HDMI、DisplayPort、DVI、VGA)。每个物理端口都是一个独立的子设备。
- 不是子设备:插在这些端口上的显示器(Monitors)、电视、投影仪等外部设备。
简单来说,子设备是“端口”(Ports),而不是“显示器”(Monitors)。操作系统通过驱动管理的是这些端口,显示器则是连接到端口上的外部实体。
2. 为什么需要枚举子设备?
枚举的目的是让操作系统(图形内核)知道显示适配器拥有哪些可用的物理资源。这样,OS才能:
- 知道有多少个显示输出可供使用。
- 正确地将检测到的显示器与物理端口关联起来。
- 管理每个端口的状态(是否连接了显示器、是否启用、音频能力等)。
- 处理热插拔事件(当用户插入或拔掉显示器线缆时)。
3. 如何枚举?DxgkDdiQueryChildRelations
这是显示微端口驱动程序(Display Miniport Driver)必须实现的一个核心函数。当操作系统初始化显卡驱动时,它会调用这个函数,要求驱动返回一个列表,列出适配器上所有的子设备(即所有视频输出端口)。
4. 子设备的属性:类型和HPD感知
正如您所说,驱动为每个子设备分配两个关键属性:
a) 类型 (DXGK_CHILD_DEVICE_TYPE)
您提到了两种,这是最核心的两个:
- TypeVideoOutput:这是最常见的类型。它代表一个物理视频输出端口(如DP、HDMI)。几乎所有子设备都是这个类型。
- TypeOther:用于代表集成在显卡上的其他非标准功能设备。在实践中非常罕见。
(补充:枚举中还有其他类型,如 TypeUnknown, TypeInvalid, 但 TypeVideoOutput 和 TypeOther 是驱动开发者主要关心的。)
b) 热插拔检测感知 (HPD Awareness)
这个值告诉操作系统,这个端口是否能够硬件检测连接事件。
- HPD-aware:端口支持热插拔检测。当用户插入或拔掉显示器时,硬件会生成一个中断信号,驱动会收到通知并报告给OS。这是现代数字接口(DP, HDMI)的标准功能。
- Non HPD-aware:端口不支持硬件检测。操作系统无法自动知道连接状态的变化。这通常见于古老的接口(如VGA),需要用户手动按“检测显示器”按钮或重启电脑来重新枚举。
工作流程举例
假设一块显卡有1个HDMI端口和2个DisplayPort端口。
- 系统启动/驱动加载:操作系统加载显卡的微端口驱动。
- 调用 DxgkDdiQueryChildRelations:OS问驱动:“你这块卡上有多少个子设备?”
- 驱动响应:驱动回复:“有3个子设备。”并为每个设备创建一个描述结构(DXGK_CHILD_DESCRIPTOR),指定:
- ChildDeviceType = TypeVideoOutput (因为都是输出端口)
- AcpiUid 或其他的唯一标识符,以便OS能区分它们。
- HpdAwareness = HpdAware (假设都是现代端口)
- OS创建设备堆栈:OS的即插即用管理器为这3个视频输出子设备分别创建物理设备对象(PDO)。至此,OS知道了有3个可用的显示输出。
- 检测显示器:随后,驱动和OS会轮询或等待中断,以检测每个端口是否连接了显示器。如果HDMI口插着显示器,OS就会为它创建一个“显示设备”,并与这个HDMI子设备关联起来,最终在“显示设置”中呈现出来。
总结
您所描述的概念是Windows图形底层的基石之一。它将物理硬件(显卡端口) 与逻辑设备(操作系统识别的显示器) 分离开来。
子设备:代表显卡物理上拥有的输出端口。由显卡厂商的驱动通过 DxgkDdiQueryChildRelations 报告给OS。
显示器:是连接到端口的外部设备。其信息通过DDC/CI通道从显示器的EDID中读取