注意:我是自学 Vulkan,对现代 OpenGL 知之甚少。
阅读 Vulkan 规范,我可以看到非常好的信号量,它允许命令缓冲区和交换链同步。这是我理解的一种简单(但我认为效率低下)的做事方式:
vkAcquireNextImageKHR
用, 信号获取图像sem_post_acq
- 使用以下命令构建命令缓冲区(或使用预构建):
- 将图像从其过渡离开的图像屏障
VK_IMAGE_LAYOUT_UNDEFINED
- 使成为
- 将图像过渡到的图像屏障
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
- 将图像从其过渡离开的图像屏障
- 提交到队列,等待
sem_post_acq
片段阶段和信令sem_pre_present
。 vkQueuePresentKHR
等待sem_pre_present
。
这里的问题是命令缓冲区中的图像屏障必须知道它们正在转换哪个图像,这意味着vkAcquireNextImageKHR
必须在知道如何构建命令缓冲区(或提交哪个预先构建的命令缓冲区)之前返回。但vkAcquireNextImageKHR
可能会睡很多(因为演示引擎很忙并且没有免费图像)。另一方面,命令缓冲区的提交本身是昂贵的,更重要的是,片段之前的所有阶段都可以运行,而无需知道最终结果将渲染到哪个图像。
从理论上讲,在我看来,像以下这样的方案将允许更高程度的并行性:
- 使用以下命令构建命令缓冲区(或使用预构建):
- 将图像从其过渡离开的图像屏障
VK_IMAGE_LAYOUT_UNDEFINED
- 使成为
- 将图像过渡到的图像屏障
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
- 将图像从其过渡离开的图像屏障
- 提交到队列,等待
sem_post_acq
片段阶段和信令sem_pre_present
。 vkAcquireNextImageKHR
用, 信号获取图像sem_post_acq
vkQueuePresentKHR
等待sem_pre_present
。
从理论上讲,这将允许管道一直执行到片段着色器,而我们等待vkAcquireNextImageKHR
. 这不起作用的唯一原因是既不能告诉命令缓冲区该图像将在以后确定(通过适当的同步),也不能向演示引擎询问特定图像。
我的第一个问题是:我的分析正确吗?如果是这样,在 Vulkan 中是否根本不可能进行这种优化,为什么不呢?
vkAcquireNextImageKHR
我的第二个问题是:如果您能说出您想要获取的特定图像并自己迭代它们,那不是更有意义吗?这样,您可以提前知道您要请求哪个图像,并相应地构建和提交您的命令缓冲区。