Перемещение макетов изображений с барьером или проходами рендеринга
В документах на вулканском языке упоминается, что макеты движущихся изображений в проходах рендера VkAttachmentDescription
структура) предпочтительнее по сравнению с их перемещением с использованием барьеров (т.е. vkCmdPipelineBarrier
). Я могу понять, что, поскольку последние вводят точки синхронизации, которые ограничивают параллельное выполнение.
Теперь рассмотрим типичный пример: переход от VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
в VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
, В этом случае ресурс будет считываться в шейдере, но для того, чтобы сделать это безопасно, необходимо синхронизировать запись цветового вложения с чтением в шейдере. Другими словами, нам все равно нужно использовать барьер, и перемещение макета на этапе рендеринга, похоже, не дает никакого преимущества.
Можете как-нибудь объяснить, как все это работает в деталях? В каких ситуациях есть реальное преимущество перемещения макетов на проходах рендеринга? Существуют ли (практические) изменения макета, которые не требуют дальнейшей синхронизации?
1 ответ
Во-первых, у вас нет выбора. API заставляет вас предоставлять finalLayout
и промежуточный VkAttachmentReference::layout
s. Ты можешь использовать vkCmdPipelineBarrier
внутри прохода рендеринга условно (так называемая самостоятельная подпрограмма), но одно из правил заключается в том, что вы не можете изменять макет прикрепленного изображения:
Если
VkImageMemoryBarrier
используется, диапазон изображения и подресурса изображения, указанный в барьере, должен быть подмножеством одного из представлений изображения, используемых кадровым буфером в текущем подпроходе. Дополнительно,oldLayout
должен быть равенnewLayout
и обаsrcQueueFamilyIndex
а такжеdstQueueFamilyIndex
должен бытьVK_QUEUE_FAMILY_IGNORED
,
Таким образом, во время прохода рендеринга вы можете изменить макет только с помощью механизма прохода рендеринга, или вы должны быть вне прохода рендеринга. Остается обсудить только случай "за пределами рендеринга":
Хороший способ думать о проходе рендеринга состоит в том, что он (потенциально, на основе платформы) копирует ресурс (используя loadOp
) в специализированную память, а когда это сделано, копирует ее обратно (используя storeOp
) назад к памяти общего назначения.
При этом разумно предположить, что вы можете получить переход к макету finalLayout
бесплатно как часть storeOp
, (И аналогично переход от initialLayout
к первому VkAttachmentReference::layout
как часть loadOp
Итак, имеет смысл использовать переход макета как часть рендеринга, если это возможно \ достаточно удобно.