引言
Direct3D 始终为在 Windows 平台上渲染图形提供最佳性能的 API。Windows Vista 的发布又使这些技术上升到了一个新的台阶。Direct3D 现在直接集成在 Vista 中,它将 Direct3D 图形管道用于桌面组合、Picture Viewer 和 Windows Presentation Foundation。
本文概述了 Direct3D Vista 的一些新功能,主要说明它们如何才能为 DirectX 开发人员带来好处。另外,在各节中还分别指出了相应功能的相关附加信息的位置。
在 Windows 帮助文件中可以找到更多的 Direct3D 文章,该文件可以从 Windows Vista Developer Story(英文)页面下载。
体系结构
Windows Vista 引入了 DirectX 的两种新类型:Direct3D 9Ex 和 Direct3D 10。
?Direct3D 9Ex 是 DirectX 的扩展版本,它针对除了使用 Direct3D 9 外,还希望使用 Windows Vista 驱动程序部分新功能的应用程序而设计。
?Direct3D 10 是一项新增的 DirectX 技术,已针对 Windows Vista 进行了全新构建。它提供了最先进的图形渲染功能。
此外,Direct3D 9 和旧版 DirectX API 仍可在 Windows Vista 上运行,从而答应旧代码向后兼容。
Windows Vista 显示器驱动程序模型 (WDDM)
Direct3D 9Ex 和 Direct3D 10 均构建于新款 Windows 显示器驱动程序模型 (WDDM) 之上。图形硬件只有实施 WDDM 才能在 Vista 上利用 Direct3D。
WDDM 提供了增强的稳定性、虚拟内存分配、安全性以及利用图形处理器 (GPU) 进行多任务操作的能力。
增强的稳定性是通过在 WDDM 中将驱动程序分割成两个组成部分(即精简的内核模式驱动程序和用户模式驱动程序)来实现的。由于将大部分驱动程序代码移出了内核,因此,WDDM 答应系统在不关闭整个操作系统的情况下从致命的崩溃和挂起中恢复。
WDDM 现在答应“虚拟”的视频内存。虚拟化将视频内存抽象化,因此没必要考虑在视频或系统内存中创建资源。只要指定即将使用哪个资源,系统就会将内存放在尽可能最合适的地方。此外,虚拟化所答应分配的内存比硬件上实际已存在的内存要大。随后,内存即根据需要调入到正确的硬件之中。
将内存分配限定于应用程序地址空间主要是为了确保安全。通过将应用程序与各自的资源相互隔离开来,WDDM 提供了增强的安全性能。
先前的驱动程序模型 (XPDM) 专为单个应用程序而设计,这样就使图形硬件的使用负担大大加重。这样做是出于性能的原因,却为共享 GPU 带来了困难。大多数用户都经历过这样的事情,即从游戏中切换出来后会造成应用程序中的设备状态丢失。再次回到游戏画面时,必须重建所有资源并重置设备,最好的情形下只是需要多花费一些时间,而最糟的情形下则会引发崩溃。
WDDM 现在提供了一个 GPU 内存治理器和调度器,它答应多个应用程序同时访问 GPU。因为 Direct3D 应用程序不再需要独占访问 GPU,因此在各应用程序间切换时几乎没有障碍。在使用 WDDM 的情况下,仅当驱动程序升级、物理移除设备、GPU 重置及发生意外错误时,Direct3D 设备才会丢失。
在运行旧版 DirectX 时,WDDM 会模拟早期驱动程序模型的行为。
Direct3D 10
Direct3D 10 分层运行系统
Direct3D 10 共分 4 层构建;一个瘦的核心层和三个用于添加功能的可选层。
层名
说明
核心
提供全部基本功能,是访问 Direct3D 10 时唯一需要的层。调试添加参数并进行一致性验证和大量调试输出。
着色反射
提供答应应用程序从设备中检索着色或效果信息的方法。
线程安全
答应多线程应用程序访问设备。默认情况下启用此层,但不会对单线程应用程序的性能造成影响。
在创建设备时可以指定不同的层组合。
有关具体信息,请参见 Direct3D 10 文档中的“API 层”。
注重:要获得 DirectX SDK,请参见 Microsoft DirectX Downloads(英文)。
Direct3D 10 图形管道
Direct3D 的先前版本提供了少量预定义的算法,称作固定功能图形管道。内存资源(如几何模型和纹理)通过这些算法运行以生成最终的显示图像。可有多种不同的方法来配置这些算法以生成不同的效果,但开发人员不能制作用于生成新的图形效果的管道。
Direct3D 8 引入了采用图形编程的可编程管道模型,它将管道分为许多阶段,每个阶段只负责一种特定类型的资源处理过程。Direct3D 10 进一步推广并增加了可编程管道的功能。Direct3D 10 有七个阶段,其中三个阶段是可编程的。通过编写着色,可编程管道阶段答应开发人员创建阶段所使用的算法。
下表列出了这些管道阶段:
阶段名
说明
输入装配器阶段
新增:为管道提供几何数据(三角形、线、点)。
顶点着色阶段
用于处理各个顶点几何数据的可编程阶段。常见操作是移动和亮起顶点。
几何着色阶段
新增:用于处理图元几何(全部的三角形线条或点)的可编程阶段。此阶段可根据输入图元创建和输出新的几何。可以使用这一阶段中的着色以编程的方式创建整个外形。
流输出阶段
新增:编写进入内存之前的阶段中所生成的顶点数据。这可用于将顶点反馈回管道之中以供另一通道使用,或者答应复制它们以交由 CPU 处理。
光栅化阶段
设置几何以将其映射至最终显示的二维视图。
像素着色阶段
用于计算每个已渲染图元的像素值的可编程阶段。可以使用这一阶段中的着色来生成高级的每像素光照或反射效果。
输出混合阶段
利用深度/模板缓冲区合并不同类型的输出数据,并将结果写入渲染目标。
有关具体信息,请参见 Direct3D 10 文档中的“管道阶段”部分。
Direct3D 10 着色
“着色”是一组命令,它们接受图形资源作为输入,运行一系列关于资源的指令并输出结果。Direct3D 10 提供三种不同的“着色”,它们分别与三种可编程管道阶段相对应:顶点着色、几何着色和像素着色。所有着色均基于一个公用着色核心,并提供相同的基本功能。除基本功能之外,每种类型的着色均提供特定于其特定阶段的独有功能。着色是使用高级着色语言 (HLSL) 编写的,该语言答应在算法级别进行着色编程。对着色中指令的数目没有限制。
假如在设备创建中包括着色反射层,则现在可使用 ID3D10ShaderReflection 接口通过反射来检索着色信息。
有关具体信息,请参见 Direct3D 10 文档中的“着色功能”部分。
几何着色
几何着色是 DirectX 的新增阶段,它可以为 3D 场景创建几何对象。可利用它来生成多种效果。使用这一功能强大的新增着色类型,可完成阴影锥、毛皮、鱼鳍、程序几何、细节、GPU 粒子系统、位移效果和计划植被(请参见 Direct3D 10 文档中的“管道 GS 示例”),这只是其中的几个示例。由于着色在 GPU 上运行,因此没有占用 CPU 资源,从而将 CPU 资源释放出来以供其他任务使用。
有关运行中几何着色的示例,请参见 Direct3D 10 文档中的“教程 13:几何着色”部分。
流输出阶段
流输出阶段是 DirectX 的新增阶段,用于将图形管道外部的顶点数据写入缓冲区。通过此阶段,可将“顶点着色”阶段或“几何着色”阶段(根据管道配置而定)生成的顶点数据读回到管道中,以供另一通道使用。这可通过 DrawAuto 命令完成,不必占用 CPU。或者,将数据复制到资源中,由 CPU 进一步处理。
有关具体信息,请参见 Direct3D 10 文档中的“流输出阶段”部分。
cbuffer 和 tbuffer
HLSL 提供以下两种类型缓冲区来存储恒变量:cbuffer 和 tbuffer。Cbuffer 类似于效果文件中的 C 结构。
下面是“常量缓冲区”的示例,它声明了一个 world 矩阵、一个对象位置和一个数组索引:
cbuffer MyObject
{
float4x4 matWorld;
float3 vObjectPosition;
int arrayIndex;
}
在 Direct3D 10 中,所有着色常量必须放在“常量缓冲区”中。可将所有常量放在一个缓冲区中,也可以放在多个缓冲区中,并可以通过任意方式来治理它们。通常,根据常量的更新和使用频率来将常量放入不同的缓冲区中。通过根据更新频率来治理常量,可减少必要的调用和更新次数,从而使 CPU 到 GPU 之间的带宽效率达到最大。从着色访问这些缓冲区时的延迟时间会减少。
Direct3D 10 中的 tbuffer 是从纹理负载中读取的着色常量的缓冲区。这为随意制定索引的数据提供了更好的性能。
有关具体信息,请参见 Direct3D 10 文档中的“着色恒变量”部分。
设备状态
Direct3D 10 将设备状态分为五种状态对象。
状态对象
说明
输入布局
在输入缓冲区中设置几何数据的格式和大小,该缓冲区会将图元从内存注入到管道中。
光栅化
设置“光栅化阶段”的状态,包括填充或剔除模式,启用剪式矩形将三维空间中的几何图元剪切并映射到二维视口中。
深度模板
配置深度缓冲区并设置模板测试。
混合
设置“输出混合”阶段将“像素着色”输出与当前渲染目标相混合的方式。
取样器
设置着色所使用的纹理取样器,以筛选内存中的纹理。
有关具体信息,请参见 Direct3D 10 文档中的“状态对象”部分。
组合在一起:效果
Direct3D 10 的效果系统已完全重写。FX10 系统比 FX9 更快,内存使用也更低,FX10 专门针对 Direct3D 10 硬件而设计。
效果答应开发人员创建这样一个文件,其中包含特定图形方法所需的所有着色和设备状态。其中可能包含位移映射、反射渲染、几何创建,或者着色和设备状态的任意组合结果。效果非常有用,因为它们封装了非凡的图形技巧,该技巧答应开发人员在内容创建应用程序、不同的游戏以及其他应用程序中使用同一效果文件,从而获得相同的结果。
可将效果编译成字节代码,以改进运行系统性能。否则它们将在载入内存时进行编译。
Direct3D 10 文档中的许多示例都使用 FX 文件。有关如何使用效果文件的完整论述,请参见“教程 3:着色和效果系统”。
资源
Direct3D 10 已重新设计了资源体系结构。
资源是内存中的一个区域,可以由图形管道访问。资源通常包含纹理、输入几何、着色资源、顶点缓冲区、索引缓冲区和常量缓冲区等内容。
对于创建的每种资源,开发人员可以平衡该资源所需的功能与该资源性能之间的关系。通常,访问 Direct3D 10 资源所需的开销比访问 DirectX 先前版本中的资源要低得多。
Direct3D 10 引入了纹理数组以简化纹理治理。纹理数组包含一个或多个纹理,可以在应用程序内部或通过着色制定索引。也可以将整个数组设置为渲染目标。
目前,可将资源存储为无类型资源。使用无类型资源时,必须通过获取视图将其解释为某一具体的类型。视图答应资源中的数据以不同的格式重新解释。这会更改其表示方式,但不会更改实际的基础数据。这种方法提高了性能,因为资源不必在每次绘图调用时均进行类型验证。
在不同的绑定位置(在图形管道中),视图可以启用不同的资源解释。例如,着色资源视图可以将具有六个纹理的 Texture2DArray 解释为立方图。
有关资源的完整论述,请参见 Direct3D 10 文档中的“资源”部分。
Direct3D 10 和 CAPS
先前各版本的 DirectX 使用功能标志或 CAPS 来决定硬件支持哪些功能。对于 Direct3D 10,确保所有功能均可在与视频硬件兼容的 Direct3D 10 上执行,因此消除了查询设备上是否存在 CAPS 的必要。
先前那些依靠于设备 caps 的应用程序可以通过改写设备枚举和强行将设备 CAPS 设为敏感值来判定它们不再存在的事实。
Direct3D 9Ex
Direct3D 9Ex 做了大量改进,答应利用某些 WDDM 功能。
Direct3D 9Ex 中新增的其中一个最大优点是其可以利用 WDDM 的 GPU 内存治理器和调度器,以减少设备丢失的次数。因为许多应用程序可以在 WDDM 下共享 GPU,因此在 Direct3D 9Ex 中设备丢失状态的情形几乎不会发生。只有在由于挂起而引起硬件重置或设备驱动程序停止时,设备才会丢失。模式更改不再导致所有视频内存资源和交换链被丢弃。
现在,通过 Direct3D 9Ex 也可以在设备或进程之间共享 Direct3D 资源。
有关 Direct3D 9Ex 的具体信息,请参见 Microsoft Windows SDK 文档的 DirectX for Windows Vista(英文)部分。
示例
通过下面的路径,您可以在 Windows Platform SDK 中找到演示 Direct3D 9Ex 新功能的示例:
../Microsoft SDKs/Windows/v6.0/Samples/multimedia/Direct3d/Direct3D9Ex
此示例创建了两台 DirectX 设备:一台在低优先级后台线程中运行,负责渲染大量的立方体;另一台在较高优先级线程中运行,并利用前台光标合成后台渲染。后台渲染被复制到共享表面,以答应前台设备对其进行访问。这样,在后台进行全面渲染时光标仍可流畅地运行。
更多资源
要查看更多的本系列文章,请访问 MSDN 上的 Windows Developer Story(英文)并下载 Windows 帮助文件。请查看有关 DirectX 编程和 Vista 兼容性问题、内存治理、IO 等信息的新增内容。