window 显示驱动开发-线程处理和同步三级

三级线程处理和同步可确保:

内核模式驱动程序中只有一个线程(调用线程)。*
图形硬件处于空闲状态。
驱动程序当前没有处理任何直接内存访问 (DMA) 缓冲区,也没有传递 GPU 计划程序。
视频内存完全被逐出主机 CPU 内存。
WDDM 保证在线程处理和同步的三级下对显示微型端口驱动程序进行如下调用。

  1. DxgkDdiAddDevice
  2. DxgkDdiQueryChildRelations*
  3. DxgkDdiRemoveDevice
  4. DxgkDdiResetFromTimeout
  5. DxgkDdiRestartFromTimeout
  6. DxgkDdiSetPowerState*
  7. DxgkDdiStartDevice
  8. DxgkDdiStopDevice
  9. DxgkDdiUnload

*例外情况是,DxgkDdiQueryAdapterInfo 可以与 DxgkDdiSetPowerState 或 DxgkDdiQueryChildRelations 同时调用。 这样,当调用 DxgkDdiQueryAdapterInfo 时,系统可以避免将设备从低功耗状态唤醒。 驱动程序需要使用必要的同步从 DxgkDdiQueryAdapterInfo 返回正确的信息。

一、Level 3调用执行条件验证

硬件状态检测代码:

BOOLEAN IsGpuIdle(PDEVICE_CONTEXT pDevExt) {
    // 检查6个主要引擎状态位
    ULONG status = READ_REGISTER_ULONG(pDevExt->pEngineRegs + 0x1A4);
    return (status & 0x3F) == 0x3F;  // 所有引擎空闲标志
}

二、关键调用实现模板

2.1 设备启动流程(DxgkDdiStartDevice)

NTSTATUS DxgkDdiStartDevice(
    _In_ CONST PVOID MiniportDeviceContext,
    _Inout_ DXGK_START_INFO* pStartInfo)
{
    // Level 3自动同步保证
    PAGED_CODE();
    
    // 1. PCIe配置空间初始化
    if (!InitPciConfigSpace(pDevExt)) {
        return STATUS_DEVICE_CONFIGURATION_ERROR;
    }

    // 2. 视频内存管理器启动
    DXGK_VIDMM_INIT vidmmInit = {0};
    vidmmInit.Flags.EnableMemoryEviction = TRUE;
    pStartInfo->DxgkDdiVidMmInit(&vidmmInit);

    // 3. 中断注册(必须最后执行)
    NTSTATUS status = IoConnectInterruptEx(
        &pDevExt->InterruptObject,
        ...);
    return status;
}

2.2 TDR恢复处理(DxgkDdiResetFromTimeout)

void DxgkDdiResetFromTimeout(_In_ PVOID MiniportDeviceContext) {
    // 系统全局TDR锁已由DXGKRNL持有
    PDEVICE_CONTEXT pDevExt = (PDEVICE_CONTEXT)MiniportDeviceContext;

    // 1. 强制终止所有上下文
    VidMmCancelAllocations(pDevExt);

    // 2. GPU硬件复位序列
    SendResetCommand(pDevExt, RESET_TYPE_FULL);

    // 3. 等待50ms复位完成
    LARGE_INTEGER interval;
    interval.QuadPart = -50 * 10000;  // 50ms
    KeDelayExecutionThread(KernelMode, FALSE, &interval);
}

三、特殊并发例外处理

3.1 低功耗状态查询(DxgkDdiQueryAdapterInfo)

NTSTATUS DxgkDdiQueryAdapterInfo(
    _In_ CONST HANDLE hAdapter,
    _Inout_ DXGKARG_QUERYADAPTERINFO* pArgs)
{
    if (pArgs->Type == DXGKQAITYPE_UMDRIVERPRIVATE) {
        // 需要与SetPowerState同步
        ExAcquireFastMutex(&pDevExt->PowerMutex);
        NTSTATUS status = QueryPowerStateInfo(pDevExt, pArgs);
        ExReleaseFastMutex(&pDevExt->PowerMutex);
        return status;
    }
    // 其他查询类型无需同步...
}

3.2 子设备枚举(DxgkDdiQueryChildRelations)

NTSTATUS DxgkDdiQueryChildRelations(
    _In_ PVOID MiniportDeviceContext,
    _Inout_ DXGK_CHILD_DESCRIPTOR* pChildRelations)
{
    // 动态检测显示器热插拔
    ExAcquireFastMutex(&pDevExt->ChildLock);
    
    if (pDevExt->bHotplugDetectionPending) {
        UpdateEdidCache(pDevExt);
        pDevExt->bHotplugDetectionPending = FALSE;
    }

    ExReleaseFastMutex(&pDevExt->ChildLock);
    return STATUS_SUCCESS;
}

四、内存逐出协议

4.1 显存回收流程

4.2 关键验证点

void VerifyLevel3Conditions() {
    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
    ASSERT(IsGpuIdle(pDevExt));
    ASSERT(VidMmGetAllocationCount() == 0);
}

五、调试与验证

5.1 WinDbg扩展命令

!dxgkd.synclevel 3   // 显示当前Level3调用栈
!vidmm.eviction      // 检查内存逐出状态

5.2 断言检查列表

断言条件错误代码
KeGetCurrentThread() == pDevExt->Level3OwnerThread0xC000000D
!InterlockedCompareExchange(&pDevExt->DmaActive, 0, 0)0xC0000010

六、版本差异

WDDM版本Level3增强特性
1.2基础同步保证
2.0增加DMA缓冲区状态检查
2.5支持PCIe FLR(功能级复位)

实现要点总结:

  • 所有Level 3调用必须包含PAGED_CODE()宏验证
  • 硬件寄存器访问前需双重确认GPU空闲状态
  • 内存逐出必须等待VidMmEvictAllocations完成回调
  • 与Power State/Child Relations的并发需使用FAST_MUTEX保护
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值