我正面临一个全面的问题。
假设我在TRANSFER_LAYOUT布局中有一个图像。这样,内存已经可用(不可见)。
假设我更新了统一缓冲区(通过vkCmdCopyBuffer)。
现在假设我有一个renderPass(带有一个“空frameBuffer”,因此没有colorAttachment使事情更简单),它使用SHADER_READ_OPTIMAL布局中的先前图像和我们刚刚更新的统一缓冲区。图像和缓冲区都在片段着色器中使用。
执行以下操作是否正确?
将图像转换为SHADER_READ_LAYOUT
srcAccess = 0; // layers will say error : it must be TRANSFER_READ
dstAccess = 0; // The visibility will be made in the renderpass dependency (hower layers tells that it should be SHADER_READ I think)
srcPipe = TOP_OF_PIPE;
dstPipe = BOTTOM_OF_PIPE;
根据我的理解,在这里使用不同于0的访问权限毫无意义,因为TOP_OF_PIPE
和BOTTOM_OF_PIPE
无法访问内存。
来自VK_EXTERNAL_SUBPASS的renderpass依赖项:
srcAccess = TRANSFER_WRITE; // for the uniformBuffer
dstAccess = SHADER_READ; // for the uniform and the image
srcPipeline = TRANSFER; // For the uniformBuffer
dstPipeline = FRAGMENT_SHADER; // They are used here
通过这种方式,我们确信统一缓冲区不会出现任何问题:由于renderPass,数据都可用且可见。内存也应该对图像可见(也要归功于依赖性)。但是,转换是在这里写到“不在之前”的最后阶段。由于我在FRAGMENT_STAGE中使用图像,这是一个错误吗?或者“renderPass依赖的结尾”表现得像一个底层阶段?
此代码适用于NVIDIA和AMD,但我不确定它是否正确
答案 0 :(得分:2)
要完全理解同步,必须简单地阅读规范;特别是Execution and Memory Dependencies理论章节。让我们根据规范中的内容分析您的情况。
您有(仅)三个同步命令: S 1 (图像过渡到TRANSFER_LAYOUT
和可用性操作), S 2 (图片过渡到SHADER_READ_LAYOUT
)和 S 3 (渲染传递VK_EXTERNAL
依赖关系)。
您的命令缓冲区是一个有序列表,如:[ Cmds 0 , S 1 , Cmds 1 , S 2 , Cmds 2 , S 3 , Cmds 3 ]。
对于 S 1 ,我们假设你正确地完成了依赖关系的第一部分(即src
部分)。您只是说您从中获取了图像。
您还说过不让可见,所以让我们假设dstAccess
是0
而dstStage
可能是BOTTOM_OF_PIPE
。
S 2 没有执行依赖,并且它没有内存依赖。只有布局过渡。规范中有一个layout transition synchronization异常,表示布局转换是在提交顺序中完整执行的(即隐式执行依赖是自动添加的)。我个人不愿意依赖它(我不相信司机在第一次尝试时正确实现它)。但我们假设它是有效的,并假设图像将被正确转换并在 S (而不是可见) > 1 子> 强>
S 3 是非附件资源的外部子通道依赖关系,但the spec reassures us与vkCmdPipelineBarrier
的{{1}}没有区别{ {1}}。
S 3 中依赖关系的第二部分(即VkMemoryBarrier
)似乎正确满足您的需求。
<小时/> TL; DR,到目前为止一直很好。
S 3 中依赖关系的第一部分(即dst
)确实会有问题。
非附件资源没有自动布局转换,因此我们不能依赖上面的拐杖。
命令集 A 3 是renderpass之前的所有命令。
同步范围 3S 只是那些位于dst
pipline阶段或任何逻辑上较早阶段的操作 (即srcStage
到指定的TOP_OF_PIPE
)。
执行依赖是在 A 3 '和 B 3 '。上面我们同意 B 3 '一半的依赖是正确的。 A 3 '一半是 A 3 和 A 3S 强>
S 2 中的布局转换是在STAGE_TRANSFER
和srcPipe = TOP_OF_PIPE
之间进行的,所以基本上可以在任何地方。它可以在dstPipe = BOTTOM_OF_PIPE
中进行(确切地说,在执行 S 2 之后记录的BOTTOM_OF_PIPE
命令之前发生)。
因此布局转换是 A 3 的一部分,但不能保证它是 A 3S 的一部分;所以不要保证过渡是交叉点 A 3 '的一部分。
这意味着无法保证在BOTTOM_OF_PIPE
的第一个子通道中的图像读取之前,布局过渡到SHADER_READ_LAYOUT
。
没有正确的内存依赖,因为它也是根据 A 3 '定义的。
编辑:不知怎的错过了,这可能是问题:
或者“renderPass依赖关系的结尾”表现得像一个底层阶段?
渲染过程的开始和结束不像任何东西。它只会影响提交订单。存在STAGE_FRAGMENT_SHADER
依赖性时仅应用(当然还有任何其他先前的显式同步命令)。如果没有明确的VK_EXTERNAL
依赖关系,那么VkSubpassDependency的有效用法部分的规范中也会有所描述(基本上所有可用的内存在VK_EXTERNAL
之前生成可见整个第一个子通道以供附件使用。)