Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graphics 使用围栏清理命令缓冲区,同时同步交换链映像_Graphics_Vulkan - Fatal编程技术网

Graphics 使用围栏清理命令缓冲区,同时同步交换链映像

Graphics 使用围栏清理命令缓冲区,同时同步交换链映像,graphics,vulkan,Graphics,Vulkan,假设我有一个由n图像组成的交换链,我允许k“飞行中的帧”。我通过一组信号量ImageAvailablesMaphore和renderFinishedSemaphore以及围栏imageInFlight确保vkAcquireNextImageKHR和vkQueueSubmit和vkQueuePresentKHR之间的正确同步,就像在以下地方做的那样: 需要设置围栏,以确保在GPU使用完相应的映像之前不再使用信号量。因此,需要在vkQueueSubmit中指定此围栏 另一方面,我正在创建独立于“飞行

假设我有一个由
n
图像组成的交换链,我允许
k
“飞行中的帧”。我通过一组信号量
ImageAvailablesMaphore
renderFinishedSemaphore
以及围栏
imageInFlight
确保
vkAcquireNextImageKHR
vkQueueSubmit
vkQueuePresentKHR
之间的正确同步,就像在以下地方做的那样:

需要设置围栏,以确保在GPU使用完相应的映像之前不再使用信号量。因此,需要在
vkQueueSubmit
中指定此围栏

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

但我无法在
vkQueueSubmit
中指定另一个围栏。我怎样才能解决这个问题

我允许
k
“飞行中的帧”

这就是你的答案。要为“帧”提供命令缓冲区的每个线程都应该有若干倍的
k
命令缓冲区。他们应该以环形缓冲方式使用它们。这些命令缓冲区应该从临时分配池中创建。当他们从环形缓冲区中选取最近使用最少的CB时,他们应该在记录到它之前重置它

在过去的
k
th帧(使用围栏)完成之前,不启动下一帧的任何工作,以确保没有线程尝试重置仍在使用的CB


如果出于某种原因,你根本无法告诉你的线程什么是
k
,你仍然需要告诉他们一些事情。当你开始处理线程时,你需要告诉他们还有多少帧在战斗中。这使他们能够对照这个帧数检查环形缓冲区的大小。如果环缓冲区中的元素数小于帧数,则环缓冲区中最旧的CB不在使用中。否则,它将不得不从池中分配一个新的CB,并将其推入环形缓冲区。

您可以为此使用时间轴信号量。您可以在此处深入阅读有关它们的信息:

时间轴信号量携带一个特定的值,而不是有信号或无信号。您感兴趣的函数是vkGetSemaphoreCounterValue,它允许您在不阻塞的情况下读取信号量的值

要创建时间轴信号量,只需将VkSemaphoreCreateInfo的pNext值设置为VkSemaphoreTypeCreateInfo,如下所示

VkSemaphoreTypeCreateInfo 
timelineCreateInfo{VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO};
timelineCreateInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
timelineCreateInfo.initialValue = 0;
VkSubmitInfo的pNext值需要设置为VkTimelineSemaphoreSubmitInfo

VkTimelineSemaphoreSubmitInfo timelineInfo{VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO};
timelineInfo.signalSemaphoreValueCount = 1;
timelineInfo.pSignalSemaphoreValues = &signalValue;
在命令缓冲区完成后,信号量的值将是您将signalValue设置为的任何值。之后,您可以使用以下命令查询值:

uint64_t value;
vkGetSemaphoreCounterValue(device, semaphore, &value);
所以假设您将signalValue设置为1,这里的值将是1或0,这是我们在VkSemaphoreTypeCreateInfo中作为初始值给出的信号量。之后,您可以安全地删除一次性命令缓冲区


注意:时间轴信号实际上是围栏和二进制信号的半替换,应该是您使用的主要同步原语。我认为唯一需要二进制信号量的函数是vkAcquireSwapchainImage。

(a)那么,在单个线程中,对于每个帧
I=0,…,k-1,
a[I]
我们有
a[I]
命令缓冲区
cb[I][0],…,cb I][a[I]-1]
,都是从公共瞬态分配池分配的?或者您是否建议为每个
i
使用专用池?(b) 您建议在每个命令缓冲区使用一次后重置整个池?(c)在任何情况下,这似乎表明每个命令缓冲区恰好对应一个交换链。但是如果我有一个命令缓冲区,它使用来自多个交换链的图像,或者它不仅渲染成交换链图像,而且渲染成纹理,会发生什么呢?我真的很想知道你的反应;特别是对于(c)。@0xbadf00d:(a)和(b)太笼统,无法提供答案,因为它们完全取决于您在每个线程中正在做什么以及您计划如何做。(c)有点离题。如果将“帧”定义为渲染到单个swapchain图像,则这就是您需要处理的内容。如果将“帧”定义为渲染到两个交换链图像,则这就是您需要处理的内容。关键是您需要正确地传达允许新框架使用的数据。谢谢您的回答。过去我已经看过时间轴信号量,但有两个问题阻止我使用它们:(a)它们只是一个设备扩展,因此可能不受GPU支持。(b) 正如在博客文章中提到的,“Vulkan的窗口系统集成API还不支持时间轴信号量”。因此,我不知道如何使用它们来同步
vkAcquireSwapchainImage
vkQueueSubmit
.a)它们是Vulkan 1.2和任何支持它们的GPU的核心功能。b) 您可以将它们与二进制信号量组合。您所要做的就是将用于vkAcquireSwapchainImage的信号量添加到waitsemaphores列表中,并在timeline sbmit信息中添加伪值。感谢您的评论。我还不清楚的是:时间轴信号如何帮助我解决问题?我试图实现的哪一方面是普通信号灯/围栏不可能实现的?我真的对你的回答感兴趣。
uint64_t value;
vkGetSemaphoreCounterValue(device, semaphore, &value);