片段着色器托管依赖项
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
。您是否积极使用设备组?
我正在片段着色器的存储缓冲区中写入数据,然后尝试直接在主机上读取数据。如果我做同样的事情但使用计算着色器,屏障就会起作用,我可以读取主机上的数据。但我可以让它与渲染通道一起工作。
// 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)
vkCmdPipelineBarrier
称为 Subpass Self-dependency,因此无法处理 subpass 外部的任何内容,包括 Host 伪管道。您需要使用 VkSubpassDependency
预先声明 vkCmdPipelineBarrier
的这种使用,其中 .srcSubpass == .dstSubpass
。并且在这种依赖中,只允许图形管道阶段。
您的 VK_SUBPASS_EXTERNAL
依赖项似乎已经完成了所有需要的工作。所以你只需要删除无效使用的vkCmdPipelineBarrier
。我假设您知道您仍然需要跟进 Fence。
我不确定你为什么 VK_DEPENDENCY_DEVICE_GROUP_BIT
。您是否积极使用设备组?