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 调用将操作联系在一起;绘制调用之前调用的顺序是任意的。 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 开销 (。 为了降低成本,已为所有类型的设备数据分配了一个对象,其中包含设备本身提供的显式创建方法。 这样就可以在对象创建时进行严格的数据验证,而不是像 Direct3D 9 一样,在 Draw 调用期间进行严格的数据验证。
引擎抽象/分离
希望同时支持 Direct3D 9 和 Direct3D 10 的应用程序(包括游戏)需要从代码库的其余部分抽象化呈现层。 实现此目的的方法有很多种,但所有这些方法的关键是设计较低级别的 Direct3D 设备的抽象层。 所有系统都应通过公共层与硬件通信,该层旨在提供 GPU 资源和低级别类型管理。
直接删除 Direct3D 9 依赖项
移植之前测试过的大型代码库时,请务必尽量减少对保留代码中以前测试的行为绝对必要的代码更改量。 最佳做法包括使用注释清楚地记录项更改的位置。 为此工作制定注释标准通常很有用,以便快速导航代码库。
下面是可用于此工作的标准单行/开始块注释的示例列表。
项 | 说明 |
---|---|
Direct3D 10 已删除 |
在删除行/代码块的位置使用此 |
Direct3D 10 需要更新 |
它有助于向 NEED UPDATE 注释添加其他说明,建议以后访问代码时应使用哪些工作/新 API 进行行为转换。 在发生 Direct3D 10 NEEDS UPDATE 时,还应大量使用断言 (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 应用程序。 但是,可以使用早期 2003 版本的 Visual Studio 生成依赖于 Direct3D 10 的 Windows Vista 应用程序。 Direct3D 10 是 Windows Vista 平台组件,其依赖项 (与 Server 2003 SP1 平台 SDK) 在以下 lib 上一样:需要 BufferOverflowU.lib 来解决任何buffer_security 检查链接器问题。
模拟设备 CAP
许多应用程序包含依赖于可用的设备 CAPS 数据的代码区域。 通过重写设备枚举并将设备 CAPS 强制为合理的值来解决此问题。 计划稍后重新访问存在 CAPS 依赖项的区域,以便在可能的情况下完全删除 CAPS。
驱动 Direct3D 10 API
本部分重点介绍 Direct3D 10 API 导致的行为更改。
- 资源创建
- 视图
- 静态资源访问与动态资源访问
- 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 的创建、锁定、填充、解锁设计点进行设计,则可以使用临时资源和资源接口上的 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 的功能与 2006 年 12 月 () DirectX SDK 中提供的 HLSL 编译器的功能相同。 此 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 带来的main区别在于创建的 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 设备呈现状态/纹理状态设置可能会有所帮助。 这会导致呈现项目,但这是启动和运行内容的最快方法。 稍后可以构造一个状态对象管理系统,该系统可以使用复合键来最大程度地重用正在使用的状态对象数。
移植纹理
支持的文件格式
例如 ,D3DX10CreateXXX 和 D3DXxxSaveXXX 函数 (图形文件创建或保存纹理,例如 ,D3DX10CreateTextureFromFile) 在 Direct3D 10 中支持与 Direct3D 9 中不同的一组文件格式:
文件格式 | Direct3D 9 | Direct3D 10 |
---|---|---|
.bmp | x | x |
.jpg | x | x |
.tga | x | |
.png | x | x |
.dds | x | x |
。Ppm | x | |
.dib | x | |
。Hdr | x | |
。烤 瓷 | x | |
.tiff | x | |
.gif | x | |
.tif | x |
有关详细信息,请将 Direct3D 9 D3DXIMAGE_FILEFORMAT 枚举与 Direct3D 10 的D3DX10_IMAGE_FILE_FORMAT 枚举进行比较。
注意
D3DX (D3DX 9、D3DX 10 和 D3DX 11) 实用工具库已弃用Windows 8。 对于纹理文件处理,建议使用 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 2 |
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 | 在 DX9 中DXGI_FORMAT_R8G8_B8G8_UNORM (,数据纵向扩展了 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 运行时中包含的 1.1DXGI 1.1 包含 BGRA 格式。 但是,对于 Direct3D 10 和 10.1 设备,这些设备的驱动程序实现到 Windows Vista (WDDM 1.0) 的 Windows 显示驱动程序模型 (WDDM) 是可选的。 请考虑改用 DXGI_FORMAT_R8G8B8A8_UNORM。 或者,可以使用 D3D10_CREATE_DEVICE_BGRA_SUPPORT 创建设备,以确保仅支持安装了 Direct3D 11.0 运行时和 WDDM 1.1 驱动程序的计算机。
²DXGI 1.0 定义了 5:6: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 功能级别上受支持。
2DXGI 1.2 引入了 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 函数不会保存对设备对象的引用。 这意味着,只要希望该对象绑定到管道,应用程序就必须确保它保留对 对象的引用。 当对象的引用计数下降到零时,对象将在销毁时从管道中解绑定。 这种引用保留方式也称为弱引用保留,因此 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 的次要更新,该更新包含在 Direct3D 11 运行时中。 此更新添加了对以下功能级别的支持:
Windows 7 还添加了对适用于 Windows 高级光栅化平台的 Direct3D 10.1 的支持 (WARP) 。 可以使用 D3D10_DRIVER_TYPE_WARP 指定 WARP 驱动程序。
有关 Direct3D 10.1 的详细信息,请参阅 Direct3D 10.1 功能和D3D10_FEATURE_LEVEL1 枚举。
相关主题