交换链是一种图元绘制结果呈现的机制,它可以将绘制结果渲染到平台相关的展示窗口/展示层当中。交换链中可能包含了一个或者多个绘制结果的图像。这些绘制图像被称作颜色图。颜色图其实就是一组像素信息,按照特定的排列方式保存在内存中。交换链中的图像个数与驱动层的实现是密切相关的。如果交换链中有两幅图像,那么称为双缓存,如果有三幅图像,那么称作三缓存。
在这些图像中,如果有一幅图像在后台已经完成了绘制过程,那么它会被交换到前台的展示窗口。为了充分利用GPU的性能,此时另一幅图像会交换作为后台的缓存来执行下一帧的绘制过程。这个过程往复执行,图像的交换过程也就持续进行。使用多幅图像可以保持GPU始终处于渲染某一帧图像的忙碌状态,从而降低总体的等待时间,改善输出帧速率。
绘制图像的交换或者说翻转过程完全依赖于展示的模式。它的更新频率可能与垂直刷新间隔(Vertical Blanking Interval,VBI)相关,也可能是一旦可以进行绘制就触发更新。换句话说,就是每当显示器刷新的时候,背景图像都会和前景图像进行交换,从而显示一幅新的画面。交换链功能可以通过扩展API的形式调用,此时需要首先启用VK_KHR_SWAPCHAIN_EXTENSION_NAME
。
交换链实现的工作流
如图所示给出了有关交换链从开始到结束的完整实现的流程图。图中使用简明的短语描述了整个流程中的每个步骤,帮助读者形成整体的概念。
我们首先浏览这个流程,快速地了解一下每个步骤所对应的基本内容。
1)创建空白窗口:这一步需要提供一个空白的本地平台窗口,并且与交换链的颜色图相关联。每当我们写入新的一帧(一幅图像)时,它都会被交换到展示层。展示层记录了本地窗口的属性信息用作显示之用。
2)查询交换链扩展:交换链API并不属于标准API的一部分。它们的实现与系统平台相关,需要加载器将这些API作为扩展的形式加载进来。加载后的扩展通过函数指针的方式进行保存,对应的声明内容被预先存储在Vulkan的标准当中。
3)创建表面并且关联到之前的窗口:这一步需要创建一个平台相关的逻辑表面对象。这个时候,它并没有为内部的颜色图像分配任何内存空间。逻辑表面对象与之前的空白窗口相关联,将这个窗口作为自己的拥有者记录。
4)获取可用的图像格式:在这一步当中,我们需要查询物理设备,并检查它所支持的图像格式。
5)查询交换链图像表面属性:这一步需要获取基本表面属性的信息,并用它来创建交换链的图像。换句话说,这一步当中需要检查当前的展示属性是否是可用的。
6)管理展示模式信息:这一步使用展示属性的信息,决定交换链当中需要用到哪种展示属性方法。交换链的展示属性决定了输入的展示请求是否会被内部执行和查询到。
7)创建交换链,获取颜色图像:我们可以使用上述信息来创建交换链的图像了。WSI的扩展函数会返回颜色图对象,它们的类型为VkImage,可以在应用程序中使用。
WSI扩展返回的图像并不是应用程序所有的,它们属于WSI,因此不能使用图像布局。图像布局只能应用于应用程序所有的图像对象上。
8)创建颜色图像视图:根据系统参数的不同,WSI扩展函数可能会返回1-3幅交换链图像(对应于单、双和三缓存)。如果需要在应用程序中使用其中某一幅图像,那么需要创建与之对应的图像视图。
9)创建深度图像:和颜色图类似,我们还需要使用深度图来完成深度测试的工作,但是和交换链图像不同的是,深度图需要通过应用程序来完成创建(而不是WSI创建好的)。首先,你需要创建一个深度图像对象(类型为VkImage),然后为它分配内存,创建图像布局,最后创建图像视图对象(VkImageView)。
10)深度图的内存分配:我们需要为深度图像对象分配物理设备内存,并且绑定到深度图像对象。
11)创建指令池:我们需要为深度图像创建一个指令缓存,因为我们要自己管理深度图像,所以我们需要使用指令缓存来设置图像布局。
12)创建指令缓存:我们需要创建指令缓存并且开始录制指令信息,从而为之前的深度图像对象创建深度图的布局。
13)图像布局:设置深度图像对象的布局,需要兼容深度/模板模式。
14)添加流水线屏障:为了确保图像布局指令的执行一定在图像视图的创建过程之前完成,我们还需要添加一个流水线屏障。插入流水线屏障之后,它可以确保自身之前的指令全部执行完成后,指令缓存后续的指令才会继续开始执行。
15)完成指令缓存的录制:确保我们已经完成了指令缓存的录制。
16)创建深度图像视图:当我们将图像对象转换到了兼容的图像布局之后,就可以为它创建对应的图像视图对象(VkImageView)了。应用程序不能直接使用图像对象,而是要通过图像视图的方式。
创建后的颜色图像视图会被传递给图形队列,确保展示层可以将它渲染到显示窗口中。我们可以通过这一流程来显示一个空白的窗口了,虽然此时还没有任何内容被绘制到交换链的颜色图上。
交换链实现类的框图
下面介绍三个新的用户自定义的类:VulkanRenderer
、VulkanSwapChain和VulkanPipeline
。这三个类并非来自Vulkan官方API或者数据结构。它们是用户需要自己编写的,但是可以帮助我们使用更有条理的方式去管理应用程序。
如图所示给出了这些模块类以及它们的层级关系。除此之外,图中还叙述了每个模块自身的职责。
酷客网相关文章:
评论前必须登录!
注册