Является ли рендеринг Vulkan локальным при многопоточном рендеринге?
Сейчас я перевожу свою игру на Вулкан. В моей игре у меня есть несколько рабочих потоков для генерации вызовов. Каждый рабочий поток имеет свой собственный буфер команд. Так как пара рендеринга прохода начала / конца должна находиться в паре команд начало / конец буфера, я думаю, что проходы рендеринга должны быть локальными для потока. Это верно?
Если это так, мой второй вопрос: как я могу разделить объекты конвейера между рабочими потоками?
В настоящее время я поддерживаю глобальную карту объектов конвейера, для каждого drawcall рабочие потоки генерируют ключ на основе состояний рендеринга, шейдеров и другой связанной информации. Но поскольку проход рендеринга также необходим для создания объекта конвейера, если проход рендеринга является локальным потоком, это сделает поток объекта конвейера локальным. В этом случае, как я могу разделить объект конвейера между различными рабочими потоками?
Конечно, у меня что-то не так, но я не могу понять, что это такое. пожалуйста, помогите.
1 ответ
Создание локальных потоков является одним из способов достижения цели, но вы можете использовать объекты Vulkan из любого потока, если вы правильно выполняете собственную (т.е. внешнюю) синхронизацию.
Любой объект, который является параметром команды Vulkan, будет прочитан. Любой объект, помеченный как "внешне синхронизированный", будет записан. Отдых - это просто синхронизация опасностей записи-чтения-записи, как обычно в многопоточном программировании.
Многие объекты Вулкана постоянны, и я думаю, VkRenderPass
это один из тех, которые упростили бы вещи. То есть только место VkRenderPass
будет помечен как "внешне синхронизированный" (т. е. опасность записи) - это его деструктор.
Если это так, мой второй вопрос: как я могу разделить объекты конвейера между рабочими потоками?
Те же правила применяются к VkPipeline
объекты. В отличие от vkCmd*
команды, команды создания (vkCreateGraphicsPipelines
) не держись за VkRenderPass
объект:
VkRenderPass
объект, переданный в качестве параметра для создания другого объекта, больше не доступен этому объекту после выполнения команды, в которую он передан.
И в любом случае они только читают его (без "внешней синхронизации"). И читать-читать "опасность" не нужно синхронизации. Так что вам не нужно беспокоиться о VkRenderPass
ES при миграции VkPipeline
в другую ветку.