WDDM 1.3 显示微型端口驱动程序任务,用于在 Windows 8.1 上支持 Miracast 无线显示器

注意

从 Windows 10 (WDDM 2.0) 开始,操作系统附带了可在任何 GPU 上运行的内置 Miracast 堆栈。 有关 Microsoft Miracast 堆栈以及从 Windows 10 开始支持 Miracast 显示器的驱动程序和硬件要求的信息,请参阅以下文档:

驱动程序开发人员不应再实现自定义 Miracast 堆栈。 Microsoft 可能会删除未来版本的 Windows 中对自定义 Miracast 堆栈的支持。

若要支持 Windows 8.1 上的 Miracast 无线显示器,在内核模式下运行的 WDDM 1.3 显示微型端口驱动程序需要执行以下任务。

支持 Miracast 接口

如果 WDDM 8.1 显示微型端口驱动程序支持 Miracast 显示器,则当 Microsoft DirectX 图形内核子系统调用 DxgkDdiQueryInterface 函数时,它必须报告具有指向驱动程序实现的 Miracast 函数的指针的 DXGK_MIRACAST_DISPLAY_INTERFACE 结构。

如果操作系统的 DirectX 图形内核子系统 (Dxgkrnl.sys) 不调用 DxgkDdiQueryInterface 函数来查询 Miracast 显示接口,则它不支持 Miracast 无线显示器,并且显示微型端口驱动程序不应报告任何 Miracast 目标。

驱动程序不应在任何完整的 WDDM 图形设备上报告多个 Miracast 目标,否则操作系统无法启动适配器。

在 Dxgkrnl 调用 DxgkDdiQueryInterface 来查询 Miracast 显示接口后,驱动程序可以在 Dxgkdrnl 调用 DxgkDdiQueryChildRelations 函数时,在设备初始化期间将目标类型报告为D3DKMDT_VOT_MIRACAST

在 Dxgkrnl 启动 Miracast 连接会话之前,Miracast 目标应保持断开连接状态。 当 Miracast 会话启动,并且监视器连接到 Miracast 接收器,或者驱动程序收到来自 Miracast 用户模式驱动程序的 I/O 请求时,由于新监视器已连接到 Miracast 接收器,显示微型端口驱动程序应通过调用 DxgkCbIndicateChildStatus 函数将监视器到达热插拔检测 (HPD) 感知值报告给操作系统。 在此调用中,驱动程序应在 DXGK_CHILD_STATUS 结构中设置以下值:

成员
类型 DXGK_CHILD_STATUS_TYPE 枚举的 StatusMiracast 常量值
Miracast连接 TRUE
MiracastMiracastMonitorType 指示连接类型的值。 如果 Miracast 接收器嵌入监视器或电视中,则此成员应设置为 D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY 枚举的 D3DKMDT_VOT_MIRACAST 常量值。

下表列出了 WDDM 1.3 显示微型端口驱动程序实现的 Miracast 函数:

函数 说明
DxgkDdiMiracastCreateContext 创建上下文以启动 Miracast 显示设备的内核模式实例。
DxgkDdiMiracastDestroyContext 创建上下文以启动 Miracast 显示设备的内核模式实例。
DxgkDdiMiracastIoControl 处理源自 Miracast 用户模式驱动程序调用 MiracastIoControl 的同步 I/O 请求。
DxgkDdiMiracastQueryCaps 查询当前显示适配器的 Miracast 功能。

启动 Miracast 会话

启动 Miracast 会话后,操作系统将调用 DxgkDdiQueryChildStatus 函数。 显示微型端口驱动程序应设置DXGK_CHILD_STATUS键入StatusMiracast 的值,应使用 DXGK_CHILD_STATUS 中的 Miracast 子结构。 如果监视器连接到 Miracast 接收器,驱动程序应设置 Miracast已连接到D3DKMDT_VOT_MIRACAST

驱动程序必须指定 D3DKMDT_VIDEO_SIGNAL_INFO 的值。VsyncFreqDivider:通过 Miracast 连接会话显示的监视器的 VSync 速率与 Miracast 接收器的 VSync 速率之比。 例如,如果 Miracast 接收器垂直刷新率为 240 Hz,连接的显示器的 VSync 中断频率为 30 Hz,则驱动程序应将 VsyncFreqDivider 设置为 8。

处理已完成编码区块的中断

通过无线 Miracast 连接传输的单个帧的数据可以分解为一个或多个编码区块。 每次 GPU 完成对这些区块之一的编码时,它都必须生成中断。 为了响应此中断,显示微型端口驱动程序必须调用 DxgkCbNotifyInterrupt 函数,并在 DXGKARGCB_NOTIFY_INTERRUPT_DATA 结构中完成 MiracastEncodeChunkCompleted 子结构,包括将DXGK_INTERRUPT_TYPE中断类型设置为DXGK_INTERRUPT_MICACAST_CHUNK_PROCESSING_COMPLETE

作为中断处理的一部分,驱动程序可以选择指定 MiracastEncodeChunkCompletedDXGKARGCB_NOTIFY_INTERRUPT_DATA 结构中的 pPrivateDriverDataPrivateDataDriverSize 成员。 用户模式驱动程序可以访问 MIRACAST_CHUNK_DATA中的此专用驱动程序数据。PrivateDriverData 成员。

如果显示微型端口驱动程序在一段时间内生成的包含区块数据的数据包数多于用户模式显示驱动程序消耗的数据包数,则新区块的可用内存空间可能会用完。在这种情况下,显示微型端口驱动程序在 MiracastEncodeChunkCompleted 中返回STATUS_NO_MEMORY状态,并且它必须调用 DxgkCbNotifyDpc 函数,以通知操作系统的 GPU 计划程序错误情况。 调用 GetNextChunkData 函数将返回 STATUS_CONNECTION_RESET 状态代码,后续调用将开始接收重置操作后提交的区块。 由于某些区块丢失,驱动程序应生成并传输新的 I 帧。

对源模式的限制

为了处理像素管道的约束,WDDM 1.3 显示微型端口驱动程序通常会限制向操作系统公开的源模式。 驱动程序通过仅使用像素管道也支持的监视器公开的模式填充源模式列表来执行此操作。 例如,驱动程序不会根据像素管道约束修改 EDID。

同样,对于 Miracast 显示,显示微型端口驱动程序限制枚举源和目标模式集时向操作系统公开的源模式集。 对于 Miracast 显示,GPU 编码功能、网络属性和接收器解码功能可以减少 Miracast 像素管道可以支持的源模式的数量。

如果显示微型端口驱动程序调用 DXGK_VIDPNSOURCEMODESET_INTERFACE::p fnAddMode 函数来尝试将三维立体声模式添加到连接到 Miracast 目标的源,则函数调用将失败。

调用操作系统提供的回调函数

操作系统提供以下 Miracast 内核模式回调函数:

函数 说明
DxgkCbMiracastSendMessage 将异步消息发送到用户模式显示驱动程序。
DxgkCbMiracastSendMessageCallback 在调用 DxgkCbMiracastSendMessage 时用于指定已完成 IRP 的IO_STATUS_BLOCK 结构。
DxgkCbReportChunkInfo
报告有关编码区块的信息。

以异步方式从内核模式发送到用户模式的消息

在 Miracast 连接会话启动之前,显示微型端口驱动程序通过 DxgkCbMiracastSendMessage 调用发送到其关联的用户模式驱动程序的任何消息不会传递。 因此,如果尚未调用用户模式驱动程序的 StartMiracastSession 函数,则发送的消息将延迟到 StartMiracastSession 返回。 如果在调用 StopMiracastSession 函数后发送消息,则操作系统会删除该消息,并且调用 DxgkCbMiracastSendMessageCallback 函数,并在 pIoStatusBlock-Status> 中设置错误状态。

修改现有显示微型端口驱动程序以支持 Miracast 显示器

调用 DxgkDdiStartDevice 函数时,显示微型端口驱动程序需要添加新的 Miracast 目标,并且应将目标的热插拔检测 (HPD) 感知值标记为 HpdAwarenessInterruptible ,以便操作系统不会轮询此目标。 此外,当调用 DxgkDdiQueryChildRelations 函数时,驱动程序应 报告D3DKMDT_VOT_MIRACAST 作为其连接类型。

驱动程序不应在任何完整的 WDDM 图形设备上报告多个 Miracast 目标。 如果驱动程序报告多个 Miracast 目标,则操作系统无法启动适配器。 如果未启动 Miracast 连接会话,驱动程序也不应报告此目标上的任何监视器。

当 DirectX 图形内核子系统调用 DxgkDdiQueryInterface 函数时,驱动程序还需要报告正确的DXGK_MIRACAST_DISPLAY_INTERFACE结构,其中包含指向内核模式地址空间中的函数的指针。

当 Miracast 会话启动时,并且监视器连接到 Miracast 接收器时,显示微型端口驱动程序应设置 DXGK_CHILD_STATUSStatusMiracast 常量值键入成员,还应设置 DXGK_CHILD_STATUSMiracast连接到TRUE,将监视器到达 HPD 报告给操作系统。 驱动程序应设置 DXGK_CHILD_STATUSMiracastMiracastMonitorType 成员为连接到接收器的正确监视器类型。 如果接收器是监视器的一部分,则应将此成员设置为 D3DKMDT_VOT_MIRACAST

如果驱动程序知道监视器的 EDID,则当操作系统调用 DxgkDdiQueryDeviceDescriptor 函数时,它应报告此 EDID。

根据硬件功能、Miracast 接收器模式列表和网络带宽,驱动程序应报告正确的源模式、目标模式、旋转模式和缩放模式。 对于目标模式,驱动程序应在 D3DKMDT_VIDEO_SIGNAL_INFO 中报告正确的 VSyncFreqDivider 成员值。 操作系统将目标模式与监视模式匹配,并删除监视器不支持的任何模式。