流水线
流水线(Pipeline)是理解D3D必须要掌握的概念。
整个流水线有很多步骤,有的步骤是固定功能,不用怎么配置,有的步骤是要写代码的,也就是所谓的着色器程序(Shader)。
一般来说,将流水线分为两类:渲染流水线和计算流水线。严格地说并这有这么明确的区分,因为他们都可以干别的事。但这里还是按这种分类来说。
渲染流水线
最开始的显卡加速器使用硬件的顶点变换来实现3D加速。现在几乎可以在显卡上实现任何算法了。
下图是具体的流程:
蓝底的是可编程的步骤,绿底的是固定功能的步骤。每一步都定义了输入和输出。
Input Assembler:是入口,负责从资源(Resource)中读取输入数据,然后装配成顶点(Vertex)。支持使用多个顶点Buffer和实时渲染。
Vertex Shader:每次读取一个顶点数据。这一步是可编程的,但不能创建或销毁顶点,只能处理上一步得到的顶点。另外,每个顶点的处理都是单独的,意思是说每个顶点着色器(Vertex Shader)都不能访问其他的顶点着色器。顶点着色器主要负责将顶点映射到合适的空间上。一般来说,顶点都是由顶点着色器处理的。
Tessellation(镶嵌) Stage:这3个步骤是新加入的步骤,必须同时使用。
- Hull Shader:从顶点着色器接收数据。对每个Primitive确定一组镶嵌因子,告诉Tessellator如何拆分。还要创建控件点,让Domain Shader创建镶嵌顶点。
- Tessellator:拆分Primitive。输出barycentric coordinates(重心坐标)。
- Domain Shader:得到重心坐标和控制点,然后创建新的顶点。传给Geometry Shader。
Geometry Shader:处理几何Primitive,并且产生几何Primitive。这一步可以添加和删除数据元素。另外,它还可以转换几何Primitive的类型。
这一步完成后,几何级别的操作也就完成了。然后进入Fragment级别的处理。Fragment本质上是一组对应于渲染目标上的像素的数据。
Rasterizer:将几何Primitive栅格化,生成Fragment,并对每个Fragment生成深度值。
Pixel Shader:得到Fragment后,对Fragment生成颜色值。
Output Mander:合并Pixel shader输出的值。最后输出成程序资源。
计算流水线
这是一个新概念。计算流水器使用计算着色器(Compute Shader)来执行一些单独的功能。它可以:
- 使用GPU实现并行计算。
- 使用分组分享内存(Group Shared Memory),使线程间可以通信。