这里是我学习完Vulkan基本操作后的一个总结,主要讲述了各个部分的功能。
对Vulkan各个部分的解释
整个Vulkan其实就下面两张图:
首先是这个不包含渲染管线的图,其中的各个步骤解释如下:
VkInstance
:这个是Vulkan最基本的,需要最先创建的结构,包含了Vulkan的所有信息VkPhysicalDevice
:这个结构体对应着物理硬件显卡,一般我们需要从众多显卡中挑选一个适合的显卡来工作。显卡可以做两个工作:图形渲染(Graphic)和GPU计算(Compute)。VkDevice
:在挑选完显卡后,我们需要根据现有的显卡创建一个软件上的逻辑显卡,这是因为我们没有办法直接操纵显卡(只有着色器可以直接运行在显卡上,我们的代码不行),而是需要先在逻辑设备上完成一些事情,让逻辑设备和显卡沟通。VkQueue
:这个在创建逻辑设备的同时会被创建,是一个命令队列,用于将我们的命令缓冲提交给显卡,显卡再从命令缓冲中将命令拿出来执行。VkCommandPool
:命令池,这个就和线程池和内存池一样,就是为了更好地利用内存而诞生的。VkCommandBuffer
:命令缓冲,可以从命令池创建,是一个缓冲,用于记录一些的命令,到时候可以被命令队列提交到显卡去执行。VkSwapchain
:交换链,交换链中有很多的图像,GPU可以对其中的图像进行操作,并且交换链本身也可以将图像交给显示屏渲染(主要就是交给显示屏渲染)。VkImage
:存储在内存中的图像。VkImageView
:VkImage不能直接访问其属性,需要VkImageView来得到其属性(包括Image的大小,色彩空间,色彩格式等)
一般来说,Vulkan的步骤就是创建好上面的东西之后,通过将命令放入命令缓冲,然后将命令缓冲提交到命令队列,命令队列再将其提交到GPU中执行就可以了。
至于GPU中究竟如何执行,第一是看你的命令,第二如果你是图形方面的命令,还要看渲染管线怎么设置:
渲染管线指定了我们需要如何渲染一个图像。其中最后边的是其渲染流程,从顶点输入到颜色混合,每个阶段都是可由代码指定的。另外还有三个阶段分别对应三个着色器(顶点着色器,细分着色器,片段着色器)。
在管线状态中:
dynamic state
是用来确定uniform
变量数据的阶段vertex input state
则是从内存输入顶点到着色器的阶段,这个阶段会看layout
关键字指定的着色器数据,并且将顶点数据给着色器input assembly state
则是告诉GPU需要将输入的点都按照什么样的形状连在一起(三角形,直线,点)rasterization state
则决定如何光栅化color blend state
决定如何进行颜色混合(是不是用透明色,颜色空间如何)viewport state
则指定了屏幕的视口和大小depth stencil state
会对图像进行深度和模板测试- 最后是多重采样,指定如何使用采样和抗锯齿。
显然,渲染管线内定义了这么多阶段,但是就是没有定义这些阶段需要用在什么图像上。这里渲染通道(Renderpass)就是干这个事情的,它会做两件事:
- 指定渲染管线工作的图像集(VkFramebuffer)。
- 指定图像从CPU到GPU,在从GPU到屏幕之间的数据格式的转变(pipeline layout)。
而framebuffer,从图中也可以看出,是会存储多个VkImage的缓冲区(就是一组VkImage)。正如图中所示,不管是深度缓冲还是模板缓冲,颜色缓冲,都需要在VkImage上进行操作。如果你需要对一个可显示的图像使用深度缓冲的话,你就需要一个存储颜色数据的VkImage和一个存储深度信息的VkImage,如果你想要加上模板缓冲的话还得加一个存储模板缓冲信息的VkImage。Framebuffer就是将这些缓冲对应的VkImage存储在一起,告诉管线:“你在做颜色混合,深度和模板缓冲的时候用这些VkImage”。
小结
Vulkan的确很麻烦,但是不是很难,因为其将所有的阶段全部展现出来了,让我能够更加清楚地了解到渲染的整个过程,弄懂了这些过程,感觉用起来就比较简单了😁。