欢迎转载【作者:张佩】【原文http://www.yiiyee.cn/Blog/wddm2/

第二部分专门只讲VIDPN。这是后面内容的基础。WDDM框架用VIDPN这个概念,来描述它所要处理的显示关系。

VIDPN

VIDPN的全称是Video Present Network,这个因为词组不太好翻译(直译可以是:视频提交网络,但颇为难听),所以一般都直接讲它的英文。

VIDPN是WDDM引入的概念,用来描述通过显卡设备(Adapter)建立的若干个显示源(Source)和若干个目标接口(Target)之间的关系。系统按照VIDPN所定义的方式,将一个或多个显示源(Source)通过显卡设备,输出到这些目标接口(Target)上。

基本元素

组成VIDPN网络的,是下面这样一些基本元素:

显示源(Source):这是一系列可提交到显卡设备,并显示出来的图像内容。

源模式(Source Mode):一个源(Source)需要一个模式(Mode)来定义它的属性,包括长、宽、颜色格式和比特深度(Bit Depth)等。

源模式集合(Source Mode Set):一个源(Source)的所有模式(Mode)的集合(Set),称为源模式集合。网络中所有源的模式集合,称为集合集(Sets)。

目标(Target):一系列物理接口,显卡设备通过它们来输出源内容。可以把它们理解成显卡上的多个接口。虽然不是很准确,但如果你愿意,也可以直接把它们理解成接在显卡设备上的若干个显示器设备——这里之所以讲不是很准确,因为从接口到最终显示,中间还存在显示器设备对图像内容的处理。作为显示器设备,另有元素Monitor Source Mode Set来标识它所能够支持的Mode。但KMDOD项目中并没有用到这个元素,它默认由显示设备自己处理Target Mode和Monitor Mode间关系。

目标模式(Target Mode):一个目标(Target)也需要一个模式(Mode)来定义它的属性,它比源更复杂一些,除了长、宽、颜色格式和深度外,还有刷新率、缓冲区长度(Pitch)等。

目标模式集合(Source Mode Set):一个目标(Target)的所有模式(Mode)集合(Set),就是源模式集合。网络中所有目标的模式集合,称为集合集(Sets)。

确定的模式(Pinned Mode):在一条Path中,不管Source还是Target,在另一方Mode确定的情况下,选择出来的能够和另一方相匹配的一个模式,称为确定的模式(Pinned Mode)。Pin是钉子的意思,即表示板上钉钉的Mode。

路径(Path):把一个源(Source)和一个目标(Target)之间的连接,称为一个路径(Path)。VIDPN网络中可能存在若干个Path,但至少有一个Path。

拓扑结构(Topology):由若干个Path组成的结构,称为拓扑结构。

从MSDN文档中还会看到其它的一些元素,如输出设备(也就是显示设备或Monitor)、输出Codec(用作输出信号或格式转换)等,但上面这些却是组成VIDPN最基本和重要的元素。KMDOD项目中也并未用到此外的其它元素。

拓扑结构

下面介绍几个VIDPN网络拓扑结构的例子,都取自MSDN文档。

示例1

下面列几张VIDPN的拓扑图,解释其中所包含的上述基本元素。

在上面的这个VIDPN的拓扑结构中,它有两个源(source1、source2)和三个目标(DVI、HD15、S-Video)。这是一种老式显卡,可以看到接口类型都比较旧。它提供了三种输出头,但只能支持两个输出源。这样一个源(Source1)输出到DVI口,另外一个源(Source2)以克隆模式(Clone Mode)同时输出到HD15和S-Video两个口上。两个源之间则是扩展模式(External Mode)。

Path1: Source 1-> DVI
Path2: Source2->HD15
Path3: Source2->S-video

三条Path组成了这个VIDPN的拓扑结构。每个Source 和Target都各有它们的mode 和mode set。在最后确定的时候,它们各自的pinned mode将被运用。

示例2

示例1中讲到一个VIDPN,两个Source对应到三个Target。那么Source和Target的数量各由什么决定的呢?从下面的图中可以清楚看到,Source的数量是由显卡内部的Codec决定的。

显卡内部因为只有两个Codec,所以它仅能提供两条Surface处理的管线(PipeLine)。这和显卡本身的处理能力有关系。但是一个被处理过的Surface却可以被轻易地输出到多个Target,这一步仅仅需要少量的硬件连线就可以实现了。所以Target的数量,取决于显卡自己的设计和定位,提供比Source数量更多的Target头也是可以的。

元素关系

MSDN用下图解释了这么多VIDPN元素之间的对应关系。

这是一张一对多和多对一的结构图。理解它们的关系很重要。总结而言,可把上面的四种关系翻译成下面的文字:

  1. 一个VIDPN,包含一个拓扑结构;

一个拓扑结构包含若干条Path;

每个Path中,包含一个Target和一个Source;

一个Target只能在唯一的Path中;

但一个Source可以存在于若干个Path中(Clone模式,见示例1)。

  1. 一个VIDPN包含多个Source Mode Set;

一个Source Mode Set由多个Source Mode组成。

  1. 一个VIDPN包含多个Target Mode Set;

一个Target Mode Set由多个Target Mode组成。

  1. 一个VIDPN包含多个Monitor source mode set;

一个Monitor source mode set由多个Monitor source mode组成。

框架接口

前文我们介绍了框架和小端口之间的关系,框架对小端口提供了强有力的支持,胜过再造的力量。这个再造的力量,源自于框架向小端口所提供的各种接口。所谓接口,其实就是框架业已实现的种种功能,而以函数形式提供给小端口驱动使用。形式上,它们被封装在若干个不同的数据结构中。

框架为小端口驱动提供的各种接口,其组织上,基本是根据VIDPN的各主要元素来划分的,下面会看到。我们会对这些接口做简单介绍,并列出接口的详细定义。

框架回调接口

框架回调接口是唯一由WDDM框架直接向小端口驱动提供的接口。其它接口都是直接或间接地,可以通过框架回调接口获取到。之所以把这个接口称为框架回调接口,因为它提供的所有函数名称,都依照DxgkCbXXX这样的格式命名。Cb是Callback的缩写。在WDDM的语境中,我们把这个接口中的所有函数,称为由框架提供的回调函数。

这个接口由DDI函数DxgkDdiStartDevice在调用的时候,作为参数传入。它的定义如下:

typedef struct _DXGKRNL_INTERFACE {
ULONG Size;
ULONG Version;
HANDLE DeviceHandle;
DXGKCB_EVAL_ACPI_METHOD DxgkCbEvalAcpiMethod;
DXGKCB_GET_DEVICE_INFORMATION DxgkCbGetDeviceInformation;
DXGKCB_INDICATE_CHILD_STATUS DxgkCbIndicateChildStatus;
DXGKCB_MAP_MEMORY DxgkCbMapMemory;
DXGKCB_QUEUE_DPC DxgkCbQueueDpc;
DXGKCB_QUERY_SERVICES DxgkCbQueryServices;
DXGKCB_READ_DEVICE_SPACE DxgkCbReadDeviceSpace;
DXGKCB_SYNCHRONIZE_EXECUTION DxgkCbSynchronizeExecution;
DXGKCB_UNMAP_MEMORY DxgkCbUnmapMemory;
DXGKCB_WRITE_DEVICE_SPACE DxgkCbWriteDeviceSpace;
DXGKCB_IS_DEVICE_PRESENT DxgkCbIsDevicePresent;
DXGKCB_GETHANDLEDATA DxgkCbGetHandleData;
DXGKCB_GETHANDLEPARENT DxgkCbGetHandleParent;
DXGKCB_ENUMHANDLECHILDREN DxgkCbEnumHandleChildren;
DXGKCB_NOTIFY_INTERRUPT DxgkCbNotifyInterrupt;
DXGKCB_NOTIFY_DPC DxgkCbNotifyDpc;
DXGKCB_QUERYVIDPNINTERFACE DxgkCbQueryVidPnInterface;
DXGKCB_QUERYMONITORINTERFACE DxgkCbQueryMonitorInterface;
DXGKCB_GETCAPTUREADDRESS DxgkCbGetCaptureAddress;
DXGKCB_LOG_ETW_EVENT DxgkCbLogEtwEvent;
DXGKCB_EXCLUDE_ADAPTER_ACCESS DxgkCbExcludeAdapterAccess;
#if DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN8)
DXGKCB_CREATECONTEXTALLOCATION DxgkCbCreateContextAllocation;
DXGKCB_DESTROYCONTEXTALLOCATION DxgkCbDestroyContextAllocation;
DXGKCB_SETPOWERCOMPONENTACTIVE DxgkCbSetPowerComponentActive;
DXGKCB_SETPOWERCOMPONENTIDLE DxgkCbSetPowerComponentIdle;
DXGKCB_ACQUIRE_POST_DISPLAY_OWNERSHIP DxgkCbAcquirePostDisplayOwnership;
DXGKCB_POWERRUNTIMECONTROLREQUEST DxgkCbPowerRuntimeControlRequest;
DXGKCB_SETPOWERCOMPONENTLATENCY DxgkCbSetPowerComponentLatency;
DXGKCB_SETPOWERCOMPONENTRESIDENCY DxgkCbSetPowerComponentResidency;
#endif
} DXGKRNL_INTERFACE, *PDXGKRNL_INTERFACE;

VIDPN接口

这个接口用来管理VIDPN相关的操作。可通过框架回调接口中的DxgkCbQueryVidPnInterface获取到,示例代码如下:

// 函数:IsSupportedVidPn
CONST DXGK_VIDPN_INTERFACE* pVidPnInterface;
NTSTATUS Status = m_DxgkInterface.DxgkCbQueryVidPnInterface(
pIsSupportedVidPn;hDesiredVidPn, //
DXGK_VIDPN_INTERFACE_VERSION_V1,
pVidPnInterface);

结构体定义如下:

typedef struct _DXGK_VIDPN_INTERFACE {
DXGK_VIDPN_INTERFACE_VERSION Version;
DXGKDDI_VIDPN_GETTOPOLOGY pfnGetTopology;
DXGKDDI_VIDPN_ACQUIRESOURCEMODESET pfnAcquireSourceModeSet;
DXGKDDI_VIDPN_RELEASESOURCEMODESET pfnReleaseSourceModeSet;
DXGKDDI_VIDPN_CREATENEWSOURCEMODESET pfnCreateNewSourceModeSet;
DXGKDDI_VIDPN_ASSIGNSOURCEMODESET pfnAssignSourceModeSet;
DXGKDDI_VIDPN_ASSIGNMULTISAMPLINGMETHODSET pfnAssignMultisamplingMethodSet;
DXGKDDI_VIDPN_ACQUIRETARGETMODESET pfnAcquireTargetModeSet;
DXGKDDI_VIDPN_RELEASETARGETMODESET pfnReleaseTargetModeSet;
DXGKDDI_VIDPN_CREATENEWTARGETMODESET pfnCreateNewTargetModeSet;
DXGKDDI_VIDPN_ASSIGNTARGETMODESET pfnAssignTargetModeSet;
} DXGK_VIDPN_INTERFACE;

TOPOLOGY接口

这个接口用来管理VIDPN的拓扑结构。可以通过调用VIDPN接口的pfnGetTopology函数得到。示例代码如下:

    // 函数:IsSupportedVidPn
D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology;
CONST DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface;
Status = pVidPnInterface->pfnGetTopology(
pIsSupportedVidPn->hDesiredVidPn,
&hVidPnTopology,
&pVidPnTopologyInterface);

结构体定义如下:

typedef struct _DXGK_VIDPNTOPOLOGY_INTERFACE {
DXGKDDI_VIDPNTOPOLOGY_GETNUMPATHS pfnGetNumPaths;
DXGKDDI_VIDPNTOPOLOGY_GETNUMPATHSFROMSOURCE pfnGetNumPathsFromSource;
DXGKDDI_VIDPNTOPOLOGY_ENUMPATHTARGETSFROMSOURCE pfnEnumPathTargetsFromSource;
DXGKDDI_VIDPNTOPOLOGY_GETPATHSOURCEFROMTARGET pfnGetPathSourceFromTarget;
DXGKDDI_VIDPNTOPOLOGY_ACQUIREPATHINFO pfnAcquirePathInfo;
DXGKDDI_VIDPNTOPOLOGY_ACQUIREFIRSTPATHINFO pfnAcquireFirstPathInfo;
DXGKDDI_VIDPNTOPOLOGY_ACQUIRENEXTPATHINFO pfnAcquireNextPathInfo;
DXGKDDI_VIDPNTOPOLOGY_UPDATEPATHSUPPORTINFO pfnUpdatePathSupportInfo;
DXGKDDI_VIDPNTOPOLOGY_RELEASEPATHINFO pfnReleasePathInfo;
DXGKDDI_VIDPNTOPOLOGY_CREATENEWPATHINFO pfnCreateNewPathInfo;
DXGKDDI_VIDPNTOPOLOGY_ADDPATH pfnAddPath;
DXGKDDI_VIDPNTOPOLOGY_REMOVEPATH pfnRemovePath;
} DXGK_VIDPNTOPOLOGY_INTERFACE;

SOURCE MODE SET接口

这个接口用来管理VIDPN中的Source Mode Set。可以通过调用VIDPN接口的pfnAcquireSourceModeSet函数得到。示例代码如下:

//函数:CommitVidPn
CONST DXGK_VIDPNSOURCEMODESET_INTERFACE* pVidPnSourceModeSetInterface = NULL;
Status = pVidPnInterface->pfnAcquireSourceModeSet(
pCommitVidPn->hFunctionalVidPn,
pCommitVidPn->AffectedVidPnSourceId,
&hVidPnSourceModeSet,
&pVidPnSourceModeSetInterface);

结构体定义如下:

typedef struct _DXGK_VIDPNSOURCEMODESET_INTERFACE {
DXGKDDI_VIDPNSOURCEMODESET_GETNUMMODES pfnGetNumModes;
DXGKDDI_VIDPNSOURCEMODESET_ACQUIREFIRSTMODEINFO pfnAcquireFirstModeInfo;
DXGKDDI_VIDPNSOURCEMODESET_ACQUIRENEXTMODEINFO pfnAcquireNextModeInfo;
DXGKDDI_VIDPNSOURCEMODESET_ACQUIREPINNEDMODEINFO pfnAcquirePinnedModeInfo;
DXGKDDI_VIDPNSOURCEMODESET_RELEASEMODEINFO pfnReleaseModeInfo;
DXGKDDI_VIDPNSOURCEMODESET_CREATENEWMODEINFO pfnCreateNewModeInfo;
DXGKDDI_VIDPNSOURCEMODESET_ADDMODE pfnAddMode;
DXGKDDI_VIDPNSOURCEMODESET_PINMODE pfnPinMode;
} DXGK_VIDPNSOURCEMODESET_INTERFACE;

TARGET MODE SET 接口

这个接口用来管理VIDPN中的Target Mode Set。可以通过调用VIDPN接口的pfnAcquireTargetModeSet函数得到。示例代码如下:

// 函数:EnumVidPnCofuncModality
CONST DXGK_VIDPNTARGETMODESET_INTERFACE* pVidPnTargetModeSetInterface = NULL;
Status = pVidPnInterface->pfnAcquireTargetModeSet(
pEnumCofuncModality->hConstrainingVidPn,
pVidPnPresentPath->VidPnTargetId,
&hVidPnTargetModeSet,
&pVidPnTargetModeSetInterface)

结构体定义如下:

typedef struct _DXGK_VIDPNTARGETMODESET_INTERFACE {
DXGKDDI_VIDPNTARGETMODESET_GETNUMMODES pfnGetNumModes;
DXGKDDI_VIDPNTARGETMODESET_ACQUIREFIRSTMODEINFO pfnAcquireFirstModeInfo;
DXGKDDI_VIDPNTARGETMODESET_ACQUIRENEXTMODEINFO pfnAcquireNextModeInfo;
DXGKDDI_VIDPNTARGETMODESET_ACQUIREPINNEDMODEINFO pfnAcquirePinnedModeInfo;
DXGKDDI_VIDPNTARGETMODESET_RELEASEMODEINFO pfnReleaseModeInfo;
DXGKDDI_VIDPNTARGETMODESET_CREATENEWMODEINFO pfnCreateNewModeInfo;
DXGKDDI_VIDPNTARGETMODESET_ADDMODE pfnAddMode;
DXGKDDI_VIDPNTARGETMODESET_PINMODE pfnPinMode;
} DXGK_VIDPNTARGETMODESET_INTERFACE;

MONITOR接口

除了上面这些由框架提供的常用接口外,还有一些未曾在KMDOD项目中用到的接口:

Monitor接口:DXGK_MONITOR_INTERFACE

这个接口可通过框架回调接口中的DxgkCbQueryMonitorInterface回调函数获取。通过这个接口,可以获取Monitor的Monitor Source Mode Set接口和刷新率范围。它有两个版本,版本2中增加了函数,用来获取Windows操作系统为Monitor增加的必须支持的Mode。

Monitor Source Mode Set接口:DXGK_MONITORSOURCEMODESET_INTERFACE

这个接口可通过Monitor接口中的接口函数pfnAcquireMonitorSourceModeSet获取,它提供了操作显示器Mode相关的函数。

版本历史

V1.0:2013/8/5

[置顶] Windows显示驱动(WDDM)编程初步(2)的更多相关文章

  1. [置顶] 基于视频采集卡驱动的错误修改CX26828

    基于视频采集卡驱动的错误修改CX26828 1. 设置root密码 command:sudo passwd root 2.查看系统状态 输入命令:lsmod root@ubuntu:/home/yu# ...

  2. [置顶] Windows Phone后台音乐详解一

    应用于: Windows Phone 8 | Windows PhoneOS 7.1 你可以为winphone编写在后台播放音乐的app.这表示即使当用户点击返回或开始按钮离开你的应用界面时,你的应用 ...

  3. [置顶] MyEclipse显示中文界面,在线安装教程

    准备工作 1,装好MyEclipse软件 2,可以上网 3,在线安装地址:http://download.eclipse.org/technology/babel/update-site/R0.11. ...

  4. CUDA版本的OpenCL在windows 7的下编程初步

    参考文献: http://blog.csdn.net/neoxmu/article/details/8866928 我安装的是CUDA5.5,代码如下: //#include "stdafx ...

  5. [置顶] Eclipse显示中文 在线安装教程

    准备工作: 1,一个完整的Eclipse软件: 2,加载软件地址:http://download.eclipse.org/technology/babel/update-site/R0.11.0/ke ...

  6. Windows网络驱动、NDIS驱动(微端口驱动、中间层驱动、协议驱动)、TDI驱动(网络传输层过滤)、WFP(Windows Filtering Platform)

    catalog . 引言 . Windows 2000网络结构和OSI模型 . NDIS驱动 . NDIS微端口驱动编程实例 . NDIS中间层驱动编程实例 . NDIS协议层驱动编程实例 . TDI ...

  7. sd_cms置顶新闻,背景颜色突击显示

    维护之前的一个客户网站,使用的是sd_cms系统,因为好久没有维护了,看到这网站的时候,真不敢相信,自己也曾做出过这样的网站. 客户要求置顶新闻始终在最上面,有背景颜色突击显示. 找到对应的代码,修改 ...

  8. Popup 解决置顶显示问题

    原文:Popup 解决置顶显示问题 前言 Popup显示时会置顶显示.尤其是 Popup设置了StayOpen=true时,会一直置顶显示,问题更明显. 置顶显示问题现象: 解决方案 怎么解决问题? ...

  9. js滚动显示: 滚动条置顶/底

    <script> //当聊天室的内容超出页面范围时, 如何让页面刷新后 显示最下面的内容 document.getElementByIdx ( 'chatboard').scrollTop ...

随机推荐

  1. react 记录:运行npm run eject命令暴露配置文件都报这个错误

    问题: react 使用create-react-app命令创建一个项目,运行npm run eject命令暴露配置文件都报这个错误 原因:主要是脚手架添加 .gitgnore文件,但是却没有本地仓库 ...

  2. 【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

    [算法]并查集+平衡树+数学+扫描线 [题解] 经典曼哈顿距离转切比雪夫距离. 曼哈顿距离:S=|x1-x2|+|y1-y2|<=c 即:max(x1-x2+y1-y2,x1-x2-y1+y2, ...

  3. javascript中实例方法与类方法的区别

    在javascript中,类有静态属性和实例属性之分,也有静态方法和实例方法之分 类属性(静态属性):通过类直接访问,不需要声明类的实例来访问 类方法(静态方法):通过类直接访问,不需要声明类的实例来 ...

  4. 转:Python网页解析:BeautifulSoup vs lxml.html

    转自:http://www.cnblogs.com/rzhang/archive/2011/12/29/python-html-parsing.html Python里常用的网页解析库有Beautif ...

  5. 【反演复习计划】【bzoj4407】于神之怒加强版

    #include<bits/stdc++.h> #define N 5000010 #define yql 1000000007 using namespace std; typedef ...

  6. 【 Zabbix 】— Tomcat监控及故障重启服务

    一.监控tomcat原理 zabbix_server开启java poller,zabbix_java开启JavaGateway, 端口为:10052,tomcat JMX开启12345提供性能数据. ...

  7. mysql-5.7.15-winx64配置

    1.    配置环境变量 1.1  添加path路径 选择 控制面板>系统和安全>系统>高级系统设置>环境变量 mysql文件目录的绝对路径\bin 1.2  修改mysql ...

  8. java两种实现二分查找方式

    二分查找法适用于 升序排列的数组,如果你所要操作的数组不是升序排序的,那么请用排序算法,排序一下. 说明:使用二分查找法相比顺序查找  节约了时间的开销,但是增加了空间使用.因为需要动态记录 起始索引 ...

  9. python类的__new__和__init__

    python的类,和其他语言有一点不太一样,就是,他把新建一个类和初始化一个类,分成了两个方法: __new__ __init__ 当然,想想就知道,肯定是__new__先发生,然后才是__init_ ...

  10. python 多进程并发与多线程并发

    本文对python支持的几种并发方式进行简单的总结. Python支持的并发分为多线程并发与多进程并发(异步IO本文不涉及).概念上来说,多进程并发即运行多个独立的程序,优势在于并发处理的任务都由操作 ...