简体   繁体   English

RenderPass依赖性和(过渡)内存屏障

[英]RenderPass Dependency and (transition) memory barrier

I am facing a comprehensive issue. 我面临一个全面的问题。

Let's say I have an image in a TRANSFER_LAYOUT layout. 假设我有一个图像在TRANSFER_LAYOUT布局中。 Going that way, the memory is already made available (not visible). 这样一来,内存已经可用(不可见)。

Let's say I update a uniform buffer (via vkCmdCopyBuffer). 假设我更新了统一缓冲区(通过vkCmdCopyBuffer)。

Now let's say I have a renderPass (with an "empty frameBuffer", so there is no colorAttachment to make thing simpler) that use the prior image in SHADER_READ_OPTIMAL layout and the uniform buffer we just update. 现在,假设我有一个使用SHADER_READ_OPTIMAL布局中的先前图像和我们刚刚更新的统一缓冲区的renderPass(带有“ empty frameBuffer”,因此没有colorAttachment使事情更简单)。 The image and the buffer are both used inside the fragment shader. 图像和缓冲区都在片段着色器内部使用。

Is it correct to do the following? 执行以下操作是否正确?

Transition the image to SHADER_READ_LAYOUT 将图片过渡到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;

It is, in my understanding, meaningless to use different access than 0 here because TOP_OF_PIPE and BOTTOM_OF_PIPE does not access memory. 以我的理解,此处使用不同于0的访问是没有意义的,因为TOP_OF_PIPEBOTTOM_OF_PIPE不会访问内存。

In the renderpass dependency from VK_EXTERNAL_SUBPASS : 在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

Going that way, we are sure that the uniform buffer will not have any problems : The data are both made available and visible thanks to the renderPass. 这样,我们可以确保统一缓冲区不会有任何问题:多亏了renderPass,数据既可用又可见。 The memory should also be made visible for the image (also thanks to the dependency). 内存也应该对图像可见(也要感谢相关性)。 However, the transition is write here to happened "not before" the bottom stage. 但是,这里的过渡是在底层阶段“之前”发生的。 Since I am using the image in FRAGMENT_STAGE, is it a mistake? 由于我在FRAGMENT_STAGE中使用图片,这是错误的吗? Or is the "end of the renderPass dependency" behave like a bottom stage? 还是“ renderPass依赖项的结束”表现得像一个底层阶段?

This code works on NVIDIA, and on AMD, but I am not sure it is really correct 该代码可在NVIDIA和AMD上使用,但我不确定它是否正确

To understand synchronization perfectly, one must simply read the specification; 为了完全理解同步,必须简单地阅读规范。 especially the Execution and Memory Dependencies theory chapter. 尤其是“ 执行和内存依赖理论”一章。 Lets analyze your situation in terms of what is written in the specification. 让我们根据规范中的内容来分析您的情况。

You have (only) three synchronization commands: S 1 (image transition to TRANSFER_LAYOUT and availability operation), S 2 (image transition to SHADER_READ_LAYOUT ), and S 3 (render pass VK_EXTERNAL dependency). 您(仅有)三个同步命令: S 1 (将图像过渡到TRANSFER_LAYOUT和可用性操作), S 2 (将图像过渡到SHADER_READ_LAYOUT )和S 3 (渲染过程VK_EXTERNAL依赖性)。

Your command buffer is an ordered list like: [ Cmds 0 , S 1 , Cmds 1 , S 2 , Cmds 2 , S 3 , Cmds 3 ]. 您的命令缓冲区是一个有序列表,例如:[ Cmds 0S 1Cmds 1S 2Cmds 2S 3Cmds 3 ]。

For S 1 let's assume you did the first part of a dependency (ie src part) correctly. 对于S 1,我们假设您正确地执行了依赖关系的第一部分(即src部分)。 You only said you made the image available from . 您只是说过您从提供了图片。

You also said you did not made it visible to , so let's assume dstAccess was 0 and dstStage was probably BOTTOM_OF_PIPE . 你也说你 去到可见的 ,所以我们假设dstAccess0dstStage大概BOTTOM_OF_PIPE

S 2 has no execution dependency and it has not memory dependency . S 2没有执行依赖性 ,也没有内存依赖性 Only layout transition. 仅布局转换。 There is an layout transition synchronization exception in the spec saying that layout transitions are performed in full in submission order (ie implicit execution dependency is automagically added). 规范中有一个布局转换同步异常,说明布局转换按提交顺序完全执行 (即, 隐式执行依赖关系会自动添加)。 I personally would not be comfortable relying on it (and I would not trust drivers to implement it correctly on the first try). 我个人不愿意依靠它(我也不相信驱动程序会在第一次尝试时正确地实现它)。 But lets assume it is valid, and assume the image will be correctly transitioned and made available from (and not visible to ) at some point after the S 1 . 但是,让我们假设它是有效的,并假设图像将在S 1之后的某个时刻正确过渡并 (不可见可用

The S 3 is an external subpass dependency on non-attachment resource, but the spec reassures us it is no different than vkCmdPipelineBarrier with a VkMemoryBarrier . S 3是对非附件资源外部依赖subpass,但该规范安慰我们这是毫不不同于vkCmdPipelineBarrierVkMemoryBarrier

The second part of the dependency (ie dst ) in S 3 seems correct for your needs. S 3中依赖性的第二部分(即dst )似乎符合您的需求。


TL;DR, so far so good. TL; DR,到目前为止一切顺利。


The first part of the dependency (ie dst ) in S 3 would indeed be the problematic one. S 3中依赖性的第一部分(即dst )确实是有问题的。

There is no automatic layout transitions for non-attachment resources, so we cannot rely on that crutch as above. 非附件资源没有自动的布局转换,因此我们不能像上面那样依赖拐杖。

Set of commands A 3 are all the commands before the renderpass. 命令集A 3是渲染通道之前的所有命令。

Synchronization scope A 3S are only those kinds of operations that are on the srcStage pipline stage or any logically earlier stage (ie TOP_OF_PIPE up to the specified STAGE_TRANSFER ). 同步作用域3S只是srcStage管线阶段或任何逻辑上较早阶段(即, TOP_OF_PIPE指定STAGE_TRANSFER )上的那些类型的操作

The execution dependency is made between A 3 ' and B 3 ' . 执行依赖性A 3 'B 3 '之间进行 Above we agreed the B 3 ' half of the dependency is correct. 上面我们同意相依的B 3 '一半是正确的。 The A 3 ' half is intersection of A 3 and A 3S . A 3 '的一半是A 3A 3S的交集。

The layout transition in S 2 is made between srcPipe = TOP_OF_PIPE and dstPipe = BOTTOM_OF_PIPE , so basically can be anywhere. S 2中的布局转换是在srcPipe = TOP_OF_PIPEdstPipe = BOTTOM_OF_PIPE ,因此基本上可以在任何地方。 It can be as late as in BOTTOM_OF_PIPE (to be precise, happens-before BOTTOM_OF_PIPE of commands recorded after S 2 is executed). 它可以迟到BOTTOM_OF_PIPE (准确地说,发生在执行S 2之后记录的命令的BOTTOM_OF_PIPE之前)。 So the layout transition is part of A 3 , but there is no guarantee it is part of A 3S ; 因此,布局过渡3一部分,但也不能保证它是一个3S的一部分; so there would not be guarantee the transition is part of the intersection A 3 ' . 因此, 不能保证过渡是交点A 3 '的一部分

That means there is no guarantee the layout transition to SHADER_READ_LAYOUT happens-before the image reading in the first subpass in STAGE_FRAGMENT_SHADER . 这意味着不能保证在SHADER_READ_LAYOUT的第一个子STAGE_FRAGMENT_SHADER读取图像之前,会发生布局过渡到SHADER_READ_LAYOUT情况。

There is no correct memory dependency either because that is defined in terms of A 3 ' too. 也没有正确的内存依赖关系 ,因为它也根据A 3 '定义。

EDIT: Somehow missed this, which is probably the problem: 编辑:不知何故错过了,这可能是问题:

Or is the "end of the renderPass dependency" behave like a bottom stage? 还是“ renderPass依赖项的结束”表现得像一个底层阶段?

Beginning and end of a render pass does not behave like anything. 渲染过程的开始和结束并不像任何行为。 It only affects submission order . 它仅影响提交顺序 In the presence of VK_EXTERNAL dependency only that applies (and of course any other previous explicit synchronization commands). 在存在VK_EXTERNAL依赖项的情况下,仅适用VK_EXTERNAL (当然还有其他任何先前的显式同步命令)。 What happens without explicit VK_EXTERNAL dependency is described in the spec too bellow Valid Usage sections of VkSubpassDependency (basically all memory that is available before TOP_OF_PIPE is made visible to the whole first subpass for attachment use). 会发生什么事没有明确VK_EXTERNAL依赖在规范中描述过波纹管的有效使用部分VkSubpassDependency (基本上所有的内存可用之前TOP_OF_PIPE可见为附件一起使用的整个第一subpass)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM