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 |