10-geometry-shaders

第 10 篇:几何着色器(Geometry Shaders)

原文:Part 10

一句话定位

几何着色器以完整图元为输入,并可输出数量可变的新图元;它揭示了“API 中存在一个阶段”并不意味着芯片上必有一个同名独立硬件块。

功能模型与实现模型

API 图会把 GS 永远画在流水线中,即使应用没有绑定 GS;这便于定义功能语义。硬件为了效率,未启用时通常直接旁路,而启用时可能复用通用 shader core,再由固定功能的输入/输出逻辑完成图元拆装。

flowchart LR P[装配后的图元<br/>可含邻接信息] --> D[GS 派发] D --> S[通用 Shader Core] S --> B[可变长度输出缓冲] B --> A[重新装配输出图元] A --> R[Rasterization] B --> SO[可选 Stream-Out]

与 VS/PS 的共性

多个 shader stage 都可抽象为:固定功能单元准备输入 → 聚合批次 → 通用执行单元运行程序 → 结果暂存/排序 → 下一阶段消费。区别主要在输入记录形状、输出协议以及是否存在可变数量输出。

因此读驱动时,不要为每个 API shader stage 预设一套独立执行硬件。很多架构共享指令集、寄存器文件和执行核心,只在前后端控制与可访问系统值上不同。

可变放大的代价

GS invocation 可发出零个、一个或多个图元,导致:

  • 输出大小运行前不完全确定,需要预留或分块管理缓冲;
  • 不同 invocation 的输出量差异会造成负载不均;
  • 需要维持同一 invocation 内的 strip/restart 语义及 invocation 之间的必要顺序;
  • 大幅 amplification 会把瓶颈从 shader ALU 转移到输出带宽、缓冲容量或后续光栅化。

GS 能表达点扩展、图层选择、少量几何生成等功能,但“能做”不等于“是最高吞吐路径”。若工作可由 instancing、tessellation、mesh/task 类阶段或 compute 预处理表达,应结合目标硬件测量。

邻接与多次调用

带 adjacency 的拓扑会给 GS 提供邻接顶点,便于轮廓等算法,但输入记录更大、装配更复杂。GS instancing 让同一输入图元触发多个 invocation;它增加并行工作,也放大输出与排序压力。

术语对照

英文 中文理解 说明
Geometry Shader 几何着色器 以图元为输入,可生成图元
adjacency 邻接信息 向 invocation 额外提供邻接顶点
amplification 几何放大 输出图元数大于输入
emit / cut 发射 / 截断 strip GS 输出协议的一部分
GS instancing GS 多实例 同一输入图元运行多个 invocation
bypass 旁路 未启用阶段时直接跳过硬件工作

面向 UMD/KMD 的阅读提示

  • 编译器后端要处理 GS 输入布局、输出 ring、emit/cut 和最大输出顶点数。
  • UMD 需配置中间缓冲大小、图元类型、invocation count 和后续 raster/stream-out 路径。
  • 查找“ring buffer”时先辨别它是命令 ring 还是 shader stage 间的数据 ring;同名概念用途完全不同。
  • KMD 通常只管理承载这些 ring/状态的内存与提交,不参与几何放大策略。

自测与实验

  • 为什么可变输出比固定一进一出的 VS 更难缓冲?
  • 未绑定 GS 时,API 图中的 GS 阶段为何仍可在硬件上完全不存在?
  • 固定总输出三角形数,比较一次调用高 amplification 与更多输入/低 amplification,观察吞吐差异。

本篇总结

GS 的关键挑战不是“对三角形运行一段代码”,而是把可变长度、可能放大的输出重新组织成有序、可继续消费的数据流。

posted @ 2026-10-26 21:59  Sailxiv  阅读(3)  评论(0)    收藏  举报