window显示驱动开发—DirectX 图形内核子系统(一)
本文介绍通过 DirectX 图形内核子系统(Dxgkrnl.sys)提供的内核模式接口。
- 显示端口驱动程序是 Dxgkrnl.sys的一部分。
- 内核模式显示微型端口驱动程序(KMD)由图形硬件供应商实现。
1. 核心组件与职责划分
组件 | 功能描述 |
---|---|
Dxgkrnl.sys | DirectX 图形内核,提供基础渲染框架、内存管理、GPU调度等核心服务 |
显示微型端口驱动 (KMD) | 由GPU厂商实现,负责硬件具体操作(如寄存器编程、中断处理) |
显示端口驱动 | 内置于Dxgkrnl,处理显示输出协议(如HDCP、EDID读取) |
2. 关键内核模式接口
(1) VidPN (Video Present Network) 管理
功能:管理显示拓扑(如多显示器配置、克隆/扩展模式)
核心接口:
NTSTATUS DxgkCrtcAcquireVidPnOwnership(DXGKARG_CRTC_ACQUIREVIDPNOWNERSHIP*);
NTSTATUS DxgkCommitVidPn(DXGKARG_COMMITVIDPN*);
驱动实现:
// KMD需处理VidPN变更请求
NTSTATUS KmHandleVidPnChange(DXGKARG_COMMITVIDPN* pArgs) {if (!ValidateVidPn(pArgs->hVidPn)) return STATUS_INVALID_PARAMETER;ApplyDisplayConfig(pArgs->hVidPn);return STATUS_SUCCESS;
}
(2) 路径无关旋转 (Path-Independent Rotation)
场景:支持屏幕旋转(如平板设备)而不改变显示路径
驱动要求:
实现 DXGK_ROTATION_SUPPORT 能力标志
处理 DXGKDDI_SETROTATION 通知
void DdiSetRotation(DXGKARG_SETROTATION* pRotation) {SetHardwareRotation(pRotation->RotationAngle);NotifyDxgkRotationComplete();
}
(3) 监视器目标模式枚举
接口:
NTSTATUS DxgkDdiEnumTargetModes(DXGKARG_ENUMTARGETMODES*);
典型流程:
3. 显示微型端口驱动 (KMD) 关键实现
(1) 驱动入口点
// 必须导出的标准函数
DXGKDDI_ADD_DEVICE DxgkDdiAddDevice;
DXGKDDI_START_DEVICE DxgkDdiStartDevice;
DXGKDDI_CREATE_DEVICE DxgkDdiCreateDevice;
(2) 中断处理
BOOLEAN DxgkDdiInterruptRoutine(DXGKRNL_INTERFACE* pDxgkInterface) {UINT32 interruptStatus = ReadGPUInterruptReg();if (interruptStatus & VSYNC_INT) {NotifyVsync(); // 通知Dxgkrnl垂直同步事件return TRUE;}return FALSE;
}
(3) GPU调度
NTSTATUS DxgkDdiSubmitCommand(DXGKARG_SUBMITCOMMAND* pSubmit) {if (pSubmit->Flags.Present) {QueuePresentCommand(pSubmit->hAllocation);} else {QueueRenderCommand(pSubmit->pCommand);}return STATUS_SUCCESS;
}
4. 用户模式-内核模式交互
交互场景 | 数据通路 | 同步机制 |
---|---|---|
资源创建/销毁 | D3DKMT_CREATEALLOCATION 内核调用 | 对象句柄引用计数 |
Present提交 | DXGK_PRESENTFLAGS 结构传递 | GPU围栏 (Fence) 同步 |
查询性能统计 | DXGK_QUERYSTATISTICS 共享内存 | 内存屏障 (Memory Barrier) |
5. 调试与验证工具
WinDbg扩展:
!dxgkd_ext.dxgkrnl # 查看Dxgkrnl内部状态
!d3dhand # 分析内核句柄
ETW事件:
// 启用显示驱动事件日志
WPP_INIT_TRACING(DriverObject, RegistryPath);
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT, "Rotation applied: %d", angle);
硬件验证:
- 使用 LatencyMon 检测Dxgkrnl调度延迟
- GPUView 分析内核命令队列状态
6. 常见问题排查
关键设计原则:
- KMD必须保证所有内核接口线程安全
- 显存管理需与Dxgkrnl的分页机制协同
- 中断处理例程不得阻塞(耗时操作应延迟处理)