Vulkan选择显示模式

选择显示模式
在屏幕上显示图像功能是Vulkan交换链最重要的功能之一,实际上,这也是设计交换链的目的。在OpenGL中,当完成对缓冲区的渲染后,需要使用前缓冲区切换图像,可以将渲染好的图像显示在计算机屏幕上。我们只能决定是否在空白间隔显示图像(在启用了垂直同步的情况下)。
在Vulkan中,我们不会受限于只能渲染一幅图像(存储在后备缓冲区中的),而且也不会受限于只能在两种显示模式(启用或禁用垂直同步)中进行选择。我们可以在多种显示模式中进行选择,但我们需要在创建交换链的过程中设定该显示模式。

具体处理过程
(1)通过调用vkEnumeratePhysicalDevices()函数获取物理设备的句柄,将该句柄存储在一个VkPhysicalDevice类型的变量中,将该变量命名为physical_device。
(2)获取已创建的显示曲面,将该显示曲面的句柄存储在一个VkSurfaceKHR类型的变量中,将该变量命名为presentation_surface。
(3)创建一个VkPresentModeKHR类型的变量,将其命名为desired_present_mode。将想要使用的显示模式存储在这个变量中。
(4)创建一个uint32_t类型的变量,将其命名为present_modes_count。
(5)调用vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device,presentation_surface,&present_modes_count,nullptr)函数。将第一个参数设置为物理设备的句柄;将第二个参数设置为已创建显示曲面的句柄;将第三个参数设置为指向present_modes_count变量的指针;将第四个参数设置为nullptr。
(6)如果该函数调用操作成功完成,present_modes_count变量中就会含有物理设备支持显示模式的数量。
(7)创建一个std::vector<VkPresentModeKHR>类型的变量,将其命名为present_modes。调整该vector容器的尺寸,使它含有的元素数量不小于present_modes_count变量的值。
(8)再次调用vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device,presentation_surface,&present_modes_count,&present_modes[0])函数。前三个参数与上次调用该函数时的前三个参数设置的值相同,但将最后一个参数设置为指向vector容器变量present_modes中第一个元素的指针。
(9)如果该函数调用操作返回的值为VK_SUCCESS,那么present_modes变量中就会含有具体硬件平台支持的显示模式。
(10)循环遍历vector容器变量present_modes中的所有元素,查明是否有与desired_present_mode变量中存储的想要使用的显示模式相同的元素。
(11)如果当前物理设备不支持想要使用的显示模式(vector容器变量present_modes中的元素,没有一个与desired_present_mode变量中存储的显示模式相等),则可选择FIFO显示模式。FIFO代表VK_PRESENT_MODE_FIFO_KHR显示模式,该模式永远都会得到支持。

具体运行情况
显示模式定义了在屏幕上显示图像的方式,当前,Vulkan中定义了4种显示模式。
最简单的模式是IMMEDIATE。在使用这种模式的情况下,当显示图像时,该图像会立刻替换之前正在被显示的图像。这个模式中没有等待时间、没有队列,也没有来自应用程序的其他参数,因此可能(概率较高)会出现画面撕裂。

Vulkan选择显示模式
显示模式FIFO是被强制规定为所有Vulkan实现都必须支持的显示模式。在使用这种模式的情况下,当显示图像时,该图像会被添加到先进先出(First In First Out,FIFO)的队列,该队列的长度等于交换链中图像的总数减一。通过使用这种队列,图像能够以与空白时间同步的方式(垂直同步)在计算机屏幕上显示,其被显示的次序永远会与其被添加到队列中的次序相同。这种显示模式中不会出现画面撕裂,因为启用了垂直同步功能。这种模式与OpenGL中将交换间隔设置为1的缓冲区交换模式类似。
TIP FIFO模式永远都会得到支持。
FIFO模式还有一个差异很小的修改版本:FIFO RELAXED。两者的差异是,在FIFO RELAXED中,只有当图像显示得足够快(比刷新频率更快)时,图像才会以与空白间隔同步的方式在计算机屏幕上显示。如果某幅图像是由应用程序显示的,而且应用程序出现延迟(显示队列中最后一幅图像的时间大于两个空白间隔之间的刷新时间,从而导致FIFO队列空了),那么这幅图像就会被立刻显示。如果显示速度足够快,就不会出现画面撕裂,但如果我们编写的应用程序的绘图速度低于显示器的刷新频率,就会出现画面撕裂。该行为与OpenGL中EXT_swap_control_tear扩展设置的行为类似。

Vulkan选择显示模式
最后一种显示模式是MAILBOX模式,可以将其视为三缓冲区显示模式。这种显示模式会使用一个队列,但该队列仅会含有一个元素。该队列中的图像会通过与空白间隔同步的方式在屏幕上显示(在启用了垂直同步的情况下)。但是当应用程序显示图像时,新图像会替换队列中的图像。因此,显示引擎总是会显示最后一个、最新的可用图像,而这种显示模式不会出现画面撕裂。

Vulkan选择显示模式
要选择显示模式,首先需要查明当前硬件平台上有哪些可用的显示模式,需要获取硬件平台支持的所有显示模式的数量。通过调用vkGetPhysicalDeviceSurfacePresentModesKHR()函数,并将最后一个参数设置为nullptr,可以做到这一点。

Vulkan选择显示模式
然后,应为得到支持的显示模式准备存储空间,并再次调用vkGetPhysicalDeviceSurface PresentModesKHR()函数,但这次应将最后一个参数设置为指向预留存储空间的指针。

Vulkan选择显示模式
现在我们已经知道指定硬件平台上有哪些显示模式可用,因而能够查明我们想要使用的显示模式是否可用。如果该硬件平台不支持我们想要使用的显示模式,则可以从可用显示名单中选择另一种显示模式,也可以选择默认的FIFO模式,因为这是一种强制实现的显示模式,所以永远都可用。

Vulkan选择显示模式
Vulkan选择显示模式

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!

 

Vulkan实战