Vulkan 异步模型加载

Vulkan async model loading

我不太确定我正在尝试做的事情是否真的正确,但是没有太多关于 Vulkan 的文档,所以这就是我想出的。如果我的设计方式完全错误,还请指正!

在我的 Vulkan 应用程序中,我有三个不同的队列

我正在尝试实现异步模型加载,这意味着所有顶点、纹理等都在单独的线程中加载。模型加载完成后,绘图命令缓冲区由主线程更新,以便渲染新加载的对象。

一切正常,我从 Vulkan 验证层收到警告:

THREADING ERROR : object of type VkQueue is simultaneously used in thread ...

如果我单步调试调试器,我可以看到以下行受到影响:

//main Loop
vkQueueSubmit(graphicsQueue, ...) //draw command buffer

//Background loading thread
vkQueueSubmit(transferQueue, ...)//copy vertex command buffer

我打印了graphicsQueuetransferQueue的地址,发现它们是一样的(同一个地址),看来我的显卡只支持单队列。所以现在我正在尝试使用信号量同步对 vkQueueSubmit 的调用:

submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &queueSemaphore;

不幸的是错误还是一样。

所以我的问题是:如何正确同步对 vkQueueSubmit 的调用?

你想多了。

你有一个操作对象的函数。并且您希望能够从同一对象上的多个线程调用该函数。但是通过该函数 操作该对象不是 线程安全的。因此,您有责任使其成为线程安全的。

无论是 Vulkan 对象还是常规 C/C++ 类型,解决方案都是一样的:使用互斥体。如果您的两个队列是同一个队列,则必须在每个线程调用 vkQueueSubmit.

的站点周围锁定一个互斥锁

不要让 Vulkan 的复杂性分散您对简单解决方案的注意力;)

话虽这么说,但如果您的图形和传输队列相同,您最好找到一种方法来重组您的代码,这样您就 不是 尝试在不同的线程上提交不同的批次。也就是让你的代码更加适应硬件。

如果 GPU 提供不同的传输队列,那么您的传输线程会生成传输 CB 并提交它们(同时将适当的信号量传递给图形提交线程,以便它可以在正确的时间等待)。如果 GPU 没有不同的传输队列,那么您仍然可以在不同的线程上生成传输 CB。但不是将信号量传递给图形线程,而是传递 命令缓冲区 。那些与下一批图形一起提交;图形提交线程还可以在传输和图形操作之间插入适当的同步。