Synchronization 片段着色器与主机依赖关系

Synchronization 片段着色器与主机依赖关系,synchronization,vulkan,memory-barriers,Synchronization,Vulkan,Memory Barriers,我正在片段着色器的存储缓冲区中写入数据,并尝试在之后直接读取主机上的数据。如果我也这么做,但是使用了计算着色器,那么屏障就会工作,我可以读取主机上的数据。但我可以让它与渲染过程一起工作 // fragment shader layout (set = 0, binding = 1) writeonly buffer Voxels { uvec4 values[10000]; } voxels; void main() { uint cur = atomicAdd(voxels.cou

我正在片段着色器的存储缓冲区中写入数据,并尝试在之后直接读取主机上的数据。如果我也这么做,但是使用了计算着色器,那么屏障就会工作,我可以读取主机上的数据。但我可以让它与渲染过程一起工作

// fragment shader
layout (set = 0, binding = 1) writeonly buffer Voxels {
  uvec4 values[10000];
} voxels;
void main() {
    uint cur = atomicAdd(voxels.count, 1);
    voxels.values[cur] = uvec4(1,2,3,4);
}
我正在尝试在渲染过程中添加内存屏障:

  VkMemoryBarrier memoryBarrier = {
    .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
    .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
    .dstAccessMask = VK_ACCESS_HOST_READ_BIT
  };
  vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
渲染过程(子过程依赖项)

但是当记录内存屏障时,我从验证层得到了一个错误。它说我需要次级自我依赖。但是如果我在子类0和子类0之间有依赖关系,我就不能有任何主机掩码

错误消息:

在VkRenderPass的子进程0期间无法设置屏障 0x61bb1e000000007b[]未指定自相关性。瓦肯人 等级库状态:如果在渲染过程中调用vkCmdPipelineBarrier 实例,必须使用至少一个渲染过程创建渲染过程 VkRenderPassCreateInfo::pDependencies中的VkSubpassDependency实例 表示从当前子类到自身的依赖关系,以及 其中srcStageMask包含中位值的子集 VkSubpassDependency::srcStageMask,dstStageMask包含 VkSubpassDependency::dstStageMask,dependencyFlags中的位值 等于VkSubpassDependency::dependencyFlags,srcAccessMask成员 pMemoryBarriers和pImageMemoryBarriers的每个元素的 VkSubpassDependency::srcAccessMask中位值的子集,以及 pMemoryBarriers和的每个元素的dstAccessMask成员 PIManageMemoryBarriers包含中位值的子集 VkSubpassDependency::dstAccessMask ()


子类内部的
vkCmdPipelineBarrier
称为子类自依赖,因此无法处理子类外部的任何内容,包括主机伪管道。您需要使用
VkSubpassDependency
预先声明使用
vkCmdPipelineBarrier
,其中
.srcSubpass==.dstSubpass
。在这种依赖关系中,只允许图形管道阶段

您的
VK\u SUBPASS\u EXTERNAL
依赖项似乎已经完成了所有需要的工作。因此,您只需要删除
vkCmdPipelineBarrier
,这是无效的用法。我想你知道你还需要一个篱笆


我不知道您为什么有
VK\u依赖项\u设备\u组\u位
。您是否积极使用设备组?

VK\u依赖项\u设备\u组\u位只是我在调试时添加的。谢谢,现在可以用了
  VkSubpassDependency subpassDependency = {
      .srcSubpass = 0,
      .dstSubpass = VK_SUBPASS_EXTERNAL,
      .srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
      .dstStageMask = VK_PIPELINE_STAGE_HOST_BIT,
      .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
      .dstAccessMask = VK_ACCESS_HOST_READ_BIT,
      .dependencyFlags = VK_DEPENDENCY_DEVICE_GROUP_BIT 
  };