vkAcquireNextImageKHR语义?超时意味着什么?

时间:2018-10-05 12:35:34

标签: vulkan

我对import matplotlib.pyplot as plt import numpy as np; np.random.seed(42) fig, axes = plt.subplots(ncols=3, sharey=True) for ax in axes: ax.plot(np.arange(30), np.cumsum(np.random.randn(30))) # set width and height in physical units (inches) width = 4 # inch height= 1 # inch def resize(evt=None): w,h = fig.get_size_inches() l = ((w-width)/2.)/w b = ((h-height)/2.)/h fig.subplots_adjust(left=l, right=1.-l, bottom=b, top=1.-b) fig.canvas.draw_idle() resize() fig.canvas.mpl_connect("resize_event", resize) plt.show() 的语义感到困惑。具体来说,在什么情况下函数可以返回vkAcquireNextImageKHR?即是什么能阻止它无法立即获取图像?它会等待什么呢?

即使演示引擎尚未完成从图像的读取,似乎也可以获取图像,并且无论如何,都需要使用信号量或围栏来同步获取的图像的用法。我想念什么?

2 个答案:

答案 0 :(得分:4)

所有这些都是实现定义的。

但是,该标准给出了一个明确的案例:

  

如果应用程序当前已获取(但尚未呈现)的图像数量小于或等于交换链中的图像数量与VkSurfaceCapabilitiesKHR::minImageCount的值之差,则最终将获取图像。 。如果当前获取的图像数量大于此数量,则不应调用vkAcquireNextImageKHR;如果是,则timeout不能为UINT64_MAX

因此,如果您已获取交换链中的所有可用图像,但未显示这些图像,则可能会超时。

可能还有其他情况,但是同样,这些情况是实现定义的。 vkAcquireNextImageKHR的一个完全有效的实现可以在返回成功的采集之前发出您提供的信号量/栅栏,从而迫使vkAcquireNextImageKHR调用本身受到任何延迟。您对此无能为力。

答案 1 :(得分:4)

Nicol Bolas的答案是正确的,但是由于对它的回答要求提供有关在实际实现中使用此位置的详细信息,因此我将在此处添加另一个答案。

在Android上,vkQueuePresentKHR将图像发送到合成器(SurfaceFlinger),由合成器进行显示。合成器会在每次显示刷新时重新显示此图像,直到它获得该窗口要显示的新图像为止。在获得下一个图像之前,它不知道将来是否或需要再次读取该缓冲区多少次,并且无法创建一个信号量,该信号量将在最后一次读取完成时发出信号。 (从理论上讲,您可以构建一个可以做到这一点的系统,但这不是Android用于此工作的Linux内核同步机制的方式。)因此,在展示图像N + 1之前,合成器无法将图像N释放回您的应用程序以进行获取,因为它无法使您获得与之配套的信号灯。

这要复杂得多,因为即使您呈现N + 1帧,合成器也不会知道渲染信号量信号将花费多长时间,因此仍然不知道它会持续多长时间。必须能够读取第N帧的图像。

这扩展到具有两个以上缓冲区的交换链。

我对其他系统不太熟悉,但是我相信其他人也有类似的限制,这使他们无法让您在呈现它们之前随意获取图像。绝对有可能构建一个允许这样做的表示引擎,但是Vulkan需要在现有系统和现有表示引擎上工作,因此必须忍受现有系统施加的限制。 Khronos成员无法更改Windows合成器,而X11,Wayland和Android之类的其他成员则很难更改/更改缓慢,因为这样做可能会影响所有现有的应用程序,框架等。