Vulkan填坑学习Day01—框架综述

Vulkan教程代码框架

一、环境搭建

主要是Windows上,下载Vulkan SDK,下载GLFW(Graphics Library Framework),下载GLM(OpenGL Mathematics),配置VS,验证Vulkan扩展。

二、目标及步骤

以创建三角形为例(后续将逐步一一进行学习代码更新):

1.实例和物理设备选取;
2.逻辑设备和队列族;
3.窗口表面和交换链;
4.图像视图和帧缓冲;
5.渲染通道;
6.图形管线;
7.命令池和命令缓冲;
8.主循环渲染。

三、具体步骤解析

(1)步骤一:实例和物理设备选取

第一步就是要建立Vulkan实例,这也是Vulkan应用程序的起始。通过描述你的应用程序和你将要使用什么API扩展来创建实例,之后查询Vulkan支持的硬件并选择一个或多个VkPhysicalDevice。

(2)步骤二:逻辑设备和队列族

第二步就要传将逻辑设备VkDevice了,此时你要更详细描述你需要使用哪些VkPhysicalDevice特性,比如多视口渲染和64位浮点数等。还要指定使用哪些队列族。大多数的Vulkan操作,如绘制命令和内存操作,都是提交到VkQueue中异步执行的。队列是从队列族中分配出来的,每个队列族支持一组特定操作。例如,图形、计算和内存转移操作可能有着单独的队列族。队列族的可用性也可以用作物理设备选取的一个显著因素。可能一个支持Vulkan的设备却不提供图形功能,但是当前阶段的显卡支持Vulkan的都基本支持了我们所需的队列操作。

(3)步骤三:窗口表面和交换链

第三步就是创建窗口和呈现渲染好的图像了。这需要两个组件,一个窗口表面(VkSurfaceKHR)和一个交换链(VkSwapchainKHR)。KHR后缀表示这些对象是Vulkan扩展的一部分。Vulkan API本身是跨平台的,表面则是要渲染到的窗口的跨平台抽象,通常用一个原生窗口句柄引用来实例化,例如Windows平台上就是HWND。

交换链就是一批渲染目标,它的基本目的就是保证我们当前渲染的图像和已经在屏幕上的那个是不一样的。保证只显示完整图像时很重要的,每次我们想要绘制一帧的时候都要向交换链请求提供一个图像。当我我们完成一帧的绘制后就将图像返回给交换链以便它在某个时候呈现到屏幕上。渲染目标个数以及将完成的图像呈现到屏幕上所需的条件依赖于呈现模式。常见的呈现模式有双缓冲(垂直同步)和三缓冲。

(4)步骤四:图像视图和帧缓冲

第四步,为了绘制从交换链获取的图像,将它包装成VkImageView和VkFramebuffer。图像视图引用了要用的图像的某个特殊部分,帧缓冲引用了用于颜色、深度和模板目标的图像视图。因为交换链中可能有很多不同图像,我们预先为每个图像创建一个图像视图和一个帧缓冲,然后在绘制的时候选择正确的那个。

(5)步骤五:渲染通道

第五步,Vulkan的渲染通道描述了渲染操作中用的图像的类型,以及如何使用它们,如何对待其内容。对于这个教程的三角形程序来说,我们就告诉Vulkan我们将使用单个图像作为颜色对象,且要在绘制操作之前被清空为一个纯色。然而渲染通道只描述了图像类型,VkFramebuffer实际上会向这些槽绑定特定的图像。

(6)步骤六:图形管线

第六步,Vulkan的图形管线通过创建一个VkPipeline对象来建立,它描述了显卡的可配置状态,比如视口大小和深度缓冲操作以及使用VkShaderModule对象时的可编程状态。VkShaderModule对象是从着色器代码创建的,我们会通过引用渲染通道指定。

Vulkan和现有API相比最显著的特性是它的所有图形管线配置都要提前设置。这意味着如果你想要切换到一个不同的着色器,或者稍微改变顶点布局,你都要完全重建图形管线。这也意味着你要为所有你想要的渲染操作的不同组合提前建立许多VkPipeline对象。只有一些基础配置,如视口大小和颜色清除等可以动态改变。所有的状态都要明确描述,比如,连默认颜色混合状态都没有。

好消息是,因为你相当于在做提前编译而不是即时编译,驱动就会有更多的优化机会,运行时也更容易得到可预测的表现,因为像切换到不同图形管线这也的大型状态改变都是明确设定好的。

(7)步骤七:命令池和命令缓冲

第七步,命令池和命令缓冲。就和之前提到的一样,Vulkan中许多的操作像绘制命令等都要提交到一个队列中。这些操作首先需要记录到VkCommandBuffer,然后才能提交。这些命令缓冲是从VkCommandPool分配的,VkCommandPool又和一个特定队列族相关联。为了绘制一个简单的三角形,我们要用如下操作来记录一个命令缓冲:

开始渲染通道;
绑定图形管线;
绘制三个顶点;
结束渲染通道。

因为帧缓冲中的图像依赖于交换链到底给我们哪一个图像,我们要为每个可能的图像记录命令缓冲并在绘制的时候选择正确的那个。

(8)步骤八:主循环渲染

第八步就是主循环了。现在绘制命令已经包装成一个命令缓冲,主循环就比较直白了。首先用vkAcquireNextImageKHR从交换链获取图像,然后为该图像选择合适的命令缓冲,用vkQueueSubmit执行。最终,返回图像到交换链以便用vkQueuePresentKHR呈现到屏幕。

提交到队列的操作是异步执行的,因此我们必须用类似信号量的同步对象来确保正确的执行顺序。绘制命令缓冲的执行一定要等待图像获取完成,否则可能会在渲染的时候用了一个还在读取用于展示到屏幕上的图像。vkQueuePresentKHR调用需要等待渲染完成,要使用第二个信号量来标记渲染完成。

四、小结

绘制一个三角形要做的工作如下:

创建一个VkInstance;

选择一个支持的显卡(VkPhysicalDevice);

创建一个VkDevice和一个VkQueue来绘制和呈现;

创建一个窗口,窗口表面和交换链;

将交换链图像包装到VkImageView;

创建一个渲染通道来指定渲染目标和用法;

为渲染通道创建帧缓冲;

建立图形管线;

用绘制命令为每个可能的交换链图像分配和记录命令缓冲;

通过获取图像来绘制帧,提交正确的绘制命令缓冲并返回图像到交换链。

发布了13 篇原创文章 · 获赞 0 · 访问量 336

猜你喜欢

转载自blog.csdn.net/qq_35312463/article/details/103813010
今日推荐