目前,我们通过在着色器中硬编码顶点数组来渲染三角形。现在我们将更改代码,以相同的方式渲染三角形,但不再硬编码顶点,而是使用 CPU 数组和顶点输入布局。
顶点缓冲区
在 Vulkan 中,您可以分配 GPU 可见的内存,并从着色器中读取它。您可以为两个目的分配内存,用于图像和缓冲区。我们已经使用图像作为渲染通道和交换链的一部分,但是在着色器中使用它们可能很复杂,因此我们将其留到后面的章节中。图像主要用于 2d 或 3d 数据,例如纹理,您希望从着色器访问它的任何部分。
另一种类型是缓冲区,它们只是一堆 GPU 可以看到并写入/读取的内存。缓冲区有多种类型,它们可以以不同的方式使用。在这里,我们将创建一个缓冲区并将其用作顶点缓冲区,这将允许 GPU 从缓冲区读取数据并将其发送到我们的顶点着色器。
要从着色器读取顶点缓冲区,您需要在管线上设置顶点输入状态。这将让 Vulkan 知道如何将给定的缓冲区解释为顶点数据。一旦设置好,我们将能够自动将顶点信息(例如顶点颜色或顶点位置)获取到顶点着色器中。
如果您熟悉 OpenGL 和 DirectX,则这种类型的缓冲区的工作方式或多或少与它们相同。
内存分配
所有缓冲区和图像都需要在内存分配之上创建。由于我们不想在本教程中实现内存分配器,因此我们将使用 AMD 创建的 Vulkan Memory Allocator (VMA) 库,它将为我们抽象化这一点。
总分配数由驱动程序固定,并且可以低至 1024。如果每个缓冲区或图像都放置在自己的内存分配中,则很容易超过此最小值,因此典型的策略是从驱动程序分配大块内存,然后将缓冲区和图像子分配到其中,使用 Vulkan Memory Allocator (VMA) 等库或自己实现分配器。
如果您查看台式计算机,您会看到 GPU 具有与主系统内存 (RAM) 分开的内存 (VRAM)。这些不同的域称为堆。在这些堆中,驱动程序可以公开针对特定用例优化的内存区域,称为内存类型。即使在集成 GPU(没有专用 VRAM)上,也可能从单个堆中获得多种内存类型。Vulkan 完全控制在何处分配数据,无论是在原生 GPU VRAM 上还是在 CPU RAM 上。VMA 库为我们稍微抽象了这一点,但了解这一点仍然非常重要。
目前,我们将把所有缓冲区都分配到 CPU RAM 上,因为这实现起来容易得多,而且目前我们不需要性能。
顶点输入布局
如果您来自 OpenGL,您可能了解顶点属性,您可以在其中让 OpenGL 知道如何在顶点着色器上读取顶点数据,然后 OpenGL 为您获取数据。在 Vulkan 中,它的工作方式非常相似。当您创建管线时,可编辑对象之一是顶点输入布局,我们现在将其留空。我们可以填写它,让 Vulkan 知道如何解释着色器的顶点数据。
让我们开始实现将硬编码三角形转换为非硬编码三角形所需的内容!
下一步:实现顶点缓冲区