You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用VK_SHARE_MODE_CONCURRENT时是否需在各队列设置内存屏障?

Vulkan中VK_SHARING_MODE_CONCURRENT模式下的同步屏障用法疑问

我们有一个传输队列(A)和一个图形队列(B),通过队列A向顶点缓冲区传输数据完成初始化。

已知若缓冲区以VK_SHARING_MODE_EXCLUSIVE创建,复制命令后需要两个屏障完成队列所有权转移:队列A释放所有权,队列B获取所有权,对应代码如下:

队列A中的代码

VkBufferMemoryBarrier barrierA = {
    .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
    .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
    .dstAccessMask = 0,
    .srcQueueFamilyIndex = transferQueueFamily,
    .dstQueueFamilyIndex = graphicsQueueFamily,
    .buffer = vertexBuffer,
    .offset = 0,
    .size = VK_WHOLE_SIZE
};

vkCmdPipelineBarrier(transferCmdBuffer,
    VK_PIPELINE_STAGE_TRANSFER_BIT,
    VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
    0,
    0, nullptr,
    1, &barrierA,
    0, nullptr);

队列B中的代码

VkBufferBarrier barrierB = {
    .sType = VK_STRUCTURE_TYPE_BUFFER_BARRIER,
    .srcAccessMask = 0,
    .dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
    .srcQueueFamilyIndex = transferQueueFamily,
    .dstQueueFamilyIndex = graphicsQueueFamily,
    .buffer = vertexBuffer,
    .offset = 0,
    .size = VK_WHOLE_SIZE
};

vkCmdPipelineBarrier(graphicsCmdBuffer,
    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
    VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
    0,
    0, nullptr,
    1, &barrierB,
    0, nullptr);

我现在的疑问是关于VK_SHARING_MODE_CONCURRENT模式的用法:已知该模式无需进行队列所有权转移,但不确定是否仍需要在两个队列中各设置一个屏障(去掉srcQueueFamilyIndex和dstQueueFamilyIndex,代码如下),还是仅需在图形队列B中设置单个屏障(因为传输队列不支持VK_PIPELINE_STAGE_VERTEX_INPUT_BIT),相关代码示例如下:

方案1:队列A和队列B各设置一个屏障

队列A中的代码

VkBufferMemoryBarrier barrierA = {
    .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
    .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
    .dstAccessMask = 0,
    .buffer = vertexBuffer,
    .offset = 0,
    .size = VK_WHOLE_SIZE
};

vkCmdPipelineBarrier(transferCmdBuffer,
    VK_PIPELINE_STAGE_TRANSFER_BIT,
    VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
    0,
    0, nullptr,
    1, &barrierA,
    0, nullptr);

队列B中的代码

VkBufferBarrier barrierB = {
    .sType = VK_STRUCTURE_TYPE_BUFFER_BARRIER,
    .srcAccessMask = 0,
    .dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
    .offset = 0,
    .size = VK_WHOLE_SIZE
};

vkCmdPipelineBarrier(graphicsCmdBuffer,
    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
    VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
    0,
    0, nullptr,
    1, &barrierB,
    0, nullptr);

方案2:仅在队列B中设置单个屏障

VkBufferBarrier barrierB = {
    .sType = VK_STRUCTURE_TYPE_BUFFER_BARRIER,
    .srcAccessMask = VK_PIPELINE_STAGE_TRANSFER_BIT,
    .dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
    .offset = 0,
    .size = VK_WHOLE_SIZE
};

vkCmdPipelineBarrier(graphicsCmdBuffer,
    VK_PIPELINE_STAGE_TRANSFER_BIT,
    VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
    0,
    0, nullptr,
    1, &barrierB,
    0, nullptr);

内容的提问来源于stack exchange,提问作者tuket

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 00:45:55