使用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
相关产品推荐
相关产品推荐

