代码之家  ›  专栏  ›  技术社区  ›  Blindy

Vulkan中更新顶点缓冲区的最普遍正确方法

  •  0
  • Blindy  · 技术社区  · 6 年前

    我看到了两种更新顶点缓冲区的常用方法:

    1. 地图+ memcpy vkCmdCopyBuffer ,将其提交到图形队列并等待队列空闲,然后释放临时命令缓冲区。之后,像往常一样将常规帧绘制队列提交到图形队列。这是在上使用的代码 https://vulkan-tutorial.com (例如, this .cpp file ).

    2. 与上面类似,只需在暂存缓冲区copy submit之后使用附加信号量发出信号,并在常规帧draw submit中等待,从而跳过“wait for idle”命令。

    0 回复  |  直到 6 年前
        1
  •  4
  •   Nicol Bolas    5 年前

    and OpenGL doesn't even have that requirement anymore ).

    曾经

    第二,如果您想到了一个让CPU等待队列或设备空闲再继续的想法,那么您想到了一个坏主意,应该使用另一个。您应该等待设备空闲的唯一时间是您要销毁该设备的时间。

    在任何情况下,在Vulkan做大多数事情都没有“最普遍正确的方式”。肯定有很多 方法,但没有“一般这样做”的建议。Vulkan是一个低级的、显式的API,其结果是您需要将Vulkan的工具应用于您的特定环境。也许在不同的硬件上配置文件。

    例如,如果每帧生成一个全新的顶点数据,那么最好看看实现是否可以直接从一致性内存中读取顶点数据,这样就根本不需要临时缓冲区。是的,读取速度可能较慢,但整个过程可能比读取后的传输速度更快。

    再说一次,可能不是。它在某些硬件上可能更快,而在其他硬件上可能更慢。有些硬件可能不允许对任何顶点输入使用的缓冲区使用一致内存。即使允许,您也可以在传输过程中执行其他工作,因此GPU在读取传输数据之前花费的等待时间最少。有些硬件有一个小的设备本地内存池,可以直接从CPU写入;此内存用于这些类型的流式应用程序。

    但是,如果要执行转移,那么您的选择主要是关于提交转移操作的队列(假设硬件有多个队列)。这主要与你愿意忍受多少延迟有关。

    例如,如果您正在为一个大型地形系统流式传输数据,那么在GPU上使用顶点数据可能需要一两帧。在这种情况下,您应该寻找一个替代的仅传输队列,在该队列上执行从暂存缓冲区到主内存的复制。如果您这样做,那么您将需要确保使用最终结果的后续命令与该队列同步,这将需要通过信号量来完成。

    推荐文章