【问题标题】:Is resetting the command buffer faster than setting an uniform buffer?重置命令缓冲区是否比设置统一缓冲区更快?
【发布时间】:2018-07-17 10:03:38
【问题描述】:

我正在尝试学习 Vulkan(主要来自 vulkan-tutorial.com),因为我编写了一个混合图形/计算应用程序(我需要渲染一个深度缓冲区并对其执行一些计算,没有显示)。我几乎要渲染我的第一个(深度)图像,我需要做的就是弄清楚如何将单个 vec4 作为唯一参数传递给我的顶点着色器(除了位置属性)。

我读到的所有地方都说推送常量比制服快,所以它们似乎是我的参数的明显选择,但似乎我需要在每个渲染图像处重置命令缓冲区,以便使用 @987654324 更改我的推送常量@,而使用制服时,我可以保持命令缓冲区固定,并在使用 vkQueueSubmit() 提交渲染任务之前简单地更新映射的内存区域(如果不连贯,则刷新)。

重写整个命令缓冲区真的比映射内存写入快吗?或者说推送参数更快的人假设命令缓冲区将在每个渲染图像时重建,所以大部分成本已经支付了?

最后,我可以更新另一个命令缓冲区中的推送常量吗? (我想不是,但我不清楚常量推送的有效时间,也不清楚管道保持绑定的时间。)如果可能,这是一个好方法吗?

编辑:不,那是不可能的,刚刚发现here那个:

每个命令缓冲区独立于其他命令缓冲区管理状态。

当命令缓冲区开始记录时,该命令中的所有状态 缓冲区未定义。

因此我的问题仍然存在。

【问题讨论】:

    标签: vulkan


    【解决方案1】:

    重写整个命令缓冲区真的比映射内存写入快吗?

    这是一个错误的问题。您没有考虑修改内存以使 GPU 可以使用它实际需要什么。

    好的,所以你已经有了这个从内存中读取制服的命令缓冲区。并且您想在两个单独的框架中使用它。但是你想改变帧之间的内存。

    嗯,在第一帧完成读取之前,您无法写入该内存。所以你需要 CB 在最后一次读取制服后设置一个事件。并且在为该帧提交 CB 之后,您需要在 CPU 上等待该事件才能写入数据(更不用说提交下一帧的数据价值了)。

    这就是 CPU/GPU 同步。对于 GPU 性能或 CPU 性能来说,这并不好。 GPU 可能会停止工作,因为 CPU 必须进行此类同步,而 CPU 可能只是坐在那里无所事事。

    重建大多数命令缓冲区是 Vulkan 应用程序的典型工作方式。

    【讨论】:

    • 假设我可以同时渲染 N 帧:我可以重写并提交命令缓冲区 N 次,或者将 N 个不同的命令缓冲区绑定到统一的 N 个不同的内存区域。在这两种情况下,我都需要 N 个栅栏才能知道何时可以提交下一帧,所以我在这里看不出有什么区别。
    • "假设我可以同时渲染 N 帧" 为什么要同时渲染多个帧?在任何情况下,您只需要 N+1 个缓冲区和 N+1 个内存区域。而且您使用信号量进行同步,而不是事件,因为您是根据提交本身的完成时间进行同步的。
    • 我只是概括,你说“你想在两个单独的帧中使用它。”,我概括为N,这是同样的问题:我可以通过分配一个统一的缓冲区来渲染框架。具体来说,在我的应用程序中,我需要的所有帧都是事先知道的(即不依赖于时间,就像在交互式应用程序中一样),所以理论上我可以同时对我需要的任意数量的帧进行排队。
    • “在这两种情况下,我都需要 N 个栅栏才能知道何时可以提交下一帧,所以我看不出这里有什么区别。” 区别在于同步.您仍然需要执行它,您仍然需要 N 个栅栏来知道何时可以重用(重新记录)或销毁命令缓冲区。但是对于 N 帧,您可以在 GPU 仍在执行其工作时执行此同步。即使您将这 N 个命令缓冲区一起提交,第一个命令缓冲区也很有可能比最后一个命令缓冲区更早完成。所以你可以在不阻塞 GPU 的情况下重复使用它。
    • @lvella:你已经被告知不同之处。在一种情况下,您必须将制服的修改与 CB 的完成同步。在另一种情况下,您可以创建一个新命令缓冲区,而不必与任何东西同步。
    猜你喜欢
    • 2011-07-24
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多