这三种同步机制在 Vulkan 中有着不同的用途和特点:
VkSemaphore - GPU 与 GPU 之间的同步
- 主要用于队列操作之间的同步(GPU 工作同步)
- 典型用例:渲染完成后再进行显示
// 示例:等待渲染完成后再显示
VkSubmitInfo submitInfo = {};
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &renderFinishedSemaphore;
VkPresentInfoKHR presentInfo = {};
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = &renderFinishedSemaphore;VkFence - CPU 与 GPU 之间的同步
- 用于让 CPU 等待 GPU 操作完成
- 可以在 CPU 端被查询和等待
- 典型用例:确保资源不会在 GPU 使用时被 CPU 修改
// 示例:等待命令缓冲执行完成
vkQueueSubmit(queue, 1, &submitInfo, fence);
vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &fence);VkEvent - GPU 内部的细粒度同步
- 用于命令缓冲内部或命令缓冲之间的精确同步
- 可以在 CPU 端设置和重置
- 典型用例:在管线中的特定点同步操作
// 在命令缓冲中使用Event
vkCmdSetEvent(commandBuffer, event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
vkCmdWaitEvents(commandBuffer, 1, &event,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, // srcStageMask
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // dstStageMask
0, nullptr, // memoryBarriers
0, nullptr, // bufferMemoryBarriers
0, nullptr); // imageMemoryBarriers选择建议
- 需要 GPU 队列间同步时,用 Semaphore
- 需要 CPU 等待 GPU 时,用 Fence
- 需要精细的 GPU 命令同步时,用 Event