Semaphores are used to coordinate queue operations both within a queue and between different queues. A semaphore’s status is always either signaled or unsignaled.
Semaphores are represented by VkSemaphore
handles:
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)
To create a new semaphore object, use the command
VkResult vkCreateSemaphore( VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore);
device
is the logical device that creates the semaphore.
pCreateInfo
points to a VkSemaphoreCreateInfo
structure
specifying the state of the semaphore object.
pAllocator
controls host memory allocation as described in the
Memory Allocation chapter.
pSemaphore
points to a handle in which the resulting semaphore
object is returned.
The semaphore is created in the unsignaled state.
The VkSemaphoreCreateInfo
structure is defined as:
typedef struct VkSemaphoreCreateInfo { VkStructureType sType; const void* pNext; VkSemaphoreCreateFlags flags; } VkSemaphoreCreateInfo;
sType
is the type of this structure.
pNext
is NULL
or a pointer to an extension-specific structure.
flags
is reserved for future use.
To destroy a semaphore, call:
void vkDestroySemaphore( VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator);
device
is the logical device that destroys the semaphore.
semaphore
is the handle of the semaphore to destroy.
pAllocator
controls host memory allocation as described in the
Memory Allocation chapter.
Semaphores can be signaled by including them in a batch as part of a queue submission command, defining a queue operation to signal that semaphore. This semaphore signal operation defines the first half of a memory dependency, guaranteeing that all memory accesses defined by the submitted queue operations in the batch are made available, and that those queue operations have completed execution.
Semaphore signal operations for vkQueueSubmit
additionally include all
queue operations previously submitted via vkQueueSubmit
in their half
of a memory dependency, and all batches that are stored at a lower index in
the same pSubmits
array.
Signaling of semaphores can be waited on by similarly including them in a batch, defining a queue operation to wait for a signal. A semaphore wait operation defines the second half of a memory dependency for the semaphores being waited on. This half of the memory dependency guarantees that the first half has completed execution, and also guarantees that all available memory accesses are made visible to the queue operations in the batch.
Semaphore wait operations for vkQueueSubmit
additionally include all
queue operations subsequently submitted via vkQueueSubmit
in their
half of a memory dependency, and all batches that are stored at a higher
index in the same pSubmits
array.
When queue execution reaches a semaphore wait operation, the queue will stall execution of queue operations in the batch until each semaphore becomes signaled. Once all semaphores are signaled, the semaphores will be reset to the unsignaled state, and subsequent queue operations will be permitted to execute.
Semaphore wait operations defined by vkQueueSubmit
only wait at
specific pipeline stages, rather than delaying all of each command buffer’s
execution, with the pipeline stages determined by the corresponding element
of the pWaitDstStageMask
member of VkSubmitInfo
.
Execution of work by those stages in subsequent commands is stalled until
the corresponding semaphore reaches the signaled state.
![]() | Note |
---|---|
A common scenario for using If an image layout transition needs to be performed on a swapchain image
before it is used in a framebuffer, that can be performed as the first
operation submitted to the queue after acquiring the image, and should not
prevent other work from overlapping with the presentation operation.
For example, a
Alternatively, This barrier accomplishes a dependency chain between previous presentation
operations and subsequent color attachment output operations, with the
layout transition performed in between, and does not introduce a dependency
between previous work and any vertex processing stages.
More precisely, the semaphore signals after the presentation operation
completes, then the semaphore wait stalls the
(The primary use case for this example is with the presentation extensions,
thus the |