window显示驱动开发—DirectX 图形内核子系统(一)

发布于:2025-06-27 ⋅ 阅读:(19) ⋅ 点赞:(0)

本文介绍通过 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);

硬件验证:

  1. 使用 LatencyMon 检测Dxgkrnl调度延迟
  2. GPUView 分析内核命令队列状态

6. 常见问题排查

关键设计原则:

  1. KMD必须保证所有内核接口线程安全
  2. 显存管理需与Dxgkrnl的分页机制协同
  3. 中断处理例程不得阻塞(耗时操作应延迟处理)

网站公告

今日签到

点亮在社区的每一天
去签到