window显示驱动开发—DirectX 图形内核子系统(三)
显示端口驱动程序接口
KMD 通过调用 DxgkCbQueryServices 函数,并使用DXGK_SERVICES值来指定其所需的接口类型,从而获取显示端口驱动程序的接口。 显示端口驱动程序提供的服务包括 AGP(加速图形端口)服务、调试报表服务、定时操作服务等。
1. 接口获取流
- KMD 通过以下步骤获取显示端口驱动的服务接口:
NTSTATUS status = pDxgkInterface->DxgkCbQueryServices(hAdapter, // 适配器句柄(来自 DXGKRNL_INTERFACE)DXGK_SERVICES_AGP, // 请求的服务类型(如 AGP、调试等)&pServiceInterface // 返回的接口指针 );
- DXGK_SERVICES 是一个枚举值,用于指定服务类型,例如:
- DXGK_SERVICES_AGP:加速图形端口(AGP)服务(如内存映射、GART 表操作)。
- DXGK_SERVICES_DEBUG_REPORT:调试报表服务(记录 GPU 错误或性能数据)。
- DXGK_SERVICES_TIMER:定时操作服务(高精度 GPU 计时器)。
- DXGK_SERVICES_VIDPN:显示拓扑管理服务(多显示器配置)。
2. 主要服务接口详解
(1) AGP 服务 (DXGK_SERVICES_AGP)
- 用途:管理 GPU 通过 AGP/PCIe 总线访问系统内存。
关键功能:
- 内存映射:将物理内存映射到 GPU 地址空间(如 AgpService->MapMemory)。
- GART 管理:操作 Graphics Aperture Remapping Table(GART)。
- 缓存一致性:处理 CPU-GPU 内存同步(如 AgpService->FlushCache)。
(2) 调试报表服务 (DXGK_SERVICES_DEBUG_REPORT)
- 用途:在 GPU 挂起、超时或 TDR(Timeout Detection and Recovery)事件中记录调试信息。
关键函数:
- DebugReportService->LogError:上报 GPU 错误代码。
- DebugReportService->CaptureLiveDump:生成 GPU 状态快照。
(3) 定时操作服务 (DXGK_SERVICES_TIMER)
- 用途:为 GPU 调度提供高精度计时。
典型场景:
- 垂直同步(VSync)事件计时。
- GPU 任务超时检测(如 TimerService->SetTimer)。
(4) VidPN 服务 (DXGK_SERVICES_VIDPN)
- 用途:管理显示拓扑(如多显示器配置、分辨率切换)。
关键操作:
- 枚举显示路径(VidPnService->EnumPaths)。
- 修改显示模式(VidPnService->SetMode)。
3. 服务接口的生命周期
获取时机:通常在 DxgkDdiStartDevice 或 DxgkDdiAddDevice 阶段请求服务接口。
释放要求:部分接口需要显式释放(通过 ServiceInterface->Release()),具体取决于服务类型。
线程安全:大多数服务接口可跨线程调用,但需注意 IRQL 级别(如 AGP 操作通常在 DISPATCH_LEVEL)。
4. 实际代码示例(AGP 服务)
// 在 KMD 的 DxgkDdiStartDevice 中获取 AGP 服务
PDXGK_AGP_INTERFACE pAgpService = nullptr;
NTSTATUS status = pDxgkInterface->DxgkCbQueryServices(hAdapter,DXGK_SERVICES_AGP,reinterpret_cast<void**>(&pAgpService)
);if (NT_SUCCESS(status)) {// 使用 AGP 服务映射内存PHYSICAL_ADDRESS physAddr = { ... };PVOID pGpuVa = nullptr;status = pAgpService->MapMemory(hAdapter,&physAddr,size,&pGpuVa);// 使用后释放接口pAgpService->Release();
}
5. 注意事项
版本兼容性:
- 不同 Windows 版本可能扩展 DXGK_SERVICES 枚举(如 Win11 新增 DXGK_SERVICES_WDDM3_0)。
- 驱动应检查返回的接口版本号(如 pAgpService->Version)。
错误处理:如果服务不可用(如 AGP 在 UEFI 模式下被禁用),DxgkCbQueryServices 返回 STATUS_NOT_SUPPORTED。
多 GPU 适配:每个适配器句柄 (hAdapter) 需要单独查询服务接口。
6. 底层实现背景
显示端口驱动(如 dxgkrnl.sys 或 GPU 厂商的 MiniPort 驱动)在初始化时注册这些服务接口。当 KMD 调用 DxgkCbQueryServices 时,系统会根据 hAdapter 找到对应的物理 GPU,并返回其服务接口表。
这种设计实现了:
- 模块化:KMD 按需加载服务,减少内存开销。
- 可扩展性:新服务类型可通过扩展 DXGK_SERVICES 添加。
- 安全隔离:服务接口受 Dxgkrnl 的权限控制(如调试服务仅在内核调试模式下可用)。