Search code examples
renderingvulkan

Sync buffer between queue on Vulkan


I'm developing a game with two command queue. One for compute shader to compute heavy work, it takes about 40ms, one for rendering, it takes less than 16ms.

I need use compute result to modify rendering content, but compute is much slower than rendering, I use conditional rendering to skip the modification if compute result is not ready.

typedef struct VkConditionalRenderingBeginInfoEXT {
    VkStructureType                   sType;
    const void*                       pNext;
    VkBuffer                          buffer;
    VkDeviceSize                      offset;
    VkConditionalRenderingFlagsEXT    flags;
} VkConditionalRenderingBeginInfoEXT;

I write the buffer on compute queue after the compute is finished, then call vkCmdBeginConditionalRenderingEXT on rendering queue.

Now the problem is, I can't set proper memory barrier for the buffer because it is accessed across queues, so my question is how to set memory barrier to make sure the buffer writing on compute queue is finished before rendering queue to read it.


Solution

  • Why can't you use proper memory barriers?

    Concurrent cross-queue resource usage is permitted using buffers created with VK_SHARING_MODE_CONCURRENT. This means you bypass the queue ownership and transfer requirements, but you still need to ensure the visibility/availability of the data to the appropriate pipeline stage.

    After running the compute work, get the compute queue to issue a barrier to ensure availability ...

    srcStage=VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
    srcAccessMask=VK_ACCESS_SHADER_WRITE_BIT
    dstStage=VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT
    dstAccessMask=VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT
    

    ... and to be sure I'd probably issue the same type of barrier on the graphics queue before the vkCmdBeginConditionalRenderingEXT() command, to ensure visibility.