片段着色器托管依赖项

Fragment shader to host dependencies

我正在片段着色器的存储缓冲区中写入数据,然后尝试直接在主机上读取数据。如果我做同样的事情但使用计算着色器,屏障就会起作用,我可以读取主机上的数据。但我可以让它与渲染通道一起工作。

// 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);

渲染通道(子通道依赖)

  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 
  };

但是我在记录内存屏障时从验证层收到错误。它说我需要 subpass 独立。但是如果我在 subpass 0 和 subpass 0 之间有依赖关系,我不能有任何主机掩码?

错误信息:

Barriers cannot be set during subpass 0 of VkRenderPass 0x61bb1e000000007b[] with no self-dependency specified. The Vulkan spec states: If vkCmdPipelineBarrier is called within a render pass instance, the render pass must have been created with at least one VkSubpassDependency instance in VkRenderPassCreateInfo::pDependencies that expresses a dependency from the current subpass to itself, and for which srcStageMask contains a subset of the bit values in VkSubpassDependency::srcStageMask, dstStageMask contains a subset of the bit values in VkSubpassDependency::dstStageMask, dependencyFlags is equal to VkSubpassDependency::dependencyFlags, srcAccessMask member of each element of pMemoryBarriers and pImageMemoryBarriers contains a subset of the bit values in VkSubpassDependency::srcAccessMask, and dstAccessMask member of each element of pMemoryBarriers and pImageMemoryBarriers contains a subset of the bit values in VkSubpassDependency::dstAccessMask (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkCmdPipelineBarrier-pDependencies-02285)

Subpass 内部的

vkCmdPipelineBarrier 称为 Subpass Self-dependency,因此无法处理 subpass 外部的任何内容,包括 Host 伪管道。您需要使用 VkSubpassDependency 预先声明 vkCmdPipelineBarrier 的这种使用,其中 .srcSubpass == .dstSubpass。并且在这种依赖中,只允许图形管道阶段。

您的 VK_SUBPASS_EXTERNAL 依赖项似乎已经完成了所有需要的工作。所以你只需要删除无效使用的vkCmdPipelineBarrier。我假设您知道您仍然需要跟进 Fence。

我不确定你为什么 VK_DEPENDENCY_DEVICE_GROUP_BIT。您是否积极使用设备组?