Подпроходные зависимости для одного подпроцесса. Как? - PullRequest
0 голосов
/ 26 октября 2018

Итак, у меня есть проход рендеринга с одним подпроходом, который рисует непосредственно в кадровый буфер. Спецификация не заставляет меня использовать зависимости - если я их опускаю, реализация вставляет их неявно (хотя я не понимаю, почему она использует srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT для первого подпроцесса - этот этап означает самое начало, т.е. не подожди чего-нибудь).

Но, как обычно, с Vulkan - лучше быть явным. И здесь возникает путаница - несколько источников используют подпроцессы по-разному.

  1. Пример куба Sdk не использует их вообще.

  2. В Vulkan-туториале используется только один:

    dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
    dependency.dstSubpass = 0;
    dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    dependency.srcAccessMask = 0;
    dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    

    Почему srcAccessMask здесь равен нулю?

  3. API без секретов использует два:

    dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
    dependency.dstSubpass = 0;
    dependency.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
    dependency.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
    dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    

    и

    dependency.srcSubpass = 0;
    dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
    dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    dependency.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
    dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
    

    Не очень понятно, почему srcStageMask VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT в первом подпроходе - не этот этап следует использовать для зависимостей выполнения, но здесь мы нужна зависимость от памяти? Тот же вопрос о том, почему dstStageMask находится VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT во втором подпроходе?

  4. В примерах синхронизации Khronos используется один:

    dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
    dependency.dstSubpass = 0;
    dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    dependency.srcAccessMask = 0;
    dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    

    Почему srcAccessMask равно 0?

  5. А вот моя попытка с двумя зависимостями:

        dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
        dependency.dstSubpass = 0;
        dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // need to wait until
    presentation is finished reading the image
        dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
        dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // we are writing to
    the image in this stage
        dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    
    and
    
        dependency.srcSubpass = 0;
        dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
        dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // we are writing to
    the image in this stage
        dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
        dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // presentation reads
    image in this stage (is it?)
        dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
    

Все это очень запутанно. Как видите, несколько компетентных источников имеют разное видение. Какой использовать? Как понять эти зависимости?

1 Ответ

0 голосов
/ 26 октября 2018

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

Соответствующий раздел о приобретении / представлении образов swapchain можно найти здесь .

  1. это старый пример из-за множества особенностей синхронизациибыли должным образом прибиты

  2. Цель состоит в том, чтобы синхронизировать использование семафора для ожидания результата vkAcquireNextImage с рендерингом.Это опасность записи после чтения, и семафор будет включать синхронизацию видимости памяти.Поэтому в srcAccessMask нет необходимости.

  3. Опять же, барьер предназначен для синхронизации с семафором.При отправке буфера команд в очередь вы можете указать, какие этапы ожидают какие семафоры.В этом случае они используют нижнюю часть ступени трубы вместо VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

  4. того же ответа, что и 2, единственное отличие - с dstAccessMask

  5. На вики-странице, на которую я ссылался выше, используется следующее:

    /* 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};
    
    /* Normally, we would need an external dependency at the end as well since we are changing layout in finalLayout,
       but since we are signalling a semaphore, we can rely on Vulkan's default behavior,
       which injects an external dependency here with
       dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
       dstAccessMask = 0. */
    

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

...