Действительно, поскольку мы собираемся WRITE
во вложении, нет необходимости использовать WRITE_BIT
(то есть сделать записи доступными) в dstAccessMask.
I Я не совсем уверен в вашей логике c здесь. Это должно быть WRITE
именно потому, что мы собираемся написать вложение.
Возможно, это поможет описать, что здесь происходит (из krOoze / Hello_Triangle / do c):
Цепи семафора 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
доступ.
Итак:
Презентация будет читать образ свопчейна и передавать сигнал семафора .
Мы связываем наши VkSubpassDependency
с сигналом (через pWaitDstStageMask
). Сигнал семафора уже охватывает все обращения к памяти, поэтому наша srcAccessMask = 0
.
Зависимость выполняет свою неявную зависимость от перехода макета (принимает ваш src
и изобретает некоторые внутренние dst
), затем происходит Layout Transition, который читает изображение и записывает его обратно, затем зависимость выполняет другую неявную зависимость (изобретает некоторую src
, которая покрывает переход макета, и использует ваш dst
).
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
.