欢迎转载【作者:张佩】【原文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. CSS3学习笔记之loading动画

    效果截图: HTML代码: <div class="divBox"> <div class="loader"> <div clas ...

  2. 微信小程序基础知识

    一.基本目录结构 app.js 定义app入口 app.json 定义页面配置 index.js 页面中的事件和监听 index.wxml 定义布局文件 1.app.json配置基本信息 { “pag ...

  3. 3中转换JSON数据的方式

    一:前言 来公司一个星期,把最近做的东西梳理下,并把觉得有必要的知识点记载下,现在传数据很多都是用JSON来传数据,所以我就找了集中传json的方式,其实是有五种的,但是有一个我没有用过,太陌生了,上 ...

  4. java基础知识(二)-----多态和构造函数

    一:前言 最近由于面试了新浪公司,面试官问我的问题我都不知道,觉得自己好菜,所以最近决定再把java基础给搞一遍,真的觉得自己好菜.每天看一点,那个家伙说<java编程思想>最少要看三遍, ...

  5. [USACO07FEB]新牛棚Building A New Barn

    洛谷题目链接:[USACO07FEB]新牛棚Building A New Barn 题目描述 After scrimping and saving for years, Farmer John has ...

  6. NYOJ 284 坦克大战 (广搜)

    题目链接 描述 Many of us had played the game "Battle city" in our childhood, and some people (li ...

  7. DWM.EXE进程(Desktop Window Manager)不能删除

    英文全拼:Desktop Window Manager(DWM) 进程描述:桌面窗口管理器文件位置:C:\Windows\System32进程简介:桌面窗口管理器是windows Vista及wind ...

  8. springboot整合jsp模板

    springboot整合jsp模板 在使用springboot框架里使用jsp的时候,页面模板使用jsp在pom.xnl中需要引入相关的依赖,否则在controller中无法返回到指定页面 〇.搭建s ...

  9. python--requests_html

    这个模块从名字上也能看出来,是专门用来解析html的,这个和requests的作者是同一人,非常牛逼的一位大佬. 大致读了一下源码,总共一个py文件(但是引用了其他的模块),加上注释总共才700多行, ...

  10. 使用System.getProperty("line.separator")时没有换行问题解决

    项目中要实现替换模版txt文本里面的内容,然后生成新的文档,其中先把模版文本的内容通过创建的 BufferedReader bufReader 使用 readLine() 来一行一行读取,所以在完成替 ...