可以在同一个绘图调用中读取输入附件并写入同一附件吗?

pai*_*ler 5 graphics vulkan

我想知道附件是否同时用作输入附件和颜色/DS 附件,从输入附件读取绘图调用然后写入相同的颜色/DS 附件,是否允许?如果下一个绘制调用也做同样的事情,从规范中我看到我需要一个 vkCmdPipelineBarrier 来使下一个绘制调用获取正确的结果,但不确定相同的绘制调用情况。

另一个问题是我可以在第一个子通道中使用输入附件吗?就像我附加从 pre-z pass 生成的深度纹理作为深度附件和输入附件一样?

Nic*_*las 6

可以通过着色器中的颜色/输入附件对同一图像执行读取/修改/写入 (RMW),只要:

  1. 您确保只有一个片段着色器将为颜色附件中的特定输出值执行 RMW。这基本上可以归结为“不透支”。

  2. 如果您需要透支(即:多个 FS 对同一输入/输出执行重复的 RMW 操作),则在子通道内的每组透支操作之间,您必须有一个管道屏障。因此,您必须将渲染命令分解为小块。请注意,为了使屏障发挥作用,您必须具有子通道自依赖性作为该子通道依赖关系图的一部分,并且屏障需要调用它。此外,您的独立性应该是针对每个区域的,因为您只关心屏幕上各个位置之间的依赖性。毕竟,您无法随机访问输入附件。

您可以使用任何附件作为任何子通道上的输入附件,只要这样做有意义即可。如果您的 loadOp 表示您不想加载数据,那么显然从具有未定义值的图像中读取数据是没有意义的。

  • @solidpixel:具体来说:“用于 SubpassData 的 (u,v) 坐标必须是常量向量 (0,0) 的 <id>”[来自 Vulkan](https://www.khronos.org/registry/ vulkan/specs/1.1-khr-extensions/html/chap36.html#spirvenv) 和“当 Image Dim 操作数为 SubpassData 时,坐标相对于当前片段位置”,来自 [OpImageRead 中的 SPIR-V](https:// /www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#OpImageRead)。因此,在 Vulkan 中,*除了*当前片段的位置之外,无法从输入附件读取。 (3认同)
  • @solidpixel:这是 OpenGL 中的要求。Vulkan 没有这个要求,因为*根据定义*,不可能从其他片段的输入附件中读取。你根本做不到。这就是为什么输入附件与制服不同类型的原因(部分)。 (2认同)

Jes*_*all 2

使用附件作为输入附件和颜色或深度/模板附件被称为反馈循环,如果您在其之间没有管道障碍的情况下读取和写入它的相同部分,那么本质上您会得到未定义的结果。由于绘制调用中不能存在管道屏障,因此您运气不好。

如果所有访问都是读取(例如启用深度测试但禁用深度写入),或者如果读取和写入访问不相交的组件(使用颜色写入掩码),则可以以明确定义的方式使用反馈循环。

对于第二个问题,是的,输入附件不必提前在同一渲染通道中写入。尽管在您的示例中,最好在第一个子通道中执行 z 预通道,然后在第二个子通道中将其用作输入附件和只读深度测试。在平铺架构上,这可能会节省带宽,因为深度缓冲区永远不必写入内存。