Vulkan/Graphics Pipelines

发布时间 2023-12-02 14:06:47作者: 经纬视界

渲染是vulkan最基础的功能,也是众多图形化应用最核心的部分。vulkan的渲染过程可以当作是通过执行不同阶段的命令以此来在展示设备上渲染出图片的过程。

 

vulkan中,渲染管线可以看作是一条生产流水线,命令在管线的开头进入,并且在管线内不同阶段执行。每个阶段都有诸如变换,读取命令或关联的数据,然后变成其他的数据的操作。在管线的结尾,管线内命令就会渲染出许多像素来组成最终画面。

渲染管线的许多部分是可选的,你可以取消它们或者vulkan实现可能根本不支持这部分功能。管线内唯一必须启用的功能是顶点着色器(vertex shader)。整条vulkan的渲染管线由下图展示。然而,看到该图时不必惊慌,我们会在章节内逐阶段的介绍它们,深挖它们的细节。

 

下面是对管线内每阶段的简单介绍:

  • 绘制(Draw):这是vulkan渲染管线中命令进入的起点。一般来说,vulkan设备内的一个小处理器或专用硬件会解释command buffer中的命令,并且直接用硬件与之交互。
  • 输入装配(Input assembly):该阶段会读取包含顶点信息的顶点缓冲(vertex buffer)和索引缓冲。(index buffer)
  • 顶点着色器(Vertex shader):这里是顶点着色器执行的步骤。它会将顶点的各属性当作输入,为下个阶段准备由变换操作和生成操作而产生的顶点数据。
  • 细分曲面控制着色器(Tessellation control shader):这是一个可编程的着色阶段,负责产生细分因子(tessellation factors)和其他面片(patch)数据,这些数据会被其他固定功能的细分阶段使用。
  • 细分曲面图元生成(Tessellation primitive generation):没有在图中展示,该固定功能的阶段使用在细分曲面控制着色器中产生的细分因子将片面图元打碎成更小,更简单的图元,这些打碎后的图元会在细分曲面评估着色器中使用。
  • 细分曲面评估着色器(Tessellation evaluation shader):该着色阶段会在每个由曲面细分图元生成阶段产生的新的顶点上运行。它与顶点着色器类似,不过顶点数据是程序产生的而不是从内存中读取的。
  • 几何着色器(Geometry shader):该着色阶段使用整个图元。一个图元可能是点、线、三角形或者以上的变体,包括围绕它们的额外顶点。该阶段还可以在管线中改变图元类型。
  • 图元装配(Primitive assembly):该阶段会使用上述由顶点着色器,细分曲面阶段或几何着色器产生的顶点,将它们组装成适合光栅化的图元。也会裁剪、变换图元以适应视口。
  • 裁剪(Clip and cull):该固定阶段会决定哪些图元是对最终图像生成具有贡献的,从而忽略掉那些毫无贡献的成员,然后将潜在的可视图元转发给光栅器。
  • 光栅化(Rasterizer):光栅化是vulkan中的核心基础。光栅器会读取由一系列顶点组成的图元,然后将他们变成一个个独立的片元,它们将来可能就是你最终图像的像素。
  • 片元预处理(Prefragment operations):有些处理可以发生在片元着色之前,比如深度和模板测试。
  • 片元装配(Fragment assembly):没有在图片中展示,片元装配组装光栅化后的输出和每个片元的数据,然后把他们发送给片元着色器。
  • 片元着色器(Fragment shader):该阶段是管线最后运行的着色器,负责给最后固定功能阶段计算片元数据。
  • 片元后处理(Postfragment operations):某些情况下,片元着色器修改了片元预处理过的数据,需要再次进行一边和预处理一样的操作。
  • 颜色混合(Color blending):颜色运算读取片元着色器和片元后处理产生的最后结果,然后使用它们更新到帧缓冲中。颜色运算包括混合和逻辑运算。

正如看到的,渲染管线中有很多互相关联的阶段。不像运算管线(Compute Pipeline),渲染管线不仅包含配置大量的固定功能的阶段,还包括做多五个着色器的使用。此外,根据不同实现,某些固定阶段实际上部分在驱动生成的着色器代码中执行。

vulkan中,将渲染管线看作一个对象的具体原因是为了提供尽可能多的信息,以便让管线在固定阶段和可编程着色器之间进行移动。如果我们不能在同一时间在同一对象内获取全部信息,vulkan实现就可能需要根据配置状态来重新编译着色器。渲染管线内包含的各个状态是经过细致的选择,正是为了避免上述情况,让管线的状态转换变得尽可能快。