> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 为什么使用网格着色器？

> 为什么使用网格着色器？

## 传统管线

在过去 20 年里，图形管线不断演进，形成了如今我们熟悉的模样。随着独立硬件供应商（IHV）不断在核心数量、内存容量和带宽方面展开竞争，几何处理模型中的某些固定功能瓶颈也变得日益明显。

**图 1. 传统图形管线。蓝色调阶段是固定功能，绿色调阶段是可编程着色器。**

<img src="https://mintcdn.com/microsoft-4404708b/6hkHc7s12mHcTMCE/images/gdk/features/graphics/ms_legacy_pipeline.png?fit=max&auto=format&n=6hkHc7s12mHcTMCE&q=85&s=d9cba34b670d44348ca3562eb17e0c44" alt="传统图形管线" width="800" height="52" data-path="images/gdk/features/graphics/ms_legacy_pipeline.png" />

这些瓶颈中最棘手的一个是输入装配器（IA）。IA 是位于图形管线顶部的硬件组件，负责处理索引并抓取顶点数据。IA 单元的数量并未按照与其他 GPU 资源相同的速率扩展。少量固定的 IA 单元会带来受限的启动率，往往无法让 GPU 核心的工作负载饱和。

几何管线底部是图元装配器（PA）。这个硬件组件将经过变换的顶点组装成图元、执行剔除和裁剪流程，然后将存活下来的实例转发给光栅化。它有固定的导出速率，维持该速率可能颇具挑战。某些情况下，这可能受 IA 影响——如果着色器波能够以更快的速度启动到管线中，就能并行提交更多图元。更多并行的在飞工作负载可以更好地对 PA 保持压力。

传统图形管线的另一个限制是几何剔除方式有限。被剔除的几何降低了有效吞吐量，浪费了内存带宽和 ALU 对永远不会呈现的顶点属性所进行的加载和着色。理想情况下，我们希望能够以多种粒度进行剔除，尽早剔除几何。

## 网格着色器管线

网格着色器管线针对上述传统图形管线的局限性。首先，它从管线中移除了 IA 和曲面细分器。目的是最大化着色器波的启动速率，将 IA 的职责转移到能够随 GPU 扩展的着色器代码。这有助于使 GPU 核心保持饱和，并对 PA 保持压力。

该管线还提供了在管线中不同位置对工作负载进行剔除的能力。可以使用放大着色器进行低粒度剔除，例如对分组对象、实例或 [meshlets](/build/core-features/graphics/newfeatures/ms/ms-meshlet-render) 的剔除。网格着色器则能够以逐图元粒度进行剔除。这为尽早且频繁地丢弃可轻松剔除的图元提供了一条路径，可节省宝贵的计算资源、内存带宽和 PA 吞吐量。

**图 2. 网格着色器管线的各个阶段。绿色调阶段是可编程的，蓝色调阶段是固定功能。**

<img src="https://mintcdn.com/microsoft-4404708b/6hkHc7s12mHcTMCE/images/gdk/features/graphics/ms_mesh_shader_pipeline.png?fit=max&auto=format&n=6hkHc7s12mHcTMCE&q=85&s=1bdf8c428560eef0a048ae32c01c9759" alt="网格着色器管线的阶段示意图" width="800" height="100" data-path="images/gdk/features/graphics/ms_mesh_shader_pipeline.png" />

## 网格着色器

网格着色器的设计目标是为几何管线提供计算着色器中才有的那种通用性水平。这让开发者能够完全控制每个线程的工作负载。将索引和顶点属性抓取移到着色器代码中消除了对固定功能硬件的依赖，最大化了波启动率，并让 IA 能随着 GPU 的其余部分一起扩展。

它们动态指定顶点和图元导出数量的能力打开了高效、片上支持图元剔除的大门。剔除可以逐 meshlet 或逐图元进行，可基于网格着色器内部任意的剔除标准。这使着色器能够将顶点属性抓取和着色推迟到管线末端，直到已经完成多层剔除之后再进行。

## 放大着色器

计算着色器经常被用于预处理资源，随后通过 ExecuteIndirect 使用其结果发起绘制调用。这是许多逐视图剔除形式的常用技术。它有若干微妙的缺点，若能得到适当的硬件支持则可优化。

其一，计算着色器实例必须将数据写入全局内存。这会带来抓取延迟，并使其受制于 GPU 全局的内存带宽争用。其二，如果计算生产者和图形消费者是连续操作，GPU 必须等待所有计算着色器实例退休后才能启动消费的绘制调用。这是由一个 UAV 资源屏障导致的，该屏障必须确保在任何着色器可以消费之前，所有对最终 UAV 的计算着色器写入都已完成。

**图 3. 一个紧随其后立即调用 ExecuteIndirect "DispatchMesh" 绘制的计算着色器的简化波调度可视化。由于 UAV 屏障，计算着色器波（黄色）与网格着色器波（绿色）的执行之间存在管线停顿。带编号的 ID 将调用它的计算着色器线程组与其子网格着色器集群相关联。**

<img src="https://mintcdn.com/microsoft-4404708b/6hkHc7s12mHcTMCE/images/gdk/features/graphics/ms_schedule_cs.png?fit=max&auto=format&n=6hkHc7s12mHcTMCE&q=85&s=5ea9ae53609437c8168f1b97ea9e501c" alt="简化波调度可视化示意图，展示了一个计算着色器工作负载紧随其后立即通过 DispatchMesh 发起的 ExecuteIndirect 调用。黄色显示的计算着色器波与绿色显示的对应网格着色器波之间因 UAV 资源屏障而存在管线停顿。" width="810" height="96" data-path="images/gdk/features/graphics/ms_schedule_cs.png" />

放大着色器阶段就是为了解决这些问题而设计的。生产者和消费者是管线化的——片上跨阶段内存，没有中间管线冲刷。放大着色器与网格着色器波的调度是交错进行的，可以更充分地让 GPU 保持饱和。

它还开启了传统图形管线中根本不存在的通用工作负载减少或放大能力。可用于实现例如剔除技术、动态实例细节层次（LOD）选择或自定义曲面细分等功能。

**图 4. 一个放大着色器工作负载的波调度可视化。管线中不再有停顿。带编号的 ID 将调用它的放大着色器线程组与其子网格着色器集群相关联。**

<img src="https://mintcdn.com/microsoft-4404708b/6hkHc7s12mHcTMCE/images/gdk/features/graphics/ms_schedule_driver.png?fit=max&auto=format&n=6hkHc7s12mHcTMCE&q=85&s=762afa8cd6264b490a8c4a450e683243" alt="简化波调度可视化示意图，展示了一个放大着色器工作负载。黄色显示的放大着色器波与绿色显示的对应网格着色器波交错执行，管线中的停顿被消除。" width="670" height="95" data-path="images/gdk/features/graphics/ms_schedule_driver.png" />

## 另请参阅

[网格着色器管线概述](/build/core-features/graphics/newfeatures/ms/ms-overview)

[网格着色器 API 概述](/build/core-features/graphics/newfeatures/ms/ms-api-design)

[网格着色器管线用法](/build/core-features/graphics/newfeatures/ms/ms-usage)


## Related topics

- [网格着色器管线 API 概述](/zh-CN/build/core-features/graphics/newfeatures/ms/ms-api-design.md)
- [Meshlet 剔除示例](/zh-CN/build/core-features/graphics/newfeatures/ms/ms-meshlet-culling.md)
- [XBOX Series X|S 上的网格着色器与 Meshlet](/zh-CN/build/core-features/graphics/newfeatures/ms/index.md)
- [为什么使用采样器反馈？](/zh-CN/build/core-features/graphics/newfeatures/sfs/why-sf.md)
- [网格着色器管线概述](/zh-CN/build/core-features/graphics/newfeatures/ms/ms-overview.md)
