使用篱笆清理命令缓冲区并同时同步交换链映像 [英] Using fences to clean-up command buffers and synchronizing swap chain images at the same time

查看:62
本文介绍了使用篱笆清理命令缓冲区并同时同步交换链映像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个由 n 个图像组成的交换链,并且允许 k 个飞行中的帧".我通过一组信号量 imageAvailableSemaphore renderFinishedSemaphore 和围栏 imageInFlight ,就像在本教程中完成的操作:

Say I have a swap chain consisting of n images and I allow k "frames in flight". I ensure correct synchronization between vkAcquireNextImageKHR, vkQueueSubmit and vkQueuePresentKHR by a set of semaphores imageAvailableSemaphore and renderFinishedSemaphore and a fence imageInFlight like it is done in this tutorial:

imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
    renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
    inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);

需要栅栏以确保我们在GPU完成使用相应图像之前不再使用信号灯.因此,需要在 vkQueueSubmit 中指定该围栏.

The fences are needed to ensure that we don't use the semaphores again before the GPU has completed consuming the corresponding image. So, this fence needs to be specified in vkQueueSubmit.

另一方面,我正在独立于飞行中的帧"创建命令缓冲区.他们是一次性提交",命令缓冲区.因此,一旦提交,我将它们添加到待删除"邮件中.列表.我需要知道GPU何时完成此列表中的命令缓冲区执行.

On the other hand, I'm creating command buffers independently of the "frames in flight". They are "one-time submit" command buffers. Hence, once submitted, I add them to a "to-be-deleted" list. I need to know when the GPU has finished execution of the command buffers in this list.

但是我无法在 vkQueueSubmit 中指定其他围栏.我该如何解决这个问题?

But I cannot specify another fence in vkQueueSubmit. How can I solve this problem?

推荐答案

我允许 k 个飞行中的框架"

好吧,这就是您的答案.每个将为帧"帧贡献命令缓冲区的线程被分配给每个帧.应该具有 k 个命令缓冲区的倍数.他们应该以环形缓冲区的方式使用它们.这些命令缓冲区应从临时分配池中创建.当他们从环形缓冲区中选择最近最少使用的CB时,应先对其进行重置,然后再记录到其中.

Well, that's your answer. Each thread that is going to contribute command buffers for a "frame" should have some multiple of k command buffers. They should use them in a ring-buffer fashion. These command buffers should be created from a transient-allocating pool. When they pick the least-recently used CB from the ring buffer, they should reset it before recording into it.

通过在过去的第 k 个帧之前,不要开始下一帧的任何工作来确保没有线程尝试重置仍在使用的CB.完成(使用围栏).

You ensure that no thread tries to reset a CB that is still in use by not starting any work for the next frame until the kth frame in the past has completed (using a fence).

如果出于某种原因您绝对不能告诉线程前面的 k 是什么,那么您仍然必须告诉他们某事.当您开始在线程上工作时,您需要告诉他们还有多少帧还在战斗中.这使他们可以对照此帧数检查环形缓冲区的大小.如果环形缓冲区中的元素数少于帧数,则不使用环形缓冲区中最旧的CB.否则,它将不得不从池中分配一个新的CB并将其推入环形缓冲区.

If for some reason you absolutely cannot tell your threads what k is up front, you're still going to have to tell them something. When you start work on the thread, you need to tell them how many frames are still in fight. This allows them to check the size of their ring buffer against this number of frames. If the number of elements in the ring buffer is less than the number of frames, then the oldest CB in the ring buffer is not in use. Otherwise, it will have to allocate a new CB from the pool and shove that into the ring buffer.

这篇关于使用篱笆清理命令缓冲区并同时同步交换链映像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆