У меня есть приложение с Vulkan для рендеринга и glfw для управления окнами. Если я запускаю несколько потоков, каждый из которых имеет свое окно, я получаю ошибки при обработке потоков и очереди, даже если ВСЕ вызовы vulkan защищены общим мьютексом. Слой вулкана говорит:
ОШИБКА РЕЗЬБЫ: объект типа VkQueue одновременно используется в потоке 0x0 и потоке 0x7fc365b99700
Вот скелет l oop под что происходит в каждом потоке:
while (!finished) {
window.draw(...);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
Скелет функции рисования выглядит следующим образом:
draw(Arg arg) {
static std::mutex mtx;
std::lock_guard lock{mtx};
// .... drawing calls. Including
device.acquireNextImageKHR(...);
// Fill command bufers
graphicsQueue.submit(...);
presentQueue.presentKHR(presentInfo);
}
Это C ++ 17, который немного упрощает синтаксис, но в остальном не имеет значения. Понятно, что все под мьютексом. Я также перехватываю вызов отладочного сообщения. Когда я это делаю, я вижу, что один поток ожидает события glfw, один печатает сообщение слоя vulkan, а два других потока пытаются получить мьютекс для lock_guard. Я в растерянности относительно того, что происходит или как даже выяснить, что вызывает это.
Я работаю на linux, и это не вызывает sh. Однако в Ma c OS X, после случайного промежутка времени, код вызовет sh в вызове MoltenVK для отправки в очередь, и когда происходит cra sh, я вижу похожую ситуацию с потоками. То есть, никакой другой поток не находится внутри вызова Vulkan.
Буду признателен за любые идеи. Моим следующим шагом будет перемещение всех представлений в очереди в один поток, хотя это не мое любимое решение.
PS: я создал полный MCVE в рамках Vookoo. Это в https://github.com/FunMiles/Vookoo/tree/lock_guard_queues и является примером 00-параллельных треугольников Чтобы попробовать это, сделайте следующее:
git clone https://github.com/FunMiles/Vookoo.git
cd Vookoo
git checkout lock_guard_queues
mkdir build
cd build
cmake ..
make
examples/00-parallelTriangles