Events are a synchronization primitive that can be used to insert a fine-grained dependency between commands submitted to the same queue, or between the host and a queue. Events have two states - signaled and unsignaled. An application can signal an event, or unsignal it, on either the host or the device. A device can wait for an event to become signaled before executing further operations. No command exists to wait for an event to become signaled on the host, but the current state of an event can be queried.
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;
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 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.4. 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.
When vkSetEvent
is executed on the host, it defines an event signal
operation which sets the event to the signaled state.
If event
is already in the signaled state when vkSetEvent
is
executed, then vkSetEvent
has no effect, and no event signal operation
occurs.
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.
When vkResetEvent
is executed on the host, it defines an event
unsignal operation which resets the event to the unsignaled state.
If event
is already in the unsignaled state when vkResetEvent
is
executed, then vkResetEvent
has no effect, and no event unsignal
operation occurs.
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 source stage mask used to determine when the event
is signaled.
When vkCmdSetEvent
is submitted to a queue, it defines an execution
dependency on commands that were submitted before it, and defines an event
signal operation which sets the event to the signaled state.
The first synchronization scope
includes every command previously submitted to the same queue, including
those in the same command buffer and batch.
The synchronization scope is limited to operations on the pipeline stages
determined by the source stage mask specified by stageMask
.
The second synchronization scope includes only the event signal operation.
If event
is already in the signaled state when vkCmdSetEvent
is
executed on the device, then vkCmdSetEvent
has no effect, no event
signal operation occurs, and no execution dependency is generated.
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 unsignaled.
stageMask
specifies the source stage mask used to determine when the event
is unsignaled.
When vkCmdResetEvent
is submitted to a queue, it defines an execution
dependency on commands that were submitted before it, and defines an event
unsignal operation which resets the event to the unsignaled state.
The first synchronization scope
includes every command previously submitted to the same queue, including
those in the same command buffer and batch.
The synchronization scope is limited to operations on the pipeline stages
determined by the source stage mask specified by stageMask
.
The second synchronization scope includes only the event unsignal operation.
If event
is already in the unsignaled state when vkCmdResetEvent
is executed on the device, then vkCmdResetEvent
has no effect, no
event unsignal operation occurs, and no execution dependency is generated.
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
is the source stage mask
dstStageMask
is the destination stage mask.
memoryBarrierCount
is the length of the pMemoryBarriers
array.
pMemoryBarriers
is a pointer to an array of VkMemoryBarrier
structures.
bufferMemoryBarrierCount
is the length of the
pBufferMemoryBarriers
array.
pBufferMemoryBarriers
is a pointer to an array of
VkBufferMemoryBarrier
structures.
imageMemoryBarrierCount
is the length of the
pImageMemoryBarriers
array.
pImageMemoryBarriers
is a pointer to an array of
VkImageMemoryBarrier
structures.
When vkCmdWaitEvents
is submitted to a queue, it defines a memory
dependency between prior event signal operations, and subsequent commands.
The first synchronization scope only includes event signal operations that
operate on members of pEvents
, and the operations that happened-before
the event signal operations.
Event signal operations performed by vkCmdSetEvent
that were
previously submitted to the same queue are included in the first
synchronization scope, if the logically latest pipeline stage in their stageMask
parameter is
logically earlier than or equal
to the logically latest pipeline
stage in srcStageMask
.
Event signal operations performed by vkSetEvent
are only included in
the first synchronization scope if VK_PIPELINE_STAGE_HOST_BIT
is
included in srcStageMask
.
The second synchronization scope
includes commands subsequently submitted to the same queue, including those
in the same command buffer and batch.
The second synchronization scope is limited to operations on the pipeline
stages determined by the destination stage mask specified by dstStageMask
.
The first access scope is
limited to access in the pipeline stages determined by the
source stage mask specified by
srcStageMask
.
Within that, the first access scope only includes the first access scopes
defined by elements of the pMemoryBarriers
,
pBufferMemoryBarriers
and pImageMemoryBarriers
arrays, which
each define a set of memory barriers.
If no memory barriers are specified, then the first access scope includes no
accesses.
The second access scope is
limited to access in the pipeline stages determined by the
destination stage mask specified
by dstStageMask
.
Within that, the second access scope only includes the second access scopes
defined by elements of the pMemoryBarriers
,
pBufferMemoryBarriers
and pImageMemoryBarriers
arrays, which
each define a set of memory barriers.
If no memory barriers are specified, then the second access scope includes
no accesses.
![]() | Note |
---|---|
|
![]() | Note |
---|---|
Applications should be careful to avoid race conditions when using events.
There is no direct ordering guarantee between a |