воскресенье, 6 марта 2016 г.

Vulkan API, Synchronization primitives, Semaphores

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



Semaphores

Семафоры используются для координации действий между очередями и между задачами внутри одной очереди. Приложение может связать семфор с ресурсом или группой ресурсов для передачи владения общими данными. Статус семафора всегда либо signaled либо unsignaled. Статус семафора меняется очередью и его можно ожидать как в этой же очереди так и в других очередях.
Для создания объекта семафора используется команда:

VkResult vkCreateSemaphore(
VkDevice device,
const VkSemaphoreCreateInfo * pCreateInfo,
const VkAllocationCallbacks * pAllocator,
VkSemaphore * pSemaphore);

• device - логическое устройство, создающее семафоры.
• pCreateInfo - указатель на структуру VkSemaphoreCreateInfo, определяющую состояние семафора.
• pAllocator - контролирует выделение памяти хостом.
• pSemaphore - указатель на хэндл VkSemaphore, куда будет возвращен созданный семафор в состоянии unsignaled.

Возвращаемые коды ошибок:
Success
• VK_SUCCESS
Failure
• VK_ERROR_OUT_OF_HOST_MEMORY
• VK_ERROR_OUT_OF_DEVICE_MEMORY

Структура VkSemaphoreCreateInfo определена как:
typedef struct VkSemaphoreCreateInfo {
VkStructureType sType;
const void * pNext;
VkSemaphoreCreateFlags flags;
} VkSemaphoreCreateInfo;

• sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO
• pNext = NULL
• flags - зарезервировано, равен 0

Чтоб уничтожить семафор необходимо вызвать команду:
void vkDestroySemaphore(
VkDevice device,
VkSemaphore semaphore,
const VkAllocationCallbacks * pAllocator);

• semaphore - не должен быть связан с командами в очереди, которые еще не были завершены в этой очереди.

Чтоб послать сигнал семафору из очереди, включите его в качестве элемента массива структуры VkSubmitInfo, передаваемой через параметр pSubmitInfo в вызов vkQueueSubmit, или как элемент массива VkBindSparseInfo, передаваемого через параметр pBindInfo в вызов vkQueueBindSparse. Семафоры включенные в массив SignalSemaphores одного из элементов задания очереди сигнализируют как только выполнение очереди дойдет до соответствующей операции и все предыдущие задачи в очереди будут завершены. Любая из операций, ожидающая этот семафор в другой очереди, будет завершена как только этот семафор получит сигнал.

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

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

Заметки:
Общая практика использования pWaitDstStageMask со значениями, отличными от VK_PIPELINE_STAGE_ALL_COMMANDS_BIT это когда происходит синхронизация операций представления оконной системы с последующими буферами команд, которые рендерят следующий кадр. В этом случае, подготавливаемое изображение не должно быть перезаписано пока не завершится отображение этой картинки, но другие этапы пайплайна могут быть выполнены без ожидания.
Флаг VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT предотвращает последующие записи в color attachment, пока не будет получен сигнал от семафора. Некоторые реализации Вулкана способны выполнять операции передачи и/или обработку вершин до того как будет получен сигнал семафора. Если передача изображения должна быть выполнена в изображение swapchain, прежде чем оно будет использовано в буфере кадра, то это может быть выполнено в качестве первой операции в отправленной в очередь после получения изображения и не должно препятствовать другой работе операций отображения.
К примеру, VkImageMemoryBarrier может использовать:
• srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
• srcAccessMask = VK_ACCESS_MEMORY_READ_BIT
• dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
• dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT.
• oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
• newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
В качестве альтернативы, oldLayout может быть VK_IMAGE_LAYOUT_UNDEFINED, если содержимое изображения должно быть сохранено.
Этот барьер решает цепочку зависимостей между предыдущими операциями отображения и последующими операциями вывода в color attachment, с выполнением передачи лайаута между ними, и не вводит зависимостей между предыдущими задачами и этапами обработки вершин. Если боле точно, то семафор сигнализирует после того как операция отображения завершена, после этого семафор простаивает в ожидании этапа VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, то есть есть зависимость от самого себя и такого же этапа с передачей лайаута между ними.

Комментариев нет:

Отправить комментарий