Vulkan: возможно генерировать вторичные буферы команд перед рендерингом?

----------------- ОРИГИНАЛЬНЫЙ ВОПРОС ------------------------

В Вулкане

Для того чтобы начать выдавать команды во вторичные буферы команд, обязательно ли уже получать образ и вызывать vkCmdBeginRenderPass() в первичном буфере команд?

Я нуб, но мне так кажется.

------------------------ РЕДАКТИРОВАТЬ № 2 --------------------------------

Да, это можно сделать:

  1. Возможно асинхронно, обрабатывать логику и записывать вызовы отрисовки во вторичных буферах команд.
  2. Проверьте, были ли записаны вторичные буферы команд: если нет, перейдите к #1, иначе продолжите.
  3. Получить изображение
  4. Запустить основной буфер команд; запустить renderpass.
  5. Выполнить ранее записанные вторичные буферы команд
  6. Отправить
  7. настоящее время

3 ответа

Решение

Да, можно сделать то, что я пытался сделать, а именно записать команды рисования во вторичные буферы команд перед тем, как начинать запись первичного буфера команд.

Проблема была двоякой.

  1. Я не устанавливал VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT в элементе flags в VkCommandBufferBeginInfo для вторичного буфера.
  2. Ошибка из слоя проверки вводит в заблуждение, что говорит: "Во время отрисовки в Pipeline (0x12) не обнаружено активного прохода рендеринга!". Это заставило меня попробовать неправильные решения.

Это зависит от того, что вы подразумеваете под "выдачей" команд вторичным буферам команд, и от команд, которые вы хотите записать в эти вторичные буферы команд.

Не все команды могут быть записаны во вторичные буферы команд. Но есть команды, которые могут быть записаны и которые не имеют ничего общего с рендерингом (и, следовательно, с проходами рендеринга) - копирование данных, отметка времени (запросы таймера) - это примеры. Они никак не связаны с проходами рендеринга, поэтому они не требуют от вас запуска прохода рендеринга.

Но если вы хотите записать команды рисования, и, как вы, вероятно, знаете, рисование может быть выполнено только из проходов рендеринга, то запуск рендеринга должен быть уже начат (в первичном буфере команд, который вызывает этот вторичный буфер команд).

Что касается функции vkAcquireNextImageKHR() - эта функция является независимой. Если под "выдачей" Вы подразумеваете запись, Вам не нужно вызывать эту функцию. Вы можете записывать любые (действительные) команды, которые вы хотите. Запись просто готовит команды для последующего использования, для подачи. То же относится и к названию Вашего вопроса:

Возможно генерировать вторичные буферы команд перед renderpass?

Я знаю, что это (надеюсь) только плохая формулировка, но Вы можете записать любой буфер команд в любое время. Это представление учитывает и порядок команд, записанных в представленных буферах команд. Итак, как вы хотите сгенерировать командный буфер перед проходом рендеринга? Если Вы хотите записать команды рисования и запустить проход рендеринга, Вам необходим объект прохода рендеринга. Если вы хотите вызвать вторичный буфер команд из основного буфера команд, и если этот вторичный буфер команд что-то рисует, то сначала вам нужно записать команду запуска прохода рендеринга. После этого Вы можете вызвать вторичный буфер команд. Но этот вторичный буфер команд уже должен быть записан:

Каждый элемент pCommandBuffers должен находиться в состоянии ожидания или выполнения.

Поэтому сначала нужно записать вторичный буфер команд, а затем записать первичный буфер команд, который вызывает этот вторичный буфер команд.

Но если вы хотите отправить командный буфер, в котором используется образ подкачки, этот образ должен быть уже получен. Как я (и другие) описали в вашем другом вопросе ( проблемы с циклическим рассмотрением кадровых буферов), вы не можете отправить команду, которая использует образ подкачки, если это изображение еще не получено. Но отправка и получение изображения не имеют ничего общего с записью буфера команд. Вы можете записать буферы команд раньше. Вы даже можете предварительно записать различные буферы команд для различных образов цепочки обмена. Опять же, запись просто готовит команды для последующего использования. Фактическое использование происходит с представлением. Таким образом, вы можете отправлять только те командные буферы, которые используют образы подкачки, которые уже были получены.

Надеюсь, это поможет;-).

Чтобы начать запись вторичного буфера команд, необходимо вызвать vkBeginCommandBuffer с VkCommandBufferInheritanceInfo объект. Если вы хотите выполнить дополнительный CB внутри прохода рендеринга, вы должны предоставить:

  1. VkRenderPass Объект для прохода будет выполнен в течение. Обратите внимание, что этот объект не является продуктом vkCmdBeginRenderPass,

  2. Индекс подпроцесса вышеупомянутого VkRenderPass что этот вторичный CB будет выполнен в течение.

Есть необязательный VkFramebuffer, который определяет изображения, которые вы будете рендерить. Но, как уже говорилось, это необязательно. В спецификации сказано, что предоставление этих данных может повысить производительность, но, тем не менее, это необязательно.

Поэтому нет, во вторичных CB нет ничего, что требовало бы наличия активного экземпляра прохода рендеринга на первичном CB, внутри которого он будет выполняться.

Другие вопросы по тегам