资源是 3D 管道使用的数据集合。 创建资源并定义其行为是编程应用程序的第一步。 本指南介绍用于选择应用程序所需的资源的基本主题。
确定需要资源的管道阶段
第一步是选择将使用资源的 图形管道 阶段(或多个阶段)。 也就是说,标识将从资源读取数据的每个阶段,以及将数据写入资源的各个阶段。 了解资源将在哪些管道阶段被使用,可以确定将调用哪些 API 来将资源绑定到这些阶段。
下表列出了可绑定到每个管道阶段的资源类型。 它包括资源是否可以作为输入或输出绑定。
| 管道阶段 | 输入/输出 | 资源 | 资源类型 |
|---|---|---|---|
| 输入汇编器 | 在 | 顶点缓冲区 | 缓冲区 |
| 输入汇编器 | 在 | 索引缓冲区 | 缓冲区 |
| 着色器阶段 | 在 | Shader-ResourceView | Buffer、Texture1D、Texture2D、Texture3D |
| 着色器阶段 | 在 | Shader-Constant 缓冲区 | 缓冲区 |
| 流输出 | 出局 | 缓冲区 | 缓冲区 |
| 输出合并 | 出局 | 渲染目标视图 | Buffer、Texture1D、Texture2D、Texture3D |
| 输出合并 | 出局 | 深度/模板视图 | Texture1D、Texture2D |
确定如何使用每个资源
选择应用程序将使用的管道阶段(因此每个阶段所需的资源)后,下一步是确定每个资源的使用方式,即 CPU 还是 GPU 可以访问资源。
应用程序运行的硬件至少需要一个 CPU 和一个 GPU。 若要选取使用值,请考虑以下选项中需要读取或写入资源的处理器类型。
| 资源使用情况 | 可以通过以下方式更新 | 更新频率 |
|---|---|---|
| 违约 | 图形处理器 (GPU) | 很少 |
| 动态 | 中央处理器 | 经常 |
| 分期 | 图形处理器 (GPU) | n/a |
| 不可变的 | CPU(仅限于资源创建时) | n/a |
默认用法适用于预期由CPU不频繁更新的资源(少于每帧更新一次)。 理想情况下,CPU 永远不会直接写入默认使用的资源,以避免潜在的性能损失。
动态使用应该用于 CPU 相对频繁更新的资源(每帧更新一次或更多次)。 动态资源的典型方案是创建动态顶点和索引缓冲区,该缓冲区将在运行时填充,其中包含每个帧用户视点可见的几何图形数据。 这些缓冲区将仅用于呈现该帧的用户可见的几何图形。
暂存用法用于在不同资源之间复制数据。 典型的情况是,将数据从默认不可由 CPU 访问的资源复制到可以由 CPU 访问的暂存资源。
当资源中的数据永远不会更改时,应使用不可变资源。
另一种理解同一想法的方法是考虑应用程序如何使用资源。
| 应用程序如何使用资源 | 资源使用情况 |
|---|---|
| 加载一次且永不更新 | 不可变或默认 |
| 应用程序重复填充资源 | 动态 |
| 渲染到纹理 | 违约 |
| CPU 对 GPU 数据的访问 | 分期 |
如果不确定要选择什么用法,请从默认用法开始,因为预期是最常见的情况。 Shader-Constant 缓冲区是应始终具有默认用法的资源类型。
将资源绑定到管道阶段
只要满足创建资源时指定的限制,资源就可以同时绑定到多个管道阶段。 这些限制被指定为使用标志、绑定标志或 CPU 访问标志。 更具体地说,只要无法同时读取和写入部分资源,资源就可以同时绑定为输入和输出。
绑定资源时,请考虑 GPU 和 CPU 将如何访问资源。 设计为单一用途的资源(不使用多个用途、绑定和 CPU 访问标志)可能会带来更好的性能。
例如,请考虑多次用作纹理的渲染目标的情况。 可能更快的方法是使用两个资源:一个是渲染目标,另一个是作为着色器资源使用的纹理。 每种资源只使用一个绑定标记,用于指示“渲染目标”或“着色器资源”。 数据将从呈现目标纹理复制到着色器纹理。
在此示例中,该技术可以通过将渲染目标写入与着色器纹理读取隔离开来提高性能。 唯一的一种方法是实现这两种方法并衡量特定应用程序中的性能差异。
相关主题