Event
Event是一个细粒度的同步原语,用于精确的界定管线里发生的操作。
Event用于同步提交到同一队列的不同命令,或者同步CPU和队列。Event不能用于不同队列的命令间的同步。
Event有两种状态signaled和unsignaled。
无论是设备还是主机,都可以直接操作event,不过他们是有区别的,主机可以使用vkGetEventStatus立即获取事件对象的状态,但是不能直接等待事件,而设备正好相反,不能直接获取事件对象的状态,但是能等待一个或者多个事件。
Event使用场景
在官方的博客里有这样一句话:
1 | Another tool for synchronization in Vulkan is the event, which uses source stage masks and destination stage masks just like pipeline barriers, and can be quite useful when we need to specify and run parallel computation. |
也就是说event一般用于并行计算中,常用于compute shader中。在渲染管线中,很少见到events。
Event与Barrier的不同
1 | The key difference between events and pipeline barriers is that event barriers occur in two parts. |
barrier是一次设置的,而Event则是分开在两部分设置的。
1 | The first part is setting an event using vkCmdSetEvent, and the second is waiting for an event with vkCmdWaitEvents |
在第一部分用vkCmdSetEvent设置event为signaled,在第二部分我们等待events时,用vkCmdWaitEvents。
而在 vkCmdSetEvent 和 vkCmdWaitEvents之间的所有的commands都不受影响。
Event的API
vkCreateEvent
创建event
1 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent( |
创建事件参数相当简单:
1 | // Now create an event and wait for it on the GPU |
新创建的事件的状态是unsignaled
vkDestroyEvent
销毁event
有创建就有销毁,如下所示:
1 | VKAPI_ATTR void VKAPI_CALL vkDestroyEvent( |
vkSetEvent
改变event的状态
1 | vkSetEvent(device, event); |
这个一般由主机调用,用来改变event的状态
vkResetEvent
重置event状态
1 | vkResetEvent(device, event); |
vkGetEventStatus
获取event的状态
1 | VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus( |
返回值是下面两者之一:
1 | VK_EVENT_SET = 3, 有信号状态 |
vkGetEventStatus一般是主机用来获取event的状态的
vkCmdSetEvent
将event放到commandBuffer中
1 | VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent( |
我们看到这里有一个stageMask
参数,它表示event需要等待前面的commands的那个stage完成。
a stageMask parameter that marks the stages to wait for in previous commands before signalling the event
vkCmdWaitEvents
等待事件。
1 | VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents( |
参数行为跟Barrier完全一致,这里不再重复。
这个函数主要是设备用来等待事件的。对于主机而言,它可以直接用vkGetEventStatus来获取event的状态,但是对于设备来说,就无法调用vkGetEventStatus函数了,所以用vkCmdWaitEvents来等待一个或者多个事件。
Event使用举例
假设有下面的计算管线:
1 | // Three dispatches that don’t have conflicting resource accesses |
对应如下运行图示
参考资料
https://www.khronos.org/blog/understanding-vulkan-synchronization