Direct3D 9 到 Direct3D 10 注意事项(Direct3D 10)
以下页面概述了 Direct3D 9 和 Direct3D 10 之间的主要差异。 以下概述提供了一些见解,可帮助开发人员了解 Direct3D 9 体验,并了解 Direct3D 10 并与之相关。
尽管本主题中的信息将 Direct3D 9 与 Direct3D 10 进行比较,因为 Direct3D 11 基于 Direct3D 10 和 10.1 中的改进而构建,因此还需要此信息才能从 Direct3D 9 迁移到 Direct3D 11。 有关迁移到 Direct3D 10 到 Direct3D 11 的信息,请参阅 迁移到 Direct3D 11。
- Direct3D 10 中重大结构变化概述
- 引擎抽象/分离
- 快速解决应用程序生成问题的技巧
- 驱动 Direct3D 10 API
- 移植纹理
- 移植着色器
- 用于监视的其他 Direct3D 10 差异
- 其他 Direct3D 10.1 差异
- 相关主题
Direct3D 10 中重大结构变化概述
使用 Direct3D 10 设备的呈现过程在结构上类似于 Direct3D 9。
- 设置顶点流源
- 在 Direct3D 10 中设置输入布局(在 Direct3D 9 中设置顶点流声明)
- 声明基元拓扑
- 设置纹理
- 设置状态对象
- 设置着色器
- 平局
Draw 调用将操作关联在一起;Draw 调用之前的调用顺序是任意的。 Direct3D 10 API 设计的主要区别如下:
- 删除固定函数
- 删除 CAPS 位 - 保证 Direct3D 10 的基本功能集
- 更严格的管理:资源访问、设备状态、着色器常量、着色器链接(对着色器的输入和输出)在阶段之间
- API 入口点名称更改反映了虚拟 GPU 内存(Map()而不是 Lock()的使用。
- 可以在创建时将调试层添加到设备
- 基元拓扑现在是显式状态(与 Draw 调用分开)
- 显式着色器常量现在存储在常量缓冲区中
- 着色器创作完全在 HLSL 中完成。 HLSL 编译器现在驻留在主 Direct3D 10 DLL 中。
- 新的可编程阶段 - 几何着色器
- 删除 BeginScene()/EndScene()
- 新组件中实现的通用 2D、焦点和适配器管理功能:DXGI
删除固定函数
有时令人惊讶的是,即使在完全利用可编程管道的 Direct3D 9 引擎中,仍有许多区域依赖于固定功能(FF)管道。 最常见的区域通常与 UI 的屏幕空间对齐呈现相关。 因此,可能需要生成一个 FF 仿真着色器或一组着色器,这些着色器提供必要的替换行为。
本文档包含一份白皮书,其中包含最常见的 FF 行为的替换着色器源(请参阅 固定函数 EMU 示例)。 某些固定函数像素行为(包括 alpha 测试)已移动到着色器中。
设备对象创建时间验证
Direct3D 10 管道已从硬件和软件的底层重新设计,主要目的是减少 CPU 开销(在绘图时)。 为了降低成本,已向所有类型的设备数据分配了一个对象,该对象具有设备本身提供的显式创建方法。 这样就可以在创建对象时而不是在 Draw 调用期间进行严格的数据验证,就像 Direct3D 9 一样。
引擎抽象/分离
希望同时支持 Direct3D 9 和 Direct3D 10 的应用程序需要使呈现层从代码库的其余部分抽象化。 实现此目的有很多方法,但其中所有方法的关键是设计较低级别的 Direct3D 设备的抽象层。 所有系统都应通过通用层与硬件通信,该层旨在提供 GPU 资源和低级别类型管理。
直接删除 Direct3D 9 依赖项
移植以前测试的大型基本代码时,请务必将代码更改量降到在代码中保留以前测试的行为绝对必要的更改量。 最佳做法包括清楚地记录项目使用注释更改的位置。 对于此工作,具有注释标准通常很有用,该标准支持快速浏览代码库。
下面是可用于此工作的标准单行/开始块注释的示例列表。
项 | 说明 |
---|---|
已删除 Direct3D 10 |
使用此方法可删除代码行/代码块 |
Direct3D 10 需要更新 |
它有助于向 NEED UPDATE 注释添加其他注释,该注释建议应将哪些工作/新 API 用于以后访问代码进行行为转换。 在 \\ Direct3D 10 需要更新发生的情况下,还应使用大量断言(false),以确保不知情地运行错误代码 |
Direct3D 10 已更改 |
发生重大更改的区域应保留以供将来参考,但已注释掉 |
// Direct3D 10 END |
结束代码块限定符 |
对于多行源,还应使用 C 样式 /* */ 注释,但在这些区域中添加相关的开始/结束批注。
快速解决应用程序生成问题的技巧
重写 Direct3D 9 类型
插入包含 Direct3D 9 基类型的类型定义/替代的高级头文件可能很有用,而 Direct3D 10 标头不再支持这些基类型。 这有助于最大程度地减少代码和接口中存在从 Direct3D 9 类型到新定义的 Direct3D 10 类型的直接映射的更改量。 此方法还可用于将代码行为保存在一个源文件中。 在这种情况下,最好定义版本中性/通常命名的类型,这些类型描述用于呈现的常见构造,但跨越 Direct3D 9 和 Direct3D 10 API。 例如:
#if defined(D3D9)
typedef IDirect3DIndexBuffer9 IDirect3DIndexBuffer;
typedef IDirect3DVertexBuffer9 IDirect3DVertexBuffer;
#else //D3D10
typedef ID3D10Buffer IDirect3DIndexBuffer;
typedef ID3D10Buffer IDirect3DVertexBuffer
#endif
其他 Direct3D 10 特定示例包括:
typedef ID3D10TextureCube IDirect3DCubeTexture;
typedef ID3D10Texture3D IDirect3DVolumeTexture;
typedef D3D10_VIEWPORT D3DVIEWPORT;
typedef ID3D10VertexShader IDirect3DVertexShader;
typedef ID3D10PixelShader IDirect3DPixelShader;
解决链接问题
建议使用最新版本 Microsoft的 Visual Studio 开发 Direct3D 10 和 Windows Vista 应用程序。 但是,可以使用早期版本的 Visual Studio 生成依赖于 Direct3D 10 的 Windows Vista 应用程序。 Direct3D 10 是一个 Windows Vista 平台组件,它与以下库上的 Server 2003 SP1 平台 SDK 一样:需要 BufferOverflowU.lib 来解决任何buffer_security检查链接器问题。
模拟设备 CAP
许多应用程序包含代码区域,这些区域依赖于可用的设备 CAPS 数据。 通过重写设备枚举并强制设备 CAPS 合理值来解决此问题。 计划稍后重新访问 CAPS 依赖项的区域,以便尽可能完全删除 CAPS。
驱动 Direct3D 10 API
本部分重点介绍 Direct3D 10 API 导致的行为更改。
- 资源创建
- Views
- 静态与动态资源访问
- Direct3D 10 效果
- 不带效果的 HLSL
- 着色器编译
- 创建着色器资源
- 着色器反射层接口
- 输入汇编程序布局 - 顶点着色器/输入流链接
- 着色器死代码删除的影响
- 顶点着色器输入结构示例
- 状态对象创建
资源创建
Direct3D 10 API 已将资源设计为泛型缓冲区类型,这些资源具有根据计划使用情况的特定绑定标志。 选择此设计点是为了方便在管道中几乎无处不在地访问资源,例如呈现到顶点缓冲区,然后立即绘制结果,而不会中断 CPU。 以下示例演示顶点缓冲区和索引缓冲区的分配,你可以在其中看到资源说明仅因 GPU 资源绑定标志而异。
Direct3D 10 API 提供了用于显式创建纹理类型资源的纹理帮助程序方法,但正如你想象的那样,这些确实是帮助程序函数。
- CreateTexture2D()
- CreateTextureCube()
- CreateTexture3D()
当面向 Direct3D 10 时,你可能希望在资源创建期间分配更多项,而不是用于 Direct3D 9。 这在创建呈现目标缓冲区和纹理时变得最明显,你还需要创建用于访问缓冲区并在设备上设置资源的视图。
注意
Direct3D 10 及更高版本的 Direct3D 扩展了 DDS 文件格式,以支持新的 DXGI 格式、纹理数组和多维数据集映射数组。 有关 DDS 文件格式扩展的详细信息,请参阅 DDS 的编程指南。
视图
视图是存储在像素缓冲区中的数据的特定类型接口。 资源可以同时为其分配多个视图,并且此功能突出显示了此 SDK 中包含的“单传递呈现到多维数据集地图”示例。
静态与动态资源访问
为了获得最佳性能,应用程序应根据数据的静态与动态性质对其数据使用进行分区。 Direct3D 10 旨在利用这种方法,因此,资源访问规则在 Direct3D 9 上大幅收紧。 对于静态资源,最好在创建期间使用其数据填充资源。 如果引擎已围绕 Direct3D 9 的 Create、Lock、Fill、Unlock 设计点进行设计,则可以在资源接口上使用暂存资源和 UpdateSubResource 方法延迟创建时间的填充。
Direct3D 10 效果
使用 Direct3D 10 效果系统超出了本文的范围。 系统已编写,以充分利用 Direct3D 10 提供的体系结构优势。 有关效果的使用的详细信息,请参阅“效果”(Direct3D 10)部分。
不带效果的 HLSL
Direct3D 10 着色器管道可以在不使用 Direct3D 10 效果系统的情况下驱动。 请注意,在此实例中,应用程序本身必须管理所有常量缓冲区、着色器、采样器和纹理绑定。 有关更多详细信息,请参阅本文档的示例链接和以下部分:
着色器编译
Direct3D 10 HLSL 编译器为 HLSL 语言定义带来了增强功能,因此能够在 2 种模式下运行。 若要完全支持 Direct3D 9 样式内部函数和语义,应使用兼容性模式标志调用编译,该标志可以按编译指定。
可以在 HLSL 中找到 Direct3D 10 的着色器模型 4.0 特定的 HLSL 语言语义和内部函数。 Direct3D 9 HLSL 语法的重大更改,最注意的是在纹理访问领域。 新语法是编译器在兼容模式之外支持的唯一形式。
注意
Direct3D 10 编译器类型 API(D3D10CompileShader 和 D3D10CompileEffectFromMemory)由在 Windows Vista 及更高版本中运行的 Direct3D 10、10.1 和 11 运行时提供。 Direct3D 10 编译器类型 API 的功能与 DirectX SDK 中提供的 HLSL 编译器相同(2006 年 12 月)。 此 HLSL 编译器不支持 Direct3D 10.1 配置文件(vs_4_1、ps_4_1、gs_4_1、fx_4_1),并且缺少许多优化和改进。 可以从最新的旧版 DirectX SDK 版本获取支持 Direct3D 10.1 配置文件的 HLSL 编译器。 有关旧版 DirectX SDK 的信息,请参阅 DirectX SDK 在哪里?。 可以从 Windows SDK 获取最新的 HLSL Fxc.exe命令行编译器和 D3DCompiler API。
创建着色器资源
在 Direct3D 10 效果系统外部创建已编译的着色器实例的方式与 Direct3D 9 非常相似,但在 Direct3D 10 中,请务必保留着色器输入签名以供以后使用。 签名默认作为着色器 blob 的一部分返回,但可以提取签名以减少内存需求(如果需要)。 有关详细信息,请参阅 在 Direct3D 10 中使用着色器。
着色器反射层接口
着色器反射层是可以通过该接口获取有关着色器要求的信息。 创建输入程序集链接(如下所示)时,这非常有用,可能需要遍历着色器输入要求,以确保向着色器提供正确的输入结构。 可以创建反射层接口的实例,同时创建已编译着色器的实例。
着色器反射层取代了提供类似功能的 D3DX9 方法。 例如 ,IsParameterUsed 被 GetDesc 方法替换。
输入汇编程序布局 - 顶点着色器/输入流链接
输入汇编程序 (IA) 替换 Direct3D 9 样式顶点流声明,其说明结构在形式上非常相似。 IA 带来的主要区别是,创建的 IA 布局对象必须直接映射到特定格式的着色器输入签名。 创建用于将输入流链接到着色器的映射对象可以用于着色器任意数量的着色器,其中着色器输入签名与用于创建输入布局的着色器的着色器匹配。
为了最好地使用静态数据驱动管道,应考虑输入流格式的排列方式,以可能的着色器输入签名并尽早创建 IA 布局对象实例,并尽可能重复使用它们。
着色器死代码删除的影响
以下部分详细介绍了 Direct3D 9 和 Direct3D 10 之间的显著差异,这可能需要在引擎代码中仔细处理。 包含条件表达式的着色器通常会在编译过程中删除某些代码路径。 在 Direct3D 9 中,在未使用时,可能会删除两种类型的输入(标记为删除):签名输入(如以下示例)和常量输入。 如果常量缓冲区的末尾包含未使用的条目,着色器中的大小声明将反映常量缓冲区的大小,而末尾没有未使用的条目。 这两种类型的输入都保留在签名或常量缓冲区 Direct3D 10 中,在常量缓冲区末尾未使用的常量输入时有特殊例外。 处理大型着色器和创建输入布局时,这可能会影响引擎。 编译器中的死代码优化删除的元素仍必须在输入结构中声明。 下面的示例演示这一操作:
顶点着色器输入结构示例
struct VS_INPUT
{
float4 pos: SV_Position;
float2 uv1 : Texcoord1;
float2 uv2 : Texcoord2; *
};
* 由于条件死代码删除,Direct3D 9 死代码删除会删除着色器中的声明
float4x4 g_WorldViewProjMtx;
static const bool g_bLightMapped = false; // define a compile time constant
VS_INPUT main(VS_INPUT i)
{
VS_INPUT o;
o.pos = mul( i.pos, g_WorldViewProjMtx);
o.uv1 = i.uv1;
if ( g_bLightMapped )
{
o.uv2 = i.uv2;
}
return o;
}
或者,可以更清楚地看到该常量是具有以下声明的编译时常量:
#define LIGHT_MAPPED false
在上面的示例中,在 Direct3D 9 下,由于编译器中的死代码优化,将删除 uv2 元素。 在 Direct3D 10 下,仍将删除死代码,但着色器输入汇编程序布局要求输入数据的定义存在。 着色器反射层提供了一种以泛型方式处理这种情况的方法,你可以遍历着色器输入要求,并确保提供对输入流到着色器签名映射的完整说明。
下面是一个示例函数,用于检测函数签名中是否存在语义名称/索引:
// Returns true if the SemanticName / SemanticIndex is used in the input signature.
// pReflector is a previously acquired shader reflection interface.
bool IsSignatureElementExpected(ID3D10ShaderReflection *pReflector, const LPCSTR SemanticName, UINT SemanticIndex)
{
D3D10_SHADER_DESC shaderDesc;
D3D10_SIGNATURE_PARAMETER_DESC paramDesc;
Assert(pReflector);
Assert(SemanticName);
pReflector->GetDesc(&shaderDesc);
for (UINT k=0; k<shaderDesc.InputParameters; k++)
{
pReflector->GetInputParameterDesc( k, ¶mDesc);
if (wcscmp( SemanticName, paramDesc.SemanticName)==0 && paramDesc.SemanticIndex == SemanticIndex)
return true;
}
return false;
}
状态对象创建
移植引擎代码时,它可能有助于最初使用一组默认的状态对象并禁用所有 Direct3D 9 设备呈现状态/纹理状态设置。 这将导致呈现项目,但这是启动和运行事情的最快方法。 稍后可以构造一个状态对象管理系统,该系统可以使用复合键来最大程度地重复使用正在使用的状态对象数。
移植纹理
支持的文件格式
从图形文件(例如 D3DX10CreateTextureFromFile)创建或保存纹理的 D3DXxxCreateXXX 和 D3DXxxSaveXXX 函数支持 Direct3D 10 中的一组不同的文件格式,而不是 Direct3D 9 中的一组文件格式:
文件格式 | Direct3D 9 | Direct3D 10 |
---|---|---|
.bmp | 是 | 是 |
.jpg | 是 | 是 |
.tga | 是 | |
.png | 是 | 是 |
.dds | 是 | 是 |
.ppm | 是 | |
.dib | 是 | |
.hdr | 是 | |
.pfm | 是 | |
.tiff | 是 | |
.gif | 是 | |
.tif | 是 |
有关详细信息,请将 Direct3D 9 D3DXIMAGE_FILEFORMAT 枚举与 Direct3D 10 的D3DX10_IMAGE_FILE_FORMAT枚举进行比较。
注意
Windows 8 已弃用 D3DX (D3DX 9、D3DX 10 和 D3DX 11)实用工具库。 对于纹理文件处理,建议使用 DirectXTex。
映射纹理格式
下表显示了从 Direct3D 9 到 Direct3D 10 的纹理格式的映射。 DXGI 中不可用的格式的任何内容都需要由实用工具例程转换。
Direct3D 9 格式 | Direct3D 10 格式 |
---|---|
D3DFMT_UNKNOWN | DXGI_FORMAT_UNKNOWN |
D3DFMT_R8G8B8 | 不可用 |
D3DFMT_A8R8G8B8 | DXGI_FORMAT_B8G8R8A8_UNORM & DXGI_FORMAT_B8G8R8A8_UNORM_SRGB ー |
D3DFMT_X8R8G8B8 | DXGI_FORMAT_B8G8R8X8_UNORM & DXGI_FORMAT_B8G8R8X8_UNORM_SRGB ー |
D3DFMT_R5G6B5 | DXGI_FORMAT_B5G6R5_UNORM ー |
D3DFMT_X1R5G5B5 | 不可用 |
D3DFMT_A1R5G5B5 | DXGI_FORMAT_B5G5R5A1_UNORM ー |
D3DFMT_A4R4G4B4 | DXGI_FORMAT_B4G4R4A4_UNORM DXGI_FORMAT_B4G4R4A4_UNORM |
D3DFMT_R3G3B2 | 不可用 |
D3DFMT_A8 | DXGI_FORMAT_A8_UNORM |
D3DFMT_A8R3G3B2 | 不可用 |
D3DFMT_X4R4G4B4 | 不可用 |
D3DFMT_A2B10G10R10 | DXGI_FORMAT_R10G10B10A2 |
D3DFMT_A8B8G8R8 | DXGI_FORMAT_R8G8B8A8_UNORM & DXGI_FORMAT_R8G8B8A8_UNORM_SRGB |
D3DFMT_X8B8G8R8 | 不可用 |
D3DFMT_G16R16 | DXGI_FORMAT_R16G16_UNORM |
D3DFMT_A2R10G10B10 | 不可用 |
D3DFMT_A16B16G16R16 | DXGI_FORMAT_R16G16B16A16_UNORM |
D3DFMT_A8P8 | 不可用 |
D3DFMT_P8 | 不可用 |
D3DFMT_L8 | DXGI_FORMAT_R8_UNORM注意:使用着色器中的 .r 重排将红色复制到其他组件以获取 D3D9 行为。 |
D3DFMT_A8L8 | DXGI_FORMAT_R8G8_UNORM注意:在着色器中使用重排 .rrrg 复制红色并将绿色移动到 alpha 组件以获取 D3D9 行为。 |
D3DFMT_A4L4 | 不可用 |
D3DFMT_V8U8 | DXGI_FORMAT_R8G8_SNORM |
D3DFMT_L6V5U5 | 不可用 |
D3DFMT_X8L8V8U8 | 不可用 |
D3DFMT_Q8W8V8U8 | DXGI_FORMAT_R8G8B8A8_SNORM |
D3DFMT_V16U16 | DXGI_FORMAT_R16G16_SNORM |
D3DFMT_W11V11U10 | 不可用 |
D3DFMT_A2W10V10U10 | 不可用 |
D3DFMT_UYVY | 不可用 |
D3DFMT_R8G8_B8G8 | DXGI_FORMAT_G8R8_G8B8_UNORM(在 DX9 中,数据纵向扩展了 255.0f,但可以在着色器代码中处理)。 |
D3DFMT_YUY2 | 不可用 |
D3DFMT_G8R8_G8B8 | DXGI_FORMAT_R8G8_B8G8_UNORM(在 DX9 中,数据纵向扩展了 255.0f,但可以在着色器代码中处理)。 |
D3DFMT_DXT1 | DXGI_FORMAT_BC1_UNORM & DXGI_FORMAT_BC1_UNORM_SRGB |
D3DFMT_DXT2 | DXGI_FORMAT_BC1_UNORM和DXGI_FORMAT_BC1_UNORM_SRGB注意:从 API/硬件的角度来看,DXT1 和 DXT2 相同...唯一的区别是“预乘 alpha”,它可以由应用程序跟踪,不需要单独的格式。 |
D3DFMT_DXT3 | DXGI_FORMAT_BC2_UNORM & DXGI_FORMAT_BC2_UNORM_SRGB |
D3DFMT_DXT4 | DXGI_FORMAT_BC2_UNORM和DXGI_FORMAT_BC2_UNORM_SRGB注意:从 API/硬件的角度来看,DXT3 和 DXT4 相同...唯一的区别是“预乘 alpha”,它可以由应用程序跟踪,不需要单独的格式。 |
D3DFMT_DXT5 | DXGI_FORMAT_BC3_UNORM & DXGI_FORMAT_BC3_UNORM_SRGB |
D3DFMT_D16 & D3DFMT_D16_LOCKABLE | DXGI_FORMAT_D16_UNORM |
D3DFMT_D32 | 不可用 |
D3DFMT_D15S1 | 不可用 |
D3DFMT_D24S8 | 不可用 |
D3DFMT_D24X8 | 不可用 |
D3DFMT_D24X4S4 | 不可用 |
D3DFMT_D16 | DXGI_FORMAT_D16_UNORM |
D3DFMT_D32F_LOCKABLE | DXGI_FORMAT_D32_FLOAT |
D3DFMT_D24FS8 | 不可用 |
D3DFMT_S1D15 | 不可用 |
D3DFMT_S8D24 | DXGI_FORMAT_D24_UNORM_S8_UINT |
D3DFMT_X8D24 | 不可用 |
D3DFMT_X4S4D24 | 不可用 |
D3DFMT_L16 | DXGI_FORMAT_R16_UNORM注意:使用着色器中的 .r 重排将红色复制到其他组件以获取 D3D9 行为。 |
D3DFMT_INDEX16 | DXGI_FORMAT_R16_UINT |
D3DFMT_INDEX32 | DXGI_FORMAT_R32_UINT |
D3DFMT_Q16W16V16U16 | DXGI_FORMAT_R16G16B16A16_SNORM |
D3DFMT_MULTI2_ARGB8 | 不可用 |
D3DFMT_R16F | DXGI_FORMAT_R16_FLOAT |
D3DFMT_G16R16F | DXGI_FORMAT_R16G16_FLOAT |
D3DFMT_A16B16G16R16F | DXGI_FORMAT_R16G16B16A16_FLOAT |
D3DFMT_R32F | DXGI_FORMAT_R32_FLOAT |
D3DFMT_G32R32F | DXGI_FORMAT_R32G32_FLOAT |
D3DFMT_A32B32G32R32F | DXGI_FORMAT_R32G32B32A32_FLOAT |
D3DFMT_CxV8U8 | 不可用 |
D3DDECLTYPE_FLOAT1 | DXGI_FORMAT_R32_FLOAT |
D3DDECLTYPE_FLOAT2 | DXGI_FORMAT_R32G32_FLOAT |
D3DDECLTYPE_FLOAT3 | DXGI_FORMAT_R32G32B32_FLOAT |
D3DDECLTYPE_FLOAT4 | DXGI_FORMAT_R32G32B32A32_FLOAT |
D3DDECLTYPED3DCOLOR | 不可用 |
D3DDECLTYPE_UBYTE4 | DXGI_FORMAT_R8G8B8A8_UINT注意:着色器获取 UINT 值,但如果需要 Direct3D 9 样式整型浮点数(0.0f、1.0f...255.f),UINT 只能在着色器中转换为 float32。 |
D3DDECLTYPE_SHORT2 | DXGI_FORMAT_R16G16_SINT注意:着色器获取 SINT 值,但如果需要 Direct3D 9 样式整型浮点数,则 SINT 只能在着色器中转换为 float32。 |
D3DDECLTYPE_SHORT4 | DXGI_FORMAT_R16G16B16A16_SINT注意:着色器获取 SINT 值,但如果需要 Direct3D 9 样式整型浮点数,则 SINT 只需在着色器中转换为 float32。 |
D3DDECLTYPE_UBYTE4N | DXGI_FORMAT_R8G8B8A8_UNORM |
D3DDECLTYPE_SHORT2N | DXGI_FORMAT_R16G16_SNORM |
D3DDECLTYPE_SHORT4N | DXGI_FORMAT_R16G16B16A16_SNORM |
D3DDECLTYPE_USHORT2N | DXGI_FORMAT_R16G16_UNORM |
D3DDECLTYPE_USHORT4N | DXGI_FORMAT_R16G16B16A16_UNORM |
D3DDECLTYPE_UDEC3 | 不可用 |
D3DDECLTYPE_DEC3N | 不可用 |
D3DDECLTYPE_FLOAT16_2 | DXGI_FORMAT_R16G16_FLOAT |
D3DDECLTYPE_FLOAT16_4 | DXGI_FORMAT_R16G16B16A16_FLOAT |
FourCC “ATI1” | DXGI_FORMAT_BC4_UNORM |
FourCC “ATI2” | DXGI_FORMAT_BC5_UNORM |
Direct3D 11 运行时中包含的 ¹DXGI 1.1 包括 BGRA 格式。 但是,对于 Direct3D 10 和 10.1 设备,这些格式的支持是可选的,这些设备适用于 Windows Vista 的 Windows 显示驱动程序模型(WDDM)(WDDM 1.0)。 请考虑改用DXGI_FORMAT_R8G8B8A8_UNORM。 或者,可以使用 D3D10_CREATE_DEVICE_BGRA_SUPPORT创建设备,以确保仅支持安装了 Direct3D 11.0 运行时和 WDDM 1.1 驱动程序或更高版本的计算机。
1.0 定义了 5:6:5 和 5:5:5:5:1 格式,但 Direct3D 10.x 或 Direct3D 11.0 运行时不支持它们。 DirectX 11.1 运行时中的 DXGI 1.2(可选)支持这些格式,这是功能级别 11.1 视频适配器和 WDDM 1.2(从 Windows 8 开始的显示驱动程序模型)所必需的,并且已在 10level9 功能级别上受支持。
1.2 引入了 4:4:4:4:4 格式。 DirectX 11.1 运行时(对于功能级别 11.1 视频适配器和 WDDM 1.2 驱动程序,并且已在 10level9 功能级别上受支持)支持此格式(可选)。
对于未压缩的格式,DXGI 限制了对任意像素格式模式的支持;所有未压缩的格式都必须为 RGBA 类型。 这可能需要重排现有资产像素格式,我们建议尽可能将它作为脱机预处理传递进行计算。
移植着色器
Direct3D 10 着色器在 HLSL 中创作
Direct3D 10 仅将程序集语言的使用限制为调试目的,因此在 Direct3D 9 中使用的任何手写程序集着色器都需要转换为 HLSL。
着色器签名和链接
我们讨论了本文档前面指向顶点着色器输入签名的输入程序集链接的要求(请参阅上文)。 请注意,Direct3D 10 运行时还收紧了阶段到着色器之间暂存链接的要求。 此更改会影响在 Direct3D 9 下可能尚未完全描述阶段之间的绑定的着色器源。 例如:
VS_OUTPUT PS_INPUT
float4 pos : SV_POSITION; float4 pos : SV_POSITION;
float4 uv1 : TEXCOORD1; float4 uv1 : TEXCOORD1;
float4x3 tangentSp : TEXCOORD2; float4 tangent : TEXCOORD2; *
float4 Color : TEXCOORD6; float4 color : TEXCOORD6;
* 断开的 VS - PS 链接 - 即使像素着色器可能对完整矩阵不感兴趣,但链接必须指定完整的 float4x3。
请注意,阶段之间的链接语义必须完全匹配,但目标阶段输入可能是要输出的值的前缀。 在上面的示例中,像素着色器可以将位置和texcoord1 作为唯一输入,但由于排序约束,它不能将位置和texcoord2 作为唯一的输入。
HLSL 着色器阶段链接
着色器之间的链接可能发生在管道中的以下任意点:
- 将汇编程序输入到顶点着色器
- 顶点着色器到像素着色器
- 顶点着色器到几何着色器
- 顶点着色器到流输出
- 几何着色器到像素着色器
- 要流出的几何图形着色器
常量缓冲区
为了便于从 Direct3D 9 移植内容,在效果系统外部进行常量管理的初始方法可能涉及创建包含所有所需常量的单个常量缓冲区。 性能必须按预期更新频率将常量排序到缓冲区中。 此组织将冗余常量集的数量减少到最小值。
功能级别 9 及更高版本 HLSL 中的用户剪辑平面
从 Windows 8 开始,可以在 HLSL 函数声明中使用剪辑平面函数属性,而不是SV_ClipDistance使着色器能够处理功能级别9_x以及功能级别 10 及更高。 有关详细信息,请参阅功能级别 9 硬件上的用户剪辑平面。
用于监视的其他 Direct3D 10 差异
整数作为输入
在 Direct3D 9 中,没有对整数数据类型的实际硬件支持,但 Direct3D 10 硬件支持显式整数类型。 如果顶点缓冲区中有浮点数据,则必须具有浮点输入。 否则,整数类型将是浮点值的位模式表示形式。 除非值标记为无内插(请参阅 内插修饰符),否则像素着色器输入不允许使用整数类型。
鼠标光标
在早期版本的 Windows 上,标准 GDI 鼠标光标例程未在所有全屏独占设备上正常运行。 添加了 SetCursorProperties、ShowCursor 和 SetCursorPosition API 来处理这些情况。 由于 Windows Vista 的 GDI 版本完全理解 DXGI 图面,因此不需要此专用鼠标光标 API,因此没有等效的 Direct3D 10。 Direct3D 10 应用程序应改为对鼠标光标使用标准 GDI 鼠标光标例程 。
将纹素映射到 Direct3D 10 中的像素
在 Direct3D 9 中,纹素中心和像素中心相隔半(请参阅 直接将纹素映射到像素(Direct3D 9) 。 在 Direct3D 10 中,纹素中心已位于半单位,因此根本不需要移动顶点坐标。
使用 Direct3D 10 更直接地呈现全屏象限。 全屏象限应在剪辑空间(-1,1)中定义,只需通过顶点着色器传递,且没有更改。 这样,就无需每次屏幕分辨率更改时重新加载顶点缓冲区,并且像素着色器中无需额外工作来操作纹理坐标。
引用计数行为更改
与以前的 Direct3D 版本不同,各种 Set 函数不会保留对设备对象的引用。 这意味着,只要应用程序希望该对象绑定到管道,应用程序就必须确保它在对象上保留引用。 当对象的 ref 计数下降到零时,该对象将在销毁管道时从管道中取消绑定。 此类型的引用保留也称为弱引用保留,因此,Device 对象上的每个绑定位置都保留对接口/对象的弱引用。 除非另有明确提及,否则应对所有 Set 方法采用此行为。 每当对象销毁导致绑定点设置为 NULL 时,调试层将发出警告。 请注意,对设备 Get 方法(如 OMGetRenderTargets)的 调用会增加所返回对象的引用计数。
测试协作级别
Direct3D 9 API TestCooperativeLevel 的功能类似于在调用 Present 时设置DXGI_PRESENT_TEST。
StretchRect
与 Direct3D 9 IDirect3DDevice9::StretchRect 方法类似的函数在 Direct3D 10 和 10.1 中不可用。 若要复制资源图面,请使用 ID3D10Device::CopySubresourceRegion。 若要调整操作大小,请使用纹理筛选呈现到纹理。 若要将 MSAA 图面转换为非 MSAA 图面,请使用 ID3D10Device::ResolveSubresource。
其他 Direct3D 10.1 差异
Windows Vista Service Pack 1(SP1)包括对 Direct3D 10 和 Direct3D 10.1 的次要更新,其中公开了以下附加硬件功能:
- MSAA 每个样本着色器
- MSAA 深度读回
- 每个呈现器目标的独立混合模式
- 多维数据集映射数组
- 呈现为块压缩格式(BC) 格式
Direct3D 10.1 更新添加了对以下新接口的支持,这些接口派生自现有接口:
Direct3D 10.1 更新还包括以下附加结构:
Direct3D 10.1 API 包含一个名为功能级别的新概念。 此概念意味着可以使用 Direct3D 10.1 API 来驱动 Direct3D 10.0 (D3D10_FEATURE_LEVEL_10_0) 或 Direct3D 10.1 (D3D10_FEATURE_LEVEL_10_1) 硬件。 由于 Direct3D 10.1 API 派生自 Direct3D 10 接口,因此应用程序可以创建 Direct3D 10.1 设备,然后将其用作 Direct3D 10.0 设备,除非需要新的 10.1 特定功能(前提是 存在D3D10_FEATURE_LEVEL_10_1 功能级别并支持这些功能)。
注意
Direct3D 10.1 设备可以使用现有的 10.0 HLSL 着色器配置文件(vs_4_0、ps_4_0、gs_4_0)和新的 10.1 配置文件(vs_4_1、ps_4_1、gs_4_1),以及额外的 HLSL 指令和功能。
Windows 7 包含 Direct3D 10.1 API 的次要更新,该 API 包含在 Direct3D 11 运行时中。 此更新添加了对以下功能级别的支持:
Windows 7 还添加了对 Direct3D 10.1 for Windows 高级光栅化平台(WARP)的支持。 可以使用 D3D10_DRIVER_TYPE_WARP 指定 WARP 驱动程序。
有关 Direct3D 10.1 的详细信息,请参阅 Direct3D 10.1 功能和D3D10_FEATURE_LEVEL1枚举。
相关主题