从输入附件中读取并在同一个 drawcall 中写入同一个附件是否可以?
Is it OK to read from an input attachment and write to the same attachment in the same drawcall?
我想知道一个附件是否同时用作输入附件和 color/ds 附件,从输入附件读取绘图调用然后写入同一个 color/ds 附件,是否允许?
如果下一个 drawcall 也在做同样的事情,从规范中我看到我需要一个 vkCmdPipelineBarrier 来使下一个 drawcall 获取正确的结果,但不确定相同的 drawcall 情况。
另一个问题是我可以在第一个子通道中使用输入附件吗?就像我附加从 pre-z 通道生成的深度纹理作为深度附件和输入附件?
将附件同时用作输入附件和颜色或 depth/stencil 附件被称为 feedback loop,如果您同时读取和写入附件的相同部分而不使用,则基本上会得到未定义的结果之间的管道屏障。由于在绘制调用中不能有管道障碍,所以你运气不好。
如果所有访问都是读取(例如,启用深度测试但禁用深度写入),您可以以明确定义的方式使用反馈循环,或者如果读取和写入用于颜色附件访问不相交的组件(使用颜色写入掩码)。
对于你的第二个问题,是的,输入附件不必在同一个渲染过程中提前编写。尽管在您的示例中,最好在第一个子通道中进行 z 预通道,然后在第二个子通道中将其用作输入附件和只读深度测试。在平铺架构上,这可能会节省带宽,因为永远不必将深度缓冲区写入内存。
可以通过着色器中的 color/input 附件对同一图像执行 read/modify/write (RMW),只要:
您确保只有一个片段着色器将对颜色附件中的特定输出值执行 RMW。这基本上可以归结为 "no overdraw".
如果你需要透支(即:多个 FS 对同一个 input/output 进行重复的 RMW 操作),那么在子通道内的每组透支操作之间,你 必须有管道屏障。所以你必须把你的渲染命令分解成小块。请注意,要使屏障起作用,您必须将子通道自依赖作为此子通道依赖关系图的一部分,并且屏障需要调用它。此外,您的依赖性应该是按区域的,因为您只关心屏幕上各个位置之间的依赖性。毕竟,您不能随机访问输入附件。
您可以在任何子通道上使用任何附件作为输入附件,只要这样做有意义。如果您的 loadOp 表示您不想加载数据,那么显然从具有未定义值的图像中读取是没有意义的。
我想知道一个附件是否同时用作输入附件和 color/ds 附件,从输入附件读取绘图调用然后写入同一个 color/ds 附件,是否允许? 如果下一个 drawcall 也在做同样的事情,从规范中我看到我需要一个 vkCmdPipelineBarrier 来使下一个 drawcall 获取正确的结果,但不确定相同的 drawcall 情况。
另一个问题是我可以在第一个子通道中使用输入附件吗?就像我附加从 pre-z 通道生成的深度纹理作为深度附件和输入附件?
将附件同时用作输入附件和颜色或 depth/stencil 附件被称为 feedback loop,如果您同时读取和写入附件的相同部分而不使用,则基本上会得到未定义的结果之间的管道屏障。由于在绘制调用中不能有管道障碍,所以你运气不好。
如果所有访问都是读取(例如,启用深度测试但禁用深度写入),您可以以明确定义的方式使用反馈循环,或者如果读取和写入用于颜色附件访问不相交的组件(使用颜色写入掩码)。
对于你的第二个问题,是的,输入附件不必在同一个渲染过程中提前编写。尽管在您的示例中,最好在第一个子通道中进行 z 预通道,然后在第二个子通道中将其用作输入附件和只读深度测试。在平铺架构上,这可能会节省带宽,因为永远不必将深度缓冲区写入内存。
可以通过着色器中的 color/input 附件对同一图像执行 read/modify/write (RMW),只要:
您确保只有一个片段着色器将对颜色附件中的特定输出值执行 RMW。这基本上可以归结为 "no overdraw".
如果你需要透支(即:多个 FS 对同一个 input/output 进行重复的 RMW 操作),那么在子通道内的每组透支操作之间,你 必须有管道屏障。所以你必须把你的渲染命令分解成小块。请注意,要使屏障起作用,您必须将子通道自依赖作为此子通道依赖关系图的一部分,并且屏障需要调用它。此外,您的依赖性应该是按区域的,因为您只关心屏幕上各个位置之间的依赖性。毕竟,您不能随机访问输入附件。
您可以在任何子通道上使用任何附件作为输入附件,只要这样做有意义。如果您的 loadOp 表示您不想加载数据,那么显然从具有未定义值的图像中读取是没有意义的。