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 |
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.