为什么我需要每个交换链图像的资源
Why do I need resources per swapchain image
我一直在学习不同的教程,但我不明白为什么我需要每个交换链图像的资源而不是飞行中的每个帧。
本教程:
https://vulkan-tutorial.com/Uniform_buffers
每个交换链图像都有一个统一的缓冲区。如果不同的图像不同时飞行,我为什么需要它?上一帧写完可以不开始重写吗?
关于深度缓冲区的 lungarg 教程也说:
And you need only one for rendering each frame, even if the swapchain has more than one image. This is because you can reuse the same depth buffer while using each image in the swapchain.
这并没有解释任何东西,它基本上是说你可以,因为你可以。那么为什么我可以重用深度缓冲区而不是其他资源呢?
这完全取决于您使用资源的方式和您想要达到的性能。
如果在每一帧之后,您愿意等待渲染完成并且您对最终的表现仍然满意,那么您可以只使用每个资源的一个副本。等待是最简单的同步,你确定资源不再被使用,所以你可以为下一帧重用它们。但是如果您想有效地利用 CPU 和 GPU 的能力,并且您不想在每一帧之后等待,那么您需要查看每个资源的使用情况。
深度缓冲区通常只是临时使用。如果您不执行任何后处理,如果您的渲染通道设置仅在内部使用深度数据(您没有为 storeOp
指定 STORE
),那么您只能使用一个深度缓冲区(深度图像)每时每刻。这是因为渲染完成后,不再使用深度数据,可以安全地将其丢弃。这适用于不需要在帧之间保留的所有其他资源。
但是如果每一帧需要使用不同的数据,或者如果生成的数据用于下一帧,那么您通常需要给定资源的另一个副本。更新数据需要同步 - 避免在这种情况下等待您需要有一个资源副本。因此,在统一缓冲区的情况下,您可以更新给定缓冲区中的数据并在给定帧中使用它。在帧完成之前您无法修改其内容 - 因此要在前一帧仍在 GPU 上处理时准备另一帧动画,您需要使用另一个副本。
同样,如果下一帧需要生成的数据(例如用于屏幕 space 反射的帧缓冲区)。重复使用相同的资源会导致其内容被覆盖。这就是为什么你需要另一个副本。
您可以在此处找到更多信息:https://software.intel.com/en-us/articles/api-without-secrets-the-practical-approach-to-vulkan-part-1
在简单的 Hello Cube 应用程序的情况下,最大限度地减少同步。
假设你的制服每一帧都在变化。这意味着主循环类似于:
- 轮询(或模拟)
- 更新(例如你的制服)
- 画画
- 重复
如果步骤#2没有自己的uniform,那么就需要写一个uniform previous frame is reading。这意味着它必须与 Fence 同步。这意味着不再考虑前一帧 "in-flight".
我一直在学习不同的教程,但我不明白为什么我需要每个交换链图像的资源而不是飞行中的每个帧。
本教程: https://vulkan-tutorial.com/Uniform_buffers
每个交换链图像都有一个统一的缓冲区。如果不同的图像不同时飞行,我为什么需要它?上一帧写完可以不开始重写吗?
关于深度缓冲区的 lungarg 教程也说:
And you need only one for rendering each frame, even if the swapchain has more than one image. This is because you can reuse the same depth buffer while using each image in the swapchain.
这并没有解释任何东西,它基本上是说你可以,因为你可以。那么为什么我可以重用深度缓冲区而不是其他资源呢?
这完全取决于您使用资源的方式和您想要达到的性能。
如果在每一帧之后,您愿意等待渲染完成并且您对最终的表现仍然满意,那么您可以只使用每个资源的一个副本。等待是最简单的同步,你确定资源不再被使用,所以你可以为下一帧重用它们。但是如果您想有效地利用 CPU 和 GPU 的能力,并且您不想在每一帧之后等待,那么您需要查看每个资源的使用情况。
深度缓冲区通常只是临时使用。如果您不执行任何后处理,如果您的渲染通道设置仅在内部使用深度数据(您没有为 storeOp
指定 STORE
),那么您只能使用一个深度缓冲区(深度图像)每时每刻。这是因为渲染完成后,不再使用深度数据,可以安全地将其丢弃。这适用于不需要在帧之间保留的所有其他资源。
但是如果每一帧需要使用不同的数据,或者如果生成的数据用于下一帧,那么您通常需要给定资源的另一个副本。更新数据需要同步 - 避免在这种情况下等待您需要有一个资源副本。因此,在统一缓冲区的情况下,您可以更新给定缓冲区中的数据并在给定帧中使用它。在帧完成之前您无法修改其内容 - 因此要在前一帧仍在 GPU 上处理时准备另一帧动画,您需要使用另一个副本。
同样,如果下一帧需要生成的数据(例如用于屏幕 space 反射的帧缓冲区)。重复使用相同的资源会导致其内容被覆盖。这就是为什么你需要另一个副本。
您可以在此处找到更多信息:https://software.intel.com/en-us/articles/api-without-secrets-the-practical-approach-to-vulkan-part-1
在简单的 Hello Cube 应用程序的情况下,最大限度地减少同步。
假设你的制服每一帧都在变化。这意味着主循环类似于:
- 轮询(或模拟)
- 更新(例如你的制服)
- 画画
- 重复
如果步骤#2没有自己的uniform,那么就需要写一个uniform previous frame is reading。这意味着它必须与 Fence 同步。这意味着不再考虑前一帧 "in-flight".