Events represent a fine-grained synchronization primitive that can be used to gauge progress through a sequence of commands executed on a queue by Vulkan. An event is initially in the unsignaled state. It can be signaled by a device, using commands inserted into the command buffer, or by the host. It can also be reset to the unsignaled state by a device or the host. The host can query the state of an event. A device can wait for one or more events to become signaled.
Events are represented by VkEvent
handles:
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent)
To create an event, call:
VkResult vkCreateEvent( VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent);
device
is the logical device that creates the event.
pCreateInfo
is a pointer to an instance of the
VkEventCreateInfo
structure which contains information about how
the event is to be created.
pAllocator
controls host memory allocation as described in the
Memory Allocation chapter.
pEvent
points to a handle in which the resulting event object is
returned.
When created, the event object is in the unsignaled state.
The VkEventCreateInfo
structure is defined as:
typedef struct VkEventCreateInfo { VkStructureType sType; const void* pNext; VkEventCreateFlags flags; } VkEventCreateInfo;
flags
is reserved for future use.
To destroy an event, call:
void vkDestroyEvent( VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator);
device
is the logical device that destroys the event.
event
is the handle of the event to destroy.
pAllocator
controls host memory allocation as described in the
Memory Allocation chapter.
To query the state of an event from the host, call:
VkResult vkGetEventStatus( VkDevice device, VkEvent event);
device
is the logical device that owns the event.
event
is the handle of the event to query.
Upon success, vkGetEventStatus
returns the state of the event object
with the following return codes:
Table 6.1. Event Object Status Codes
Status | Meaning |
---|---|
| The event specified by |
| The event specified by |
If a vkCmdSetEvent
or vkCmdResetEvent
command is pending
execution, then the value returned by this command may immediately be out
of date.
The state of an event can be updated by the host.
The state of the event is immediately changed, and subsequent calls to
vkGetEventStatus
will return the new state.
If an event is already in the requested state, then updating it to the same
state has no effect.
To set the state of an event to signaled from the host, call:
VkResult vkSetEvent( VkDevice device, VkEvent event);
device
is the logical device that owns the event.
event
is the event to set.
To set the state of an event to unsignaled from the host, call:
VkResult vkResetEvent( VkDevice device, VkEvent event);
device
is the logical device that owns the event.
event
is the event to reset.
The state of an event can also be updated on the device by commands inserted in command buffers. To set the state of an event to signaled from a device, call:
void vkCmdSetEvent( VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask);
commandBuffer
is the command buffer into which the command is
recorded.
event
is the event that will be signaled.
stageMask
specifies the pipeline stage at which the state of
event
is updated as described below.
To set the state of an event to unsignaled from a device, call:
void vkCmdResetEvent( VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask);
commandBuffer
is the command buffer into which the command is
recorded.
event
is the event that will be reset.
stageMask
specifies the pipeline stage at which the state of
event
is updated as described below.
For both vkCmdSetEvent
and vkCmdResetEvent
, the status of
event
is updated once the pipeline stages specified by stageMask
(see Section 6.5.2, “Pipeline Stage Flags”) have completed executing
prior commands.
The command modifying the event is passed through the pipeline bound to the
command buffer at time of execution.
To wait for one or more events to enter the signaled state on a device, call:
void vkCmdWaitEvents( VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers);
commandBuffer
is the command buffer into which the command is
recorded.
eventCount
is the length of the pEvents
array.
pEvents
is an array of event object handles to wait on.
srcStageMask
(see Section 6.5.2, “Pipeline Stage Flags”) is the
bitwise OR of the pipeline stages used to signal the event object
handles in pEvents
.
dstStageMask
is the pipeline stages at which the wait will occur.
pMemoryBarriers
is a pointer to an array of
memoryBarrierCount
VkMemoryBarrier
structures.
pBufferMemoryBarriers
is a pointer to an array of
bufferMemoryBarrierCount
VkBufferMemoryBarrier
structures.
pImageMemoryBarriers
is a pointer to an array of
imageMemoryBarrierCount
VkImageMemoryBarrier
structures.
See Section 6.5.3, “Memory Barriers” for more details about memory
barriers.
vkCmdWaitEvents
waits for events set by either vkSetEvent
or
vkCmdSetEvent
to become signaled.
Logically, it has three phases:
dstStageMask
(see
Section 6.5.2, “Pipeline Stage Flags”) until the eventCount
event objects specified by pEvents
become signaled.
Implementations may wait for each event object to become signaled in
sequence (starting with the first event object in pEvents
, and
ending with the last), or wait for all of the event objects to become
signaled at the same time.
pMemoryBarriers
,
pBufferMemoryBarriers
and pImageMemoryBarriers
(see
Section 6.5.3, “Memory Barriers”).
dstStageMask
Implementations may not execute commands in a pipelined manner, so
vkCmdWaitEvents
may not observe the results of a subsequent
vkCmdSetEvent
or vkCmdResetEvent
command, even if the stages in
dstStageMask
occur after the stages in srcStageMask
.
Commands that update the state of events in different pipeline stages may execute out of order, unless the ordering is enforced by execution dependencies.
![]() | Note |
---|---|
Applications should be careful to avoid race conditions when using events.
For example, an event should only be reset if no |
An act of setting or resetting an event in one queue may not affect or be visible to other queues. For cross-queue synchronization, semaphores can be used.