如何在计算着色器写入和顶点属性读取之间创建屏障
How to create a barrier between compute shader write and vertex attribute read
我有一个粒子系统,首先我 运行 计算着色器并更新所有属性,然后我将这些属性用作顶点着色器中的 vao 输入。
现在我需要在这些阶段之间设置一个屏障,但我不确定该怎么做,无论我尝试什么都会出错。
目前我有这样的管道障碍:
VkMemoryBarrier memoryBarrier;
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.pNext = nullptr;
memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
memoryBarrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_B
然后我使用此依赖项创建渲染通道:
VkSubpassDependency computeDependency;
computeDependency.srcSubpass = 0;
computeDependency.dstSubpass = 0;
computeDependency.srcStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
computeDependency.dstStageMask = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
computeDependency.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
computeDependency.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
computeDependency.dependencyFlags = 0;
但这不起作用,因为我收到此错误:验证层:依赖项 1 指定源阶段掩码,其中包含不在源子通道 0 使用的 GRAPHICS 管道中的阶段。Vulkan 规范指出:对于任何pDependencies 的元素,如果 srcSubpass 不是 VK_SUBPASS_EXTERNAL,则该依赖项的 srcStageMask 成员中包含的所有阶段标志必须是由源子通道的 pipelineBindPoint 成员标识的管道支持的管道阶段(https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-pDependencies-00837 )
您不能在子通道中间执行计算着色器。 The render pass scope of vkCmdDispatch
is "outside",这也是为什么subpass之间的依赖只能指定图形操作支持的阶段。因此,渲染过程中计算着色器和消费者之间的任何依赖都是外部依赖:包含渲染过程的子通道与外界之间的依赖。
所以你的srcSubpass
应该是VK_SUBPASS_EXTERNAL
。
我有一个粒子系统,首先我 运行 计算着色器并更新所有属性,然后我将这些属性用作顶点着色器中的 vao 输入。
现在我需要在这些阶段之间设置一个屏障,但我不确定该怎么做,无论我尝试什么都会出错。
目前我有这样的管道障碍:
VkMemoryBarrier memoryBarrier;
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.pNext = nullptr;
memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
memoryBarrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_B
然后我使用此依赖项创建渲染通道:
VkSubpassDependency computeDependency;
computeDependency.srcSubpass = 0;
computeDependency.dstSubpass = 0;
computeDependency.srcStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
computeDependency.dstStageMask = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
computeDependency.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
computeDependency.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
computeDependency.dependencyFlags = 0;
但这不起作用,因为我收到此错误:验证层:依赖项 1 指定源阶段掩码,其中包含不在源子通道 0 使用的 GRAPHICS 管道中的阶段。Vulkan 规范指出:对于任何pDependencies 的元素,如果 srcSubpass 不是 VK_SUBPASS_EXTERNAL,则该依赖项的 srcStageMask 成员中包含的所有阶段标志必须是由源子通道的 pipelineBindPoint 成员标识的管道支持的管道阶段(https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkRenderPassCreateInfo-pDependencies-00837 )
您不能在子通道中间执行计算着色器。 The render pass scope of vkCmdDispatch
is "outside",这也是为什么subpass之间的依赖只能指定图形操作支持的阶段。因此,渲染过程中计算着色器和消费者之间的任何依赖都是外部依赖:包含渲染过程的子通道与外界之间的依赖。
所以你的srcSubpass
应该是VK_SUBPASS_EXTERNAL
。