VkPresentModeKHR-呈现模式

在构建交换链 vk::SwapchainCreateInfoKHR时,有一个设置是 VkPresentModeKHR。根据官方手册VkPresentModeKHR(3) Manual Page,呈现模式有6种。

相关术语

垂直空白间隙(Vertical Blank Interval)

指在扫描线技术中(例如隔行扫描)电子束从前一画面的右下角移至后一画面的左上角时的时间差所引起的空白画面。这一情况出现在使用阴极射线管的显示器、使用视频图形阵列标准的显示器中。下面简称VBI。

在现代的显示器(比如LCD)中,虽然没有电子枪进行隔行扫描,但是同时控制上百万个像素点是不可能的,还是需要动态扫描进行刷新。这个刷新过程可以理解为从上往下的逐行扫描。因此VBI的含义是一段可以安全的换出"显示到显示器上的图像"的时间,可以简单理解为在从上到下扫描完帧缓冲,即可以认为屏幕上显示了完整画面(实际上某些情况下有撕裂)后的一段空白时间。这个扫描过程只受帧同步信号(VSYNC)影响。

撕裂(tearing)

在显示引擎正在显示一张图像时,如果它不再显示当前这张图像,而是显示另一张图像(某些模式下会有这样做),那么屏幕上有一部分是旧的图像(比如上面一半),另一部分是新的图像(比如下面一半)。这个现象就是撕裂。

显示模式

总结

VK_PRESENT_MODE__KHR在表中省略。

✅是 ☑️大部分时候是 ❌否 ❓不确定
模式 是否有队列 是否等待VBI再更新当前图像 是否支持并发访问单个图像 可能观察到撕裂(tearing)
IMMEDIATE
MAILBOX ✅单项目队列
FIFO
FIFO_RELAXED ☑️
SHARED_DEMAND_REFRESH
SHARED_CONTINUOUS_REFRESH

三个有队列的显示模式MAILBOX,FIFO,FIFO_RELAXED的差别

FIFO_RELAXED和FIFO的差别主要体现在应用过慢的情况下。当应用绘制的很慢的时候,有可能在显示引擎显示了第一个图像之后的VBI的过程中,应用并没有生成好下一个图像。这时如果没有到VBI,即显示引擎处于动态扫描过程中,对于FIFO_RELAXED,在下一个图像生成好之后,就不需要等待VBI,直接让显示引擎显示出来。如果是FIFO,就还需要等到扫描结束后的VBI才绘制。因此FIFO_RELAXED会稍微缓解延迟问题。

MAILBOX虽然也有队列,但是他只能保存一个项目。这在应用过快的情况下非常有用。比如16.6毫秒内如果应用生成了多个图像,那么在下个VBI时只有MAILBOX会显示最新的一个,因为最新的把之前生成好的都覆盖了。但是基于FIFO的就只能等之前的都显示完。

详细描述

VK_PRESENT_MODE_IMMEDIATE_KHR

显示引擎不等待VBI直接更新当前图像。

VK_PRESENT_MODE_MAILBOX_KHR

显示引擎等待下个VBI再更新当前图像。有一个内部的可以容纳一个项目的队列保存等待显示的请求项目。如果队列满时收到新的显示请求,新的会替代现有的项目,与之前的项目关联的任何图像都可以被应用重复使用。在VBI期间队列不为空时,队列中的一个请求会被移除然后在这个期间被处理。

VK_PRESENT_MODE_FIFO_KHR

显示引擎等待下个VBI再更新当前图像。有一个内部的单向队列保存等待显示的请求项目。新请求被放到队尾。在VBI期间队列不为空时,队列中队头的请求会被移除然后在这个期间被处理。这是唯一必须支持的 presentMode的值。

VK_PRESENT_MODE_FIFO_RELAXED_KHR

显示引擎一般会等待下个VBI再更新当前图像。如果从上次更新到当前时刻已经经过了一个或更多VBI,显示引擎就不再等待下一个VBI而直接更新图像,这个模式可以减轻一些应用的视觉延迟。这些应用大部分时间可以在下个VBI之前生成新图像,但是偶尔会迟到,正好在下个VBI之后生成好新图像。有一个内部的单向队列保存等待显示的请求项目。新请求被放到队尾。在VBI期间队列不为空时,队列中队头的请求会被移除然后在这个期间或者之后被处理。

VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR

显示引擎和应用可以并发访问单个图像,这被称为共享的可展示图像 shared presentable image。显示引擎仅需要在收到新的显示请求后更新当前图像。因此无论是否需要更新,应用必须发起显示请求。但是,显示引擎可能在任何时间更新当前图像,意味着可能有撕裂。

VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR

显示引擎和应用可以并发访问单个图像,这被称为共享的可展示图像 shared presentable image。显示引擎在他的有规律的刷新循环下周期性更新当前图像。应用只需要发起初次显示请求,在这个请求之后显示引擎必须更新当前图像,不需要更多的显示请求。应用可以通过发起显示请求表明图像内容已更新,但是这并不能保证更新的实机。如果该图像的渲染实机不正确有可能产生视觉撕裂。

参考

作者

Gehan Zheng

发布于

2023-03-07

更新于

2023-12-18

许可协议

评论