微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Vulkan:如何安全地替换 commandBuffer

如何解决Vulkan:如何安全地替换 commandBuffer

当我的场景更新时(例如引入了新模型),我使用函数 tempBuffer 将我的绘图命令缓冲区重新记录到新的命令缓冲区 (buildCommandBuffers) 中。

我有一个 drawCmdBuffers 数组,用于主绘制例程。

让问题稍微复杂一点,我的 buildCommandBuffers 函数可能会从单独线程中的计时器调用,因此在发生此更新时渲染函数可能仍在循环。这是因为我的场景更新可能需要一段时间,我需要在创建命令缓冲区时锁定场景内存(这是一个单独的问题......但添加的每个网格都会触发场景更新,我需要能够缓冲这些更新).

我为每个命令缓冲区设置了一个栅栏,所以一旦我记录到我的“tempBuffer”中,我就会执行以下操作:

        VK_CHECK_RESULT(vkEndCommandBuffer(tempBuffers[i]));        
        // wait for this command buffer to finish (we might be re-recording)
        if (imagesInFlight[_image_index] != VK_NULL_HANDLE) 
        {
            vkWaitForFences(device,1,&imagesInFlight[_image_index],VK_TRUE,UINT64_MAX);
        }
        // destroy in use command buffer
        
        vkFreeCommandBuffers(device,cmdPool,&drawCmdBuffers[i]);
        drawCmdBuffers[i] = tempBuffers[i];

这样安全吗?或者我可以做些什么来停止对 drawCmdBuffers[i] 的访问?

解决方法

看起来您需要 CPU-CPU 同步(通常是互斥锁)来访问 imagesInFlight[] 数组和 drawCommandBuffers[] 或其中的单个元素。否则,您可能正在等待最近帧的栅栏,而另一个线程正在为下一帧提交命令缓冲区——在这种情况下,即使您的等待完成,GPU 仍将使用命令缓冲区。

假设您确实需要重用命令缓冲区而不是每帧重新记录它们,一种方法是让 buildCommandBuffers 线程只构建对 drawCmdBuffers 的更改列表。类似的东西:

渲染线程:

for each frame:
  acquire mutex for command buffer edit list
  for (i,cmdbuf) in command buffer edit list:
    push drawCmdBuffers[i] and most recent frame fence to a deferred-destroy queue
    drawCmdBuffers[i] = cmdbuf;
  clear edit list
  release mutex
  submit render commands for frame,using drawCmdBuffers

更新线程:

on_timer:
  acquire mutex for command buffer edit list
  while fence at front of deferred-destroy queue has signaled:
    free command buffer at front of queue
    pop queue
  release mutex
  for each command buffer that needs to be replaced:
    record command buffer
    acquire mutex for command buffer edit list
    append (cmdbuf_index,cmdbuf) to edit list
    release mutex

这样只有渲染线程直接访问drawCmdBuffers,所以不需要保护。您只有一个从定时器线程到渲染线程的编辑队列,以及一个命令缓冲区队列,用于从渲染线程到定时器线程(或实际在栅栏上等待的其他线程,而不仅仅是轮询)他们在每个计时器上)。在任何给定时刻(除了短暂的互斥锁被持有时),命令缓冲区句柄仅在这些列表中的一个中。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。