Vulkan获取交换链图像

在使用交换链图像前,我们需要从显示引擎获取该图像,该处理过程称为图像采集。通过该处理过程可以将图像的索引转换为交换链图像的句柄(通过调用vkGetSwapchain ImagesKHR()函数可以获取交换链图像的句柄。

准备工作

要获取Vulkan中的图像,需要设置两种前面没有介绍过的对象,它们是信号和栅栏(fence)。
信号用于使设备的队列同步。这意味着我们提交命令时,这些命令需要等其他操作完成后才能被处理。在这类情况中,我们可以设定这些命令必须等待另一些命令被执行后才被处理,这就是信号的作用。它们用于实现内部队列同步,但是不能使用它们通过已提交的命令使应用程序的操作同步。
要使应用程序的操作同步,需要使用栅栏。栅栏用于通知应用程序某项工作已经完成,应用程序可以根据得到的信息,获取栅栏的状态,查明某些命令是否仍旧正在被处理或者这些命令已经完成了它们的任务。

具体处理过程

(1)获取已创建逻辑设备的句柄,将该句柄存储在一个VkDevice类型的变量中,将该变量命名为logical_device。
(2)获取交换链的句柄,将该句柄赋予一个VkSwapchainKHR类型的变量,将该变量命名为swapchain。
(3)创建一个信号,将该信号存储在一个VkSemaphore类型的变量中,将该变量命名为semaphore。或者创建一个栅栏,将该栅栏的句柄存储在一个VkFence类型的变量中,将该变量命名为fence。这两个同步化对象必须至少创建一个(无论哪个都可以),也可以两个都创建。
(4)创建一个uint32_t类型的变量,将其命名为image_index。
(5)调用vkAcquireNextImageKHR(logical_device,swapchain,<超时时间>,semaphore,fence,&image_index)函数。将第一个参数设置为逻辑设备的句柄;将第二个参数设置为交换链的句柄;将第三个参数设置为超时时间的限定值,超过该时间值函数调用操作就会返回超时错误提示信息;将第四和第五个参数设置为一个或两个同步基元:信号和/或栅栏;将第六个参数设置为指向image_index变量的指针。
(6)检查vkAcquireNextImageKHR()函数调用操作的返回值。如果该值等于VK_SUCCESS或VK_SUBOPTIMAL_KHR,就说明该函数调用操作成功完成,并且image_index变量会含有交换链图像的索引(该索引为通过调用vkGetSwapchainImagesKHR()函数获得的交换链图像组中交换链图像的编号)。如果vkAcquireNextImageKHR()函数调用操作的返回值等于VK_ERROR_OUT_OF_DATE_KHR,就无法使用该交换链中的任何图像。这样就必须销毁该交换链,并重新创建该交换链以便获取图像。

具体运行情况

调用vkAcquireNextImageKHR()函数会获得交换链图像的索引,该索引为通过调用vkGetSwapchainImagesKHR()函数获得的交换链图像组中交换链图像的编号。调用vkAcquireNextImageKHR()函数的操作不会返回交换链图像句柄,如下列代码所示。

Vulkan获取交换链图像

这段代码调用了vkAcquireNextImageKHR()函数。由于显示引擎的内部机制,有时可能无法立刻获得图像,甚至可能使我们编写的应用程序无限期等待下去。当我们想要获取的图像数量大于显示引擎能够提供的图像数量时,这种情况就会出现。这就是在上面调用vkAcquireNextImageKHR()函数的操作中,通过第三个参数来设置超时时间限定值(该值的单位为纳秒)的原因。该限定值通知硬件编写的应用程序能够等待的最长时间。超过该限定值后,vkAcquireNextImageKHR()函数就会因超时而无法获得图像并显示错误提示信息。在上面的代码中,我们设置的超时时间为2秒。

还有一些参数是设置信号和栅栏的参数。我们获得了图像后,可能仍旧无法立刻使用该图像,需要等待先前提交的引用了该图像的所有操作都执行完。因此,应用程序可使用栅栏查明何时能够安全地修改图像,但我们也可以命令驱动程序在处理应用于指定图像的新命令前,处于等待状态。在这种情况中可使用信号,通常信号的效果更好。

TIP 使应用程序等待的性能降低的性能比单独使GPU等待降低的性能多得多。
在获取交换链图像的过程中,函数调用操作的返回值也非常重要。当函数调用操作的返回值为VK_SUBOPTIMAL_KHR时,就意味着我们仍可以使用这幅图像,但对于显示引擎来说该图像不再是最合适的图像了。获取了一幅图像后,就应该重新创建交换链,但不需要立刻就这样做。当vkAcquireNextImageKHR()函数调用操作的返回值等于VK_ERROR_OUT_OF_DATE_KHR时,我们就无法再通过指定的交换链使用图像,因而需要尽快重新创建交换链。
在获取交换链图像时需要注意的最后一点,是在能够使用图像前,需要更改(转变)图像的布局,布局是图像内部内存组织形式,它会随图像的当前用途而变化。如果我们想要通过不同的方式使用图像,就需要更改它的布局。
例如,显示引擎使用的图像必须拥有VK_IMAGE_LAYOUT_PRESENT_SRC_KHR布局。但是如果我们想要将图像作为渲染材料,该图像就必须拥有VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL布局。更改布局的操作称为转变。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!

 

Vulkan实战