Зависимость подпроцесса синхронизации WSI и ссылка на вывод цветового вложения - PullRequest
1 голос
/ 20 апреля 2020

Мне кажется, я понимаю, как работает синхронизация Vulkan, но у меня есть проблема с пониманием синхронизации с WSI.

Примеры синхронизации , мы можем найти этот код

/* Only need a dependency coming in to ensure that the first
   layout transition happens at the right time.
   Second external dependency is implied by having a different
   finalLayout and subpass layout. */
VkSubpassDependency dependency = {
    .srcSubpass = VK_SUBPASS_EXTERNAL,
    .dstSubpass = 0,
    // .srcStageMask needs to be a part of pWaitDstStageMask in the WSI semaphore.
    .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    .srcAccessMask = 0,
    .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    .dependencyFlags = 0};

По-моему, это должно быть что-то вроде этого:

VkSubpassDependency dependency = {
    .srcSubpass = VK_SUBPASS_EXTERNAL,
    .dstSubpass = 0,
    // .srcStageMask needs to be a part of pWaitDstStageMask in the WSI semaphore.
    .srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE,
    .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    .srcAccessMask = 0,
    .dstAccessMask = 0,
    .dependencyFlags = 0};

Действительно, поскольку мы собираемся ЗАПИСАТЬ вложение, нет необходимости использовать WRITE_BIT (имеется в виду сделать записи доступными) в dstAccessMask.

Но истинная проблема в srcStageMask.

Я понимаю, почему dstStageMask равен COLOR_ATTACHMENT_OUTPUT_BIT. Это потому, что нормально работать на предыдущих этапах, поскольку мы не касаемся вложения.

Однако для srcStageMask я ничего не видел в связи между WSI и COLOR_ATTACHMENT_OUTPUT_BIT , Для меня переход макета должен появиться в конце презентации и непосредственно перед началом этапа COLOR_ATTACHMENT_OUTPUT. И конец презентации, для меня, должен быть представлен BOTTOM_OF_PIPE, а не COLOR_ATTACHMENT_OUTPUT

Где я ошибаюсь?

1 Ответ

2 голосов
/ 20 апреля 2020

Действительно, поскольку мы собираемся WRITE во вложении, нет необходимости использовать WRITE_BIT (то есть сделать записи доступными) в dstAccessMask.

I Я не совсем уверен в вашей логике c здесь. Это должно быть WRITE именно потому, что мы собираемся написать вложение.

Возможно, это поможет описать, что здесь происходит (из krOoze / Hello_Triangle / do c):

swapchain image sync

Цепи семафора VkSubpassDependency (через pWaitDstStageMask). Затем он выполняет переход макета. Затем он синхронизируется с Load Op. (Затем в подпроцессе происходит загрузка Op. И в подпрограмме vkDraw s появляются какие-то вещи в образе swapchain.)

Теперь предположительно (как это типично для первого использования образа swapchain) наш Load Op равен VK_ATTACHMENT_LOAD_OP_CLEAR , Это означает VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT доступ.

Итак:

  1. Презентация будет читать образ свопчейна и передавать сигнал семафора .

  2. Мы связываем наши VkSubpassDependency с сигналом (через pWaitDstStageMask). Сигнал семафора уже охватывает все обращения к памяти, поэтому наша srcAccessMask = 0.

  3. Зависимость выполняет свою неявную зависимость от перехода макета (принимает ваш src и изобретает некоторые внутренние dst ), затем происходит Layout Transition, который читает изображение и записывает его обратно, затем зависимость выполняет другую неявную зависимость (изобретает некоторую src, которая покрывает переход макета, и использует ваш dst).

  4. Load Op происходит в субпроходе, и вы должны четко убедиться, что это происходит после всего вышеперечисленного. Таким образом, ваш dst в вашей зависимости должен быть VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, чтобы покрыть нагрузку.

Теперь существует три типа опасностей памяти: чтение → запись, запись → пишите и пишите → читайте (и читайте → читать не представляет опасности). В WWH что-то пишет ресурс, в то время как другие пишут это тоже. Не ясно, какая запись происходит последней, поэтому содержимое памяти становится мусором. В RWH и WRH чтение и запись могут происходить одновременно. Неясно, видит ли чтение неизмененную память или записанную (т. Е. Читает мусор).

Без явной зависимости переход макета и последующая загрузка Op образуют опасность записи → записи. Поэтому dstAccessMask должно не быть 0, чтобы устранить опасность и убедиться, что одна запись происходит до второй.

(Возможно, стоит отметить, что мы вводим VkSubpassDependency исключительно для перехода к макету. В противном случае ожидание семафора уже будет всем необходимым. По умолчанию srcStageMask = TOP_OF_PIPE, что означает, что без явной зависимости переход макета может произойти до ожидания семафора, то есть до того, как презентация закончит его чтение; это будет опасность чтения и записи).


Для меня переход макета должен появиться в конце презентации и непосредственно перед началом этапа COLOR_ATTACHMENT_OUTPUT. И конец презентации, для меня, должен быть представлен BOTTOM_OF_PIPE, а не COLOR_ATTACHMENT_OUTPUT

У нас здесь есть немного выбора: pWaitDstStageMask = dependency.srcStageMask = ?

Теперь наша ситуация это:

vkBeginCommandBuffer();
[possibly vkCmdDispatch()?]
vkBeginRenderPass();
vkCmdDraw(); // does vertex shading + fragment shading, then color writes
vkEndRenderPass();
vkEndCommandBuffer();

vkQueueSubmit(.pwaitDstStageMask = ?);

Если мы используем VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, то ожидание семафора не блокирует запуск гипотетического vkCmdDispatch() (VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT). И Зависимость Subpass src также не заставляет его завершать sh. Отлично!

Используемая стадия не должна быть более ранней, чем VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT. Например, с VK_PIPELINE_STAGE_ALL_COMMANDS ожидание семафора излишне заблокирует vkCmdDispatch(), а также вершинный и фрагментный шейдер vkCmdDraw. Между тем, изображение подкачки нам нужно только тогда, когда нам действительно нужно записать его в Load Op (что, как вы можете себе представить, происходит, когда vkCmdDraw() достигает точки, необходимой для выполнения цветной записи).

Теперь мы мог выбрать VK_PIPELINE_STAGE_BOTTOM_OF_PIPE. Семафор ничего не блокирует (dstStage\pWaitDstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE означает то же самое, что и «ничто»). Большой! Но Зависимость Subpass теперь блокирует все (srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE означает то же самое как VK_PIPELINE_STAGE_ALL_COMMANDS). Это означает, что наш vkCmdDispatch должен закончить sh, прежде чем начнется наш подпроход. Не так здорово ...

Итак, лучшая практика - использовать pWaitDstStageMask = dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT.

...