若要指示 GPU 支持 GDI 硬件加速,显示微型端口驱动程序的 DriverEntry 函数实现必须使用指向驱动程序实现的 DxgkDdiRenderKm 函数的指针填充 DRIVER_INITIALIZATION_DATA 结构的 DxgkDdiRenderKm 成员。
DirectX 图形内核子系统调用 DxgkDdiRenderKm 函数,以从操作系统提供的内核模式规范显示驱动程序 (CDD) 传递的命令缓冲区生成 DMA 缓冲区。
当 DirectX 图形内核子系统的显示端口驱动程序 (Dxgkrnl.sys) 调用 DxgkDdiCreateContext 函数时,它会设置 pCreateContext-Flags-GdiContext >> 成员以指示用于 GDI 硬件加速的上下文。
同样,当显示端口驱动程序调用 DxgkDdiCreateDevice 函数时,它会设置 pCreateDevice-Flags-GdiDevice >> 成员以指示用于 GDI 硬件加速的设备。
1. 核心目标
确保显示微型端口驱动程序正确声明对 GDI 硬件加速 的支持,使 Windows 图形子系统(DWM/GDI)能利用 GPU 加速渲染。
2. 关键驱动初始化设置
(1) DriverEntry 必须注册 DxgkDdiRenderKm
作用:
驱动程序必须实现 DxgkDdiRenderKm,用于处理 GDI 命令缓冲区 并生成 GPU 可执行的 DMA 缓冲区。
在 DRIVER_INITIALIZATION_DATA 结构中显式声明支持:
DRIVER_INITIALIZATION_DATA DriverInitData = {0};
DriverInitData.DxgkDdiRenderKm = YourDxgkDdiRenderKmFunction; // 必须指向有效实现
DriverInitData.DxgkDdiRenderKm = YourDxgkDdiRenderKmFunction; // 必须指向有效实现
调用关系:
DxgkDdiRenderKm 由 DirectX 图形内核(Dxgkrnl.sys) 调用,用于转换 CDD(内核模式规范显示驱动程序) 提供的命令。
(2) 关键标志:GdiContext 和 GdiDevice
DxgkDdiCreateContext 中的 GdiContext 标志
当显示端口驱动创建 GDI 硬件加速上下文 时,会设置:
pCreateContext->Flags.GdiContext = TRUE; // 表示此上下文用于 GDI 加速
驱动程序行为:
需分配适合 GDI 渲染的 GPU 资源(如专用命令队列/状态)。
DxgkDdiCreateDevice 中的 GdiDevice 标志
当显示端口驱动创建 GDI 兼容设备 时,会设置:
pCreateDevice->Flags.GdiDevice = TRUE; // 表示此设备支持 GDI 加速
驱动程序行为:需初始化与 GDI 兼容的设备特性(如线性内存布局、特定像素格式支持)。
3. 关键调用流程
驱动加载时:DriverEntry 注册 DxgkDdiRenderKm,声明支持 GDI 加速。
设备初始化时:DxgkDdiCreateDevice 收到 GdiDevice=TRUE,配置 GDI 兼容设备。
上下文创建时:DxgkDdiCreateContext 收到 GdiContext=TRUE,分配 GDI 专用资源。
渲染时:DxgkDdiRenderKm 被调用,将 CDD 的 GDI 命令转换为 DMA 缓冲区供 GPU 执行。
4. 实现注意事项
场景 | 驱动程序需处理的操作 |
---|---|
GdiDevice=TRUE | 确保设备支持 GDI 要求的特性(如 DXGI_FORMAT_B8G8R8A8_UNORM 像素格式)。 |
GdiContext=TRUE | 可能需禁用某些 GPU 优化(如 Tile-Based Rendering),以匹配 GDI 的立即模式渲染。 |
DxgkDdiRenderKm | 需正确处理 CDD 提供的 GDI 命令缓冲区,生成合规的 DMA 缓冲区。 |
5. 伪代码示例
// DriverEntry 中初始化 GDI 支持
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObj, PUNICODE_STRING RegistryPath) {
DRIVER_INITIALIZATION_DATA InitData = {0};
InitData.DxgkDdiRenderKm = YourRenderKmHandler; // 关键:注册渲染函数
// ... 其他初始化 ...
DxgkInitialize(&InitData);
}
// DxgkDdiCreateDevice 处理 GDI 设备
NTSTATUS DxgkDdiCreateDevice(D3DKMDT_HDEVICE hDevice, CONST DXGKARG_CREATEDEVICE* pArgs) {
if (pArgs->Flags.GdiDevice) {
// 配置 GDI 兼容设备(如线性内存模式)
}
}
// DxgkDdiRenderKm 处理 GDI 命令
NTSTATUS DxgkDdiRenderKm(D3DKMDT_HDEVICE hDevice, CONST DXGKARG_RENDER* pArgs) {
if (pArgs->Flags.GdiContext) {
// 转换 CDD 的 GDI 命令为 DMA 缓冲区
}
}
6. 总结
- 必须实现:DxgkDdiRenderKm 是 GDI 加速的核心,未注册会导致回退到软件渲染。
- 标志处理:GdiDevice 和 GdiContext 指示需启用 GDI 兼容模式。
- 性能影响:正确的实现可显著提升 GDI/DWM 渲染效率,错误实现可能导致黑屏或性能下降。
适用于 WDDM v1.2+ 驱动程序开发,尤其是需要兼容传统 GDI 应用的 GPU 驱动。