作者:手机用户2602905667 | 来源:互联网 | 2022-12-09 09:29
我不太确定它是否真的正确我想要做的事情但是没有那么多关于Vulkan的文档,所以这就是我提出的.如果我的设计方式完全错误,请纠正我!
在我的Vulkan应用程序中,我有三个不同的队列
graphicsQueue:用于提交图形命令缓冲区
presentQueue:用于显示完成的图像
transferQueue:用于复制缓冲区,纹理等.
我正在尝试实现异步模型加载,这意味着所有顶点,纹理等都在一个单独的线程中加载.模型加载完成后,主线程会更新绘图命令缓冲区,以便渲染新加载的对象.
一切正常,因为它应该期望我从Vulkan Validation层获得警告:
线程错误:VkQueue类型的对象同时用于线程...
如果我单步执行调试器,我可以看到以下行受到影响:
//main Loop
vkQueueSubmit(graphicsQueue, ...) //draw command buffer
和
//Background loading thread
vkQueueSubmit(transferQueue, ...)//copy vertex command buffer
我打印了地址,graphicsQueue
并transferQueue
发现它们是相同的(相同的地址),所以看起来我的显卡只支持单个队列.所以现在我正在尝试同步vkQueueSubmit
使用信号量的调用:
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &queueSemaphore;
不幸的是,错误仍然是一样的.
所以我的问题是:如何正确地同步呼叫vkQueueSubmit
?
1> Nicol Bolas..:
你是在思考这个问题.
你有一个操纵对象的功能.并且您希望能够从同一对象上的多个线程调用该函数.但是通过该函数操作该对象不是线程安全的.因此,由您决定使其线程安全.
无论是Vulkan对象还是常规C/C++类型,解决方案都是相同的:您使用互斥锁.如果您的两个队列是相同的队列,则必须在每个线程调用的站点周围锁定互斥锁vkQueueSubmit
.
不要让Vulkan的复杂性分散你对简单解决方案的注意力;)
但是,如果您的图形和传输队列相同,那么找到重构代码的方法可能会更好,这样您就不会尝试在不同的线程上提交不同的批处理.也就是说,使您的代码更适应硬件.
如果GPU提供了不同的传输队列,那么您的传输线程会生成传输CB并提交它们(同时将相应的信号量传递给图形提交线程,以便它可以在正确的时间等待).如果GPU没有明确的传输队列,那么您仍然可以在不同的线程上生成传输CB.但是,不是将信号量传递给图形线程,而是传递命令缓冲区.那些与下一个图形批次一起提交; 图形提交线程还可以在传输和图形操作之间插入适当的同步.
指示不清楚。GPU和CPU现在都着火了。