我一直在遵循不同的教程,但我不明白为什么我需要每个交换链图像资源而不是飞行中的每个帧资源。
本教程: https://vulkan-tutorial.com/Uniform_buffers
每个交换链图像都有一个统一的缓冲区。如果不同时同时播放不同的图像,我为什么需要它?如果前一帧完成,我可以不开始重写吗?
关于深度缓冲区的lunarg教程也说:
即使交换链有多个图像,您也只需要一个即可渲染每一帧。这是因为在使用交换链中的每个图像时,您可以重复使用相同的深度缓冲区。
这什么也没解释,基本上说可以,因为可以。那么为什么我可以重用深度缓冲区而不重用其他资源呢?
答案 0 :(得分:4)
在简单的Hello Cube应用程序中,这是为了最大程度地减少同步。
比方说,您的制服在每一帧都在变化。这意味着主循环类似于:
如果步骤#2没有自己的制服,则需要编写一个制服来读取前一帧。这意味着它必须与栅栏同步。那将意味着先前的帧不再被视为“运行中”。
答案 1 :(得分:2)
这完全取决于您使用资源的方式以及要实现的性能。
如果在每一帧之后您都愿意等待渲染完成而对最终性能仍然满意,则每个资源只能使用一个副本。等待是最简单的同步,您可以确保不再使用资源,因此可以将它们重新用于下一帧。但是,如果您想有效地利用CPU和GPU的功能,又不想在每一帧之后都等待,那么您需要查看每种资源的使用方式。
深度缓冲区通常仅临时使用。如果您不执行任何后处理,则如果渲染过程设置仅在内部使用深度数据(您未为STORE
指定storeOp
),那么您只能使用一个深度缓冲区(深度图像)每时每刻。这是因为完成渲染后,不再使用深度数据,可以安全地丢弃它。这适用于不需要在帧之间持久的所有其他资源。
但是,如果每个帧需要使用不同的数据,或者在下一帧中使用生成的数据,则通常需要给定资源的另一个副本。更新数据需要同步-为了避免在这种情况下等待,您需要拥有一个资源副本。因此,在使用统一缓冲区的情况下,您可以在给定缓冲区中更新数据并在给定帧中使用它。在帧结束之前,您无法修改其内容-因此,要在动画仍在GPU上处理前一帧的同时准备动画的另一帧,则需要使用另一个副本。
类似地,如果下一帧需要生成的数据(例如,用于屏幕空间反射的帧缓冲区)。重用同一资源将导致其内容被覆盖。这就是为什么您需要另一个副本。
您可以在此处找到更多信息:https://software.intel.com/en-us/articles/api-without-secrets-the-practical-approach-to-vulkan-part-1