DirectX11编程指南

  • 格式:pdf
  • 大小:208.73 KB
  • 文档页数:3

DirectX11编程指南

微软在2009年8⽉的DirectXSDK中发布了DirectX的正式版本。基于对DirectX的⼀贯兴趣,我把DirectX Graphics的⽂档边看边译为中⽂。也算是⼀份学习笔记吧。

,Direct3D是在Windows平台上开发实时3D应⽤的软件开发接⼝。随着Windows操作系统的升级,Direct3D的版本也随着升级。WindowsXP对应Direct3D9的各个版本,Vista对应D3D10,10.1,Windows7则对应D3D11。所以在XP平台上是没法做D3D10及以上的开发了。不过看起来因为Win7实际上是Vista的⼀个升级,所以微软也准备在Vista上⽀持D3D11。

D3D11是D3D10的⼀个超集,即它包含了D3D10的所有功能,并在其渲染管线上添加了⼀些新的特性。根据官⽅的⽂档,D3D11的新特性包括:

ComputerShader(计算着⾊器)

计算着⾊器能把GPU当成⼀种通⽤功能的并⾏处理器来使⽤。其实在D3D9时代就已经可以应⽤GPU来进⾏GP(General-Purpose)计算了,只不过那时候需要使⽤⼀些特殊的⼿段来处理(⽐如将数据包装成“纹理”)。在D3D11中专门实现了这样⼀个着⾊器阶段来⽀持GP计算,应该使得开发这类应⽤更为⽅便⼀些了。(参考NVIDIA的CUDA 技术以及OpenCL标准)

虽然计算着⾊器也是通过D3DDevice进⾏访问的,并能和其他的图形着⾊器共享内存资源,但它并不直接连接到其他的着⾊器阶段上⾯。这⼤概是因为ComputerShader并不直接与图形渲染功能相关吧。

Dynamic Shader Linkage(动态着⾊器链接)

D3D11包含的SM5(Shader Model规范)⽀持⾯向对象语⾔的构建⽅式,并⽀持运⾏时的着⾊器链接。

多线程(Multithreading)

随着CPU的多核化趋势渐渐普及,D3DAPI对多线程的⽀持。D3D11对多线程提供了这样的功能⽀持:

并发的对象创建 - 可以在多个线程中并发地进⾏对象(资源、着⾊器等)的创建。在多线程中创建命令列表 - 命令列表是⼀个记录了图形处理命令的序列。在D3D11中,可以在多个线程中创建命令列表,然后⼜主渲染线程来发送这个命令列表到渲染硬件。

Tessellation(细分)

细分技术使得能够⽤不同的精度等级(LOD,Level of detail)来渲染⼀个模型。GPU可以根据所需的LOD来处理输⼊的模型,以得到相应负责度的实际模型。这项技术可以⼤⼤减少内存带宽对三⾓形数量的限制。这项技术通过两个新的着⾊器阶段来实现:Hull Shader(壳着⾊器)和Domain Shader(域着⾊器)。

除了上⾯的4项主要的特性外,D3D11还⽀持:

通过在创建Device的时候指定特性等级(feature level),D3D11可以在低于等级的硬件(即不完全⽀持D3D11规格的硬件)上运⾏。ShaderModel 5⼤内存⽀持 ⽀持超过4GB的资源。…(有待深⼊了解)

DirectX11 不但包含了新的Direct3D 11。 还引⼊了两个新的图形组件: Direct2D和DirectWrite。

Direct2D是⼀套硬件加速的、⽴即模式的2D图形绘制接⼝。(是⽤来取代GDI,GDI+,DirectDraw吗?) 它能⾼性能、⾼质量地绘制2D图形、位图以及⽂本。D2D能与D3D及GDI良好地互操作。

DirectWrite⽀持⾼质量的⽂本渲染,与分辨率⽆关的字体轮廓线绘制,全unicode⽂本⽀持及布局处理等等。

在D3D API 中, Device(设备)是⼀个核⼼的概念,Device是对⼀个图形硬件的抽象,它负责创建和销毁其他的对象,渲染图元等功能。D3D11中,Device对象主要⽤来管理资源,⽽DeviceContext对象执⾏渲染操作。⼀个对象只能被创建它的Device使⽤。多个Device可以通过共享资源来共享数据,但这个共享的资源也只能在创建它的Device内使⽤。(意思就是说多个Device都可以访问共享对象⾥⾯的数据,但处了创建Device之外,其他Device不能直接把这个资源连接到渲染管线上使⽤)

每个Device都由⼀个ID3D11Device接⼝来代表,可以通过D3D11CreateDevice或者D3D11CreateDeviceAndSwapChain函数来创建这个接⼝。每个Device都可以使⽤⼀个或多个DeviceContext,这主要是⽤来⽀持多线程操作。

D3D11CreateDevice函数的原型如下:

HRESULT D3D11CreateDevice(IDXGIAdapter*pAdapter,D3D_DRIVER_TYPEDriverType,HMODULESoftware,UINTFlags,CONSTD3D_FEATURE_LEVEL*pFeatureLevels,UINTFeatureLevels,UINTSDKVersion,ID3D11Device **ppDevice,D3D_FEATURE_LEVEL*pFeatureLevel,ID3D11DeviceContext **ppImmediateContext

参数解析:

IDXGIAdapter *pAdapter: 显⽰适配器接⼝。表⽰要创建的Device与这个适配器硬件对应。⼀台电脑上可能安装多个显⽰适配器(即显卡),可以使⽤IDXGIFactory::EnumAdapters函数来遍历所有的适配器。传⼊NULL的话就表⽰使⽤默认的适配器(你的电脑上⾄少应该有⼀个显卡吧)。

D3D_DRIVER_TYPEDriverType:创建的Device的类型。可能的值有:

D3D_DRIVER_TYPE_UNKNOWN: 未知类型,创建设备时不能使⽤D3D_DRIVER_TYPE_HARDWARE: 硬件设备,指使⽤硬件来实现D3D的功能。它使⽤硬件来加速D3D功能,并⽤软件实现硬件不⽀持的部分,因此能提供最好的性能。这⼀种设备类型通常都⽤⼀个HAL(Hardware Abstraction Layer,硬件抽象层)来代表。D3D_DRIVER_TYPE_REFERENCE: 参考设备,即使⽤软件(CPU上运⾏)来实现D3D的所有功能。参考设备注重功能的准确性⽽不保证速度。因此主要⽤来做功能的测试、演⽰与调试等。参考设备由DirectXSDK提供(D3D11Ref.dll ?)。这个设备通常叫做REF Device或Reference rasterizer(光栅器)D3D_DRIVER_TYPE_NULL: 空设备,即不提供D3D渲染功能的设备,它主要⽤来测试⼀些⾮测试的API的功能。它也是由DirectXSDK提供。D3D_DRIVER_TYPE_SOFTWARE: 软件渲染器,也是由软件实现D3D的所有功能。这个渲染器必须由⽤户⾃⼰实现,并通过⼀个DLL提供。D3D_DRIVER_TYPE_WARP: Windows Advanced Resterization Platform。 ⼀个⾼性能的软件光栅器。提供特性集9.1到10.1的⽀持。

HMODULESoftware:软件渲染器DLL,如果不⽤软件渲染器的话,传⼊NULL

UINTFlags:创建标记,这写标记主要⽤来控制创建的Device中的层次,这些标记可以按位与操作。如果不特别指定的话,传⼊0。 D3D11_CREATE_DEVICE_FLAG 的取值有:

D3D11_CREATE_DEVICE_SINGLETHREADED = 0x1, 设置Device为单线程使⽤。D3D11默认是⽀持多线程使⽤的,即在每个API的调⽤中都会进⾏锁保护。如果确定不会在多线程环境中使⽤,则设置该标记,则不会进⾏锁保护,这样可以提⾼性能。D3D11_CREATE_DEVICE_DEBUG = 0x2, 让Device⽀持调试层D3D11_CREATE_DEVICE_SWITCH_TO_REF = 0x4, 同时创建REF和HAL设备,这样就可以在运⾏时进⾏切换,以⽀持调试功能。D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS = 0x8, 阻⽌创建多线程(这个需要深⼊了解)D3D11_CREATE_DEVICE_BGRA_SUPPORT = 0x20, 在允许D2D与D3D互操作时设置

CONST D3D_FEATURE_LEVEL *pFeatureLevels, UINTFeatureLevels:指向⼀组特征集。创建函数会按顺序尝试这些特征集,并选择第⼀个能⽀持的特征集。传⼊NULL的话,则会依次尝试从⾼到低(SM5->SM2)的所有特征集。 特征集的可选项有:D3D_FEATURE_LEVEL_9_1 = 0x9100, SM2D3D_FEATURE_LEVEL_9_2 = 0x9200, SM2D3D_FEATURE_LEVEL_9_3 = 0x9300, SM3D3D_FEATURE_LEVEL_10_0 = 0xa000, SM4D3D_FEATURE_LEVEL_10_1 = 0xa100, SM4D3D_FEATURE_LEVEL_11_0 = 0xb000, SM5UINTSDKVersion: SDK版本,传⼊D3D11_SDK_VERSION,这是由SDK设置的⼀个常数

ID3D11Device **ppDevice,D3D_FEATURE_LEVEL *pFeatureLevel,ID3D11DeviceContext**ppImmediateContext 三个返回值,返回创建的Device,⽴即DeviceContext及当前的特征集。

Device Context 包含了Device的环境或设置。更精确地说,DeviceContext⽤来设置渲染状态,产⽣渲染命令,并使⽤资源。D3D11实现了两种Context,⼀种是⽴即渲染(immediate rendering),⼀种是延迟渲染(deferred rendering)。它们都由ID3D11DeviceContext接⼝代表。每个线程只能有⼀个Context,⼀般主线程拥有⽴即Context,⽤于渲染,其他⼯作线程拥有延迟Context。

⼀个Device有且只有⼀个⽴即Context,它⽤来直接绘制到硬件,它能够从GPU获取数据,也可以⽤来⽴即执⾏(或回放)⼀个命令列表。⽴即Context可以在创建Device时获取,也可以通过()接⼝获取。

延迟Context将GPU命令记录到命令列表之中。它主要⽤来在主线程之外记录渲染命令。创建延迟Context时将不会继承任何的⽴即Context的状态。延迟Context通过ID3D11Device::CreateDeferredContext()接⼝创建。

ID3D11Device接⼝函数都是线程安全的,但ID3D11DeviceContext接⼝不是线程安全的,即必须只能在⼀个线程内进⾏调⽤。这区别于ID3D10Device接⼝。