«Синхронизация» перехода макета прохода рендеринга с семафором в сценарии Acquire-Present в Vulkan - PullRequest
2 голосов
/ 21 февраля 2020

Итак, есть официальный пример https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples#combined -graphicspresent-queue :

/* 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};

Может кто-нибудь предоставить мне соответствующие разделы в спецификации, которые объединяют гарантию (составляют цепочку из рассуждений), что при такой компоновке зависимостей переход не произойдет, пока семафор ожидания очереди (полученное изображение) не будет сигнализирован?

В частности, я не могу найти, как интерпретировать эту "зависимость от той же самой стадии к себе" .

Чтобы было ясно. Я нашел много мест, которые, кажется, здесь актуальны. Я читаю документы уже более месяца, но изо всех сил пытаюсь найти в них согласованность.

Например, когда (согласно спецификации) происходит операция доступности? Когда была отправлена ​​соответствующая операция зависимости от памяти (как в порядке отправки)? Если да, то когда будет представлена ​​зависимость от подпроцесса? Или это где-то между инструкциями области действия источника и инструкцией области назначения (как в If srcSubpass is equal to VK_SUBPASS_EXTERNAL, the first synchronization scope includes commands that occur earlier in submission order than the vkCmdBeginRenderPass). И если да, то на какие инструкции ссылается srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT в приведенном выше примере?

РЕДАКТИРОВАТЬ после ответа krOoze

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

Признаюсь, я неверно истолковал часть о цепочке зависимостей выполнения в spe c.

Итак, чтобы подвести итог. Чтобы определить рассматриваемый механизм в терминах Спецификации, мы имеем следующее:

  1. ожидание семафора операция происходит до подпрохода операция зависимости (здесь у меня есть некоторые проблемы на самом деле):

    6.4.2. Ожидание семафора *
    Операция ожидания семафора происходит после первого набора операций в зависимости выполнения и происходит до второго набора операций в зависимости выполнения.

    Но как быть уверенным, что наша операция зависимостей подпроцесса находится во втором наборе? Он находится в том же пакете, у него нет определенного порядка отправки в отношении зависимости подпроцесса (по крайней мере, я его не вижу), и определение второй области синхронизации семафора не полезно, потому что наша зависимость подпроцесса не возникает на этапе конвейера VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT (и это ограничение второй области синхронизации в случае vkQueueSubmit). Более того, область синхронизации в любом случае не определяет второй набор операций. Это отличный термин. Но я нашел еще одно утверждение, которое может быть полезным здесь (хорошо, если мы согласимся, что зависимость подпроцесса является частью рабочего элемента):

    4.3.5. Отправка в очередь
    Каждый пакет состоит из трех отдельных частей:

    1. Ноль или более семафоров для ожидания перед выполнением остальной части пакета.
    2. Ноль или более рабочих элементов для выполнения.
    3. Ноль или более семафоров для сигнала о завершении рабочих элементов.

    И мы должны быть уверен в этом порядке построения цепочки зависимостей выполнения:

  2. Ожидание семафора и зависимость подпроцесса составляют цепочку зависимостей выполнения согласно:

    6.1. Зависимости исполнения и памяти
    Цепочка зависимостей исполнения - это последовательность зависимостей исполнения , которые образуют отношение «до и после» между первой зависимостью A 'и конечной зависимостью B'. Для каждой последовательной пары зависимостей выполнения существует цепочка, если пересечение B S в первой зависимости и A S во второй зависимости не является пустым set.

    (подробности см. в ответе krOoze)

    Исходя из этого, мы знаем, что область назначения нашей зависимости subpass будет происходить после , сигнализируя семафор ( операция сигнала находится в исходной области действия операции ожидания семафора.
    Теперь у нас должно быть все в порядке с правилом перехода макета:

  3. Переход макета происходит после операции доступности для нашей зависимости подпроцесса:

    7.1. Создание рендеринга Pass
    Автоматическая c компоновка перехода от initialLayout происходит после операций доступности для всех зависимостей с srcSubpass, равным VK_SUBPASS_EXTERNAL, где dstSubpass использует вложение, которое будет перенесено.

    Если честно, мне все еще не хватает порядка между сигнализацией семафора и частью операции доступности в spe c, но я думаю, что это можно предположить.
    (вышеприведенное сработает, потому что доступность операция является частью операции зависимости от памяти:

    Операция, которая выполняет зависимость от памяти, генерирует:
    • Операция доступности с исходной областью всех записей в первой области доступа зависимости и область назначения домена устройства.

    хорошо, наша первая область доступа пуста, но все же это операция доступности, верно?)

Есть также следующее утверждение:

Для вложений, однако, su Зависимости bpass работают больше как VkImageMemoryBarrier, определенный аналогично описанному выше VkMemoryBarrier, индексы семейства очередей установлены в VK_QUEUE_FAMILY_IGNORED и имеют следующие макеты:
• Эквивалентом oldLayout является компоновка вложения в соответствии с описанием подпуска для srcSubpass. * 11 • Эквивалентом newLayout является макет вложения в соответствии с описанием подпроцесса для dstSubpass.

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

* Все цитаты из spe c из "Vulkan® 1.2.132 - A Спецификация (со всеми зарегистрированными расширениями Vulkan) "

1 Ответ

3 голосов
/ 21 февраля 2020

I go немного больше этого значения в krOoze / Hello_Triangle / do c. Что должно произойти в этом сценарии:

enter image description here

В частности, я не могу найти, как интерпретировать эту "зависимость от той же стадии к себе ".

Теперь, давайте сначала позаботимся об этой проблеме. Это то, что я люблю называть интуитивно понятной системой синхронизации .

Вы делаете , а не"синхронизировать этапы" или что-то в этом роде. Это интуиция, которая только вызовет у вас замешательство. Вы синхронизируете области.

Люди также путают конвейер с блок-схемой. Существует огромная разница в интуиции. В блок-схеме вы начинаете с начала, затем вы go проходите все этапы по порядку, затем вы закончите и навсегда закончите. Это , а не , что такое конвейер. Это никогда не начинается и никогда не заканчивается. Трубопровод просто есть. Это как настольная игровая доска. Вы набираете команды через конвейер, а они go через этапы, похожие на колышки на плате.

Команда синхронизации - это нечто, что вводит зависимость между двумя вещами: между исходная область синхронизации и конечная область синхронизации . Это гарантирует, что область sr c происходит до области dst.

A scope является некоторым подмножеством операций с очередями, и на какой стадии они в данный момент могут выполнять их выполнение.

Итак, с этой лучшей интуицией,

    .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,

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

Например, когда (согласно спецификации ) операция доступности происходит.

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

Операция доступности (если есть) происходит после области синхронизации источника. Затем происходит переход макета (если есть). Затем происходит операция видимости (если есть). И только после этого может выполняться область синхронизации источника.

Может ли кто-нибудь предоставить мне соответствующие разделы в спецификации, которые объединяют гарантию (составляют цепочку рассуждений)

Я просто хочу похлопать вас по голове за то, что вам нужна авторитетная информация ...: D

Итак, вам нужно знать формализм и номенклатуру. Это то, с чем описаны все примитивы синхронизации. Это только одна страница, но относительно трудно читать. Я попытался объяснить важные части выше. Я не буду здесь это цитировать, это 6.1. Зависимости исполнения и памяти глава.

Теперь у семафора есть своя глава. Важно отметить, что он ведет себя немного иначе для других команд, чем для vkQueueSubmit (что раздражает). В любом случае ( 6.4.2. Ожидание семафора ):

Вторая область синхронизации включает в себя все команды, представленные в одном пакете. В случае vkQueueSubmit вторая область синхронизации ограничена операциями на этапах конвейера, определенных маской этапа назначения , определенной соответствующим элементом pWaitDstStageMask. Кроме того, в случае vkQueueSubmit вторая область синхронизации дополнительно включает все команды, которые происходят позже в порядке отправки .

Вторая область доступа включает всю память доступ, осуществляемый устройством.

Пакет (для vkQueueSubmit) - единственный VkSubmitInfo. Порядок подачи также имеет свою главу; в основном это означает «все другие Пакеты, которые находятся позже в массиве отправки, а также любое будущее vkQueueSubmit в той же очереди».

Итак, это означает: «если вы ждете семафор, все команды в VkSubmitInfo могут достигнуть стадии pWaitDstStageMask только после того, как семафор был сигнализирован ".

Теперь важно понять, что делает Pass Render Pass. Помимо записанных команд у него есть и другие «синхронизируемые»: автоматические c переходы макета, операции загрузки и операции сохранения.

автоматический c переход макета:

Автоматическая c компоновка переходов от initialLayout происходит после операций доступности для всех зависимостей с srcSubpass, равным VK_SUBPASS_EXTERNAL, где dstSubpass использует вложение, которое будет переходить

Автоматическая c компоновка переходов в компоновку, используемую в подпроцессе, происходит до операций видимости для всех зависимостей с этим подпропуском как dstSubpass.

Так Проще говоря, переход макета находится внутри зависимости, которую определяет список VkSubpassDependency. Это происходит после .srcStageMask с .srcAccessMask. И это происходит до .dstSubpass и .dstStageMask с .dstAccessMask.

Операция загрузки:

Операция загрузки для каждого семпла во вложении происходит - до того, как записано команда, которая обращается к образцу в первом подпроцессе, где используется вложение. [...] Операции загрузки для вложений с цветным форматом выполняются на этапе конвейера VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT.

VK_ATTACHMENT_LOAD_OP_LOAD [...] Для вложений с цветным форматом используется тип доступа VK_ACCESS_COLOR_ATTACHMENT_READ_BIT.

VK_ATTACHMENT_LOAD_OP_CLEAR (или VK_ATTACHMENT_LOAD_OP_DONT_CARE) [...] Для вложений с цветным форматом используется тип доступа VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.

Операция загрузки происходит как часть первого подпроцесса, который использует вложение (ваш .dstSubpass). И вышесказанное однозначно определяет ваши .dstStageMask и .dstAccessMask)

Теперь дело доходит до нашего выбора pWaitDstStageMask и .srcStageMask и .srcAccessMask. Вы указываете, что это pWaitDstStageMask = COLOR_ATTACHMENT_OUTPUT, .srcStageMask = COLOR_ATTACHMENT_OUTPUT и .srcAccessMask = 0.

Операция ожидания семафора должна произойти, прежде чем VkSubpassDependency. Это указывается как цепочка зависимостей :

Цепочка зависимостей выполнения - это последовательность зависимостей выполнения, которые формируют отношение «до того» между первой зависимостью A ' и окончательная зависимость B '. Для каждой последовательной пары зависимостей выполнения существует цепочка, если пересечение B S в первой зависимости и A S в вторая зависимость не является пустым набором.

Т.е. два последующих примитива синхронизации также синхронизируются друг с другом и образуют переходное свойство. Наш A ' здесь - это сигнал семафора, а наш B' - это область видимости VkSubpassDependency. Наша B S - это область видимости семафора, т.е. pWaitDstStageMask. И наша A S является областью sr c нашего VkSubpassDependency.

Так что наше пересечение pWaitDstStageMask с .srcStageMask все еще COLOR_ATTACHMENT_OUTPUT , Таким образом, формируется цепочка зависимостей, которая гарантирует, что сигнал семафора происходит - до COLOR_ATTACHMENT_OUTPUT команд в подпроцессе 0 прохода рендеринга.

Теперь, собрав все воедино: сигнал семафора из vkAcquireNextImage делает образ swapchain доступным из для чтения механизма представления. Ожидание семафора в vkQueueSubmit делает образ подкачки видимым для , все команды в пакете ограничены COLOR_ATTACHMENT_OUTPUT. VkSubpassDependency цепочки к этому семафору ждут. Изображение по-прежнему видно , поэтому дополнительная зависимость от памяти не требуется, поэтому наш .srcAccessMask равен 0. Переход макета записывает изображение и делает его (неявно) доступным из перехода макета и видимым для независимо от того, * .dst* был предоставлен VkSubpassDependency.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...