在这个例子中,我们将一些缓冲区复制到顶点缓冲区中,我们希望在两个提交中快速开始使用此缓冲区进行渲染,而无需等待一些栅栏:
vkBeginCommandBuffer(tansferCommandBuffer)
vkCmdCopyBuffer(tansferCommandBuffer, hostVisibleBuffer, vertexBuffer)
vkEndCommandBuffer(tansferCommandBuffer)
vkQueueSubmit(queue, tansferCommandBuffer)
vkBeginCommandBuffer(renderCommandBuffer)
...
vkCmdBindVertexBuffers(vertexBuffer)
vkCmdDraw()
...
vkEndCommandBuffer(renderCommandBuffer)
vkQueueSubmit(queue, renderCommandBuffer)
根据我的理解,tansferCommandBuffer
在提交renderCommandBuffer
时可能尚未完成,renderCommandBuffer
可能会被安排,并且会在vertexBuffer
中读取浮动数据。< / p>
我们可以在提交完成后提交tansferCommandBuffer
时附加信号量,并将此信号量转发到renderCommandBuffer
以等待执行。这里的问题是它阻止了第二批不依赖于缓冲区的批处理命令。
或者我们可以在复制命令之后或绑定顶点命令之前插入一个屏障,这似乎要好得多,因为我们可以指定对缓冲区的访问是我们主要关注的并且可能保留批处理的一部分来执行
使用信号量而不是类似案例的障碍(单一队列,多次提交)是否有充分的理由?
答案 0 :(得分:1)
每当您更改使用资源向驱动程序/硬件通知该更改的方式时,都需要屏障。因此,在您的示例中,可能也需要屏障。
但至于信号量。提交命令缓冲区时,指定信号量句柄和管道阶段,在这些阶段应在相应的信号量上进行等待。您可以通过VkSubmitInfo结构的以下成员执行此操作:
- pWaitSemaphores是一个指向信号量数组的指针,在此批处理的命令缓冲区开始执行之前要等待。如果 提供了等待的信号量,它们定义了一个信号量等待 操作
- pWaitDstStageMask是一个指向管道阶段数组的指针,每个相应的信号量都将在该阶段发生。
因此,当您提交命令缓冲区时,所有直到指定阶段的命令都可以由硬件执行。