window显示驱动开发—确定显示适配器上的 VidPN 支持
本主题介绍显示微型端口驱动程序如何确定显示适配器上是否支持特定视频呈现网络 (VidPN) 。 阅读此材料之前,应熟悉以下主题中的材料:
- 视频呈现网络简介
- VidPN 对象和接口
如果 VidPN 满足以下条件,则它是 正常运行 的:
- 它具有至少一个路径的拓扑。 (路径是源与 target 之间的关联。)
- 拓扑中的每个源和目标都具有固定模式。
如果满足以下条件之 一,则显示适配器支持 VidPN:
- 它是功能性的,并且可以在显示适配器上实现。 也就是说,可以将显示适配器上的视频输出编解码器配置为支持 VidPN 指定的拓扑和固定模式。
- 它具有至少具有一个路径的拓扑,并且可以扩展到可在显示适配器上实现的功能 VidPN。 也就是说,无需更改已固定的任何模式,即可在尚未固定模式的所有视频源和目标上固定模式。 此外,还可以在显示适配器上实现生成的功能 VidPN。
- 它有一个空拓扑。 其思路是显示适配器上始终支持不显示任何内容。
确定是否支持 VidPN 的一部分是确定 VidPN 的拓扑是否有效。 换句话说,视频呈现源是否可以连接到拓扑指定的视频呈现目标? 请注意,并不要求拓扑中的所有视频存在目标都具有连接的监视器。 拓扑可以有效,即使没有连接的监视器,也可以支持 VidPN。
VidPN 管理器不时调用 DxgkDdiIsSupportedVidPn ,询问显示微型端口驱动程序是否在显示适配器上支持某个 VidPN。 传递给 DxgkDdiIsSupportedVidPn 的参数之一是名为所需 VidPN 的 VidPN 对象的句柄。 DxgkDdiIsSupportedVidPn 必须检查所需 VidPN 的拓扑,并且必须记下所需 VidPN 中的哪些视频呈现源和目标已具有固定模式。 然后,它必须返回一个布尔值,该值指示根据本主题前面给出的定义 (是否支持所需的 VidPN) 。
核心概念回顾与解析
1. VidPN (Video Present Network) 是什么?
VidPN是一个描述当前或期望的显示配置的软件抽象模型。它定义了:
- 拓扑 (Topology):哪个视频呈现源(Video Present Source,可以理解为一个桌面或一个应用程序的渲染内容)连接到哪个视频呈现目标(Video Present Target,即物理输出端口,如HDMI 1)。
- 模式 (Mode):每个源和目标的显示设置,如分辨率、刷新率、颜色深度、时序等。
固定模式 (Pinned Mode):一个已经被选定并激活的模式。
2. “正常运行”的VidPN (Functional VidPN)
一个VidPN要被称为“Functional”,必须满足两个基本条件:
- 有至少一条路径:必须有至少一个源成功连接到了一个目标。没有路径意味着没有图像输出。
- 每个源和目标都有固定模式:路径上的每个端点都必须有明确、具体的显示模式设置。不能存在“未指定”或“无效”的模式。
3. 显示适配器“支持”一个VidPN的含义(核心)
这是 DxgkDdiIsSupportedVidPn 函数需要判断的核心问题。驱动需要检查一个给定的VidPN是否能在硬件上实现。支持分为三种情况,您已经列出,这里进行解释:
情况一:完全匹配,可直接实现
条件:所需的VidPN本身就是“Functional”的,并且其指定的拓扑和所有的固定模式都在显示适配器硬件的物理能力范围内。
例子:VidPN要求将源A(1920x1080 @ 60Hz)输出到Target 1(HDMI端口)。你的显卡HDMI口确实支持1080p@60Hz,驱动只需配置相应的硬件寄存器即可实现。驱动应返回 TRUE。
情况二:可扩展为实现
条件:VidPN的拓扑有效(即连接的路径在硬件上是可能的),但某些源或目标还没有固定模式。驱动需要判断:能否在不改变已有固定模式的前提下,为那些未固定模式的源和目标选择一个模式,使得整个VidPN变得“Functional”并且最终能被硬件支持?
例子:用户想要“扩展”桌面。VidPN拓扑是:源A -> Target 1,源B -> Target 2。但只有源A(主显示器)的模式是固定的(2560x1440)。源B和Target 2的模式未指定。驱动需要检查:在Target 2(比如是一个DP口)上,能否找到一个与源A模式同时工作的模式(比如1920x1080@60Hz)?如果可以,那么这个VidPN就是“可支持”的。驱动应返回 TRUE。
情况三:空拓扑
条件:VidPN中没有任何路径(即没有源连接到任何目标)。这代表“不显示任何内容”(比如用户关闭了所有显示器)。
解释:从硬件角度看,让显卡停止输出信号通常是总是可行的。因此驱动总是应该支持空拓扑的VidPN,并返回 TRUE。