gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 01:23:55 25 4
gpt4 key购买 nike

假设设备内存中有一个顶点缓冲区和一个与主机一致且可见的暂存缓冲区。还假设桌面系统具有独立的 GPU(因此是独立的内存)。最后,假设正确的帧间同步。

我看到两种更新顶点缓冲区的一般可能方法:

  1. Map + memcpy + 取消映射到暂存缓冲区,然后是包含 vkCmdCopyBuffer 的 transient (单个命令)命令缓冲区,将其提交给图形队列并等待队列空闲,然后释放 transient 命令缓冲区。之后像往常一样将常规帧绘制队列提交到图形队列。这是 https://vulkan-tutorial.com 上使用的代码(例如,this .cpp file)。

  2. 与上述类似,只是在暂存缓冲区副本提交后使用额外的信号量发出信号,并在常规帧绘制提交中等待,从而跳过“等待空闲”命令。

#2 对我来说有点意义,我反复阅读不要在 Vulkan 中执行任何“等待空闲”操作,因为它使 CPU 与 GPU 同步,但我从未见过它在 Vulkan 中使用任何在线教程或示例。如果必须相对频繁地更新顶点缓冲区,专业人员通常会做什么?

最佳答案

首先,如果您分配了一致性内存,那么几乎可以肯定您这样做是为了从 CPU 访问它。这需要映射它。 Vulkan 不是 OpenGL;不需要在使用内存之前取消映射内存 (and OpenGL doesn't even have that requirement anymore)。

只有当您要删除内存分配本身时,才应该永远取消映射内存。

其次,如果您的想法涉及让 CPU 在继续之前等待队列或设备空闲,那么您的想法很糟糕,应该使用不同的想法。只有当您想要销毁设备时,您才应该等待设备空闲。

不应相信教程代码可以提供最佳实践。它通常旨在简单,以便于理解一个概念。简单的 Vulkan 代码通常会影响性能(如果您不关心性能,则不应使用 Vulkan)。

无论如何,在 Vulkan 中做大多数事情都没有“最普遍正确的方法”。有很多绝对不正确的方法,但没有“通常这样做”的建议。 Vulkan 是一个低级的显式 API,其结果是您需要将 Vulkan 的工具应用到您的具体情况。可能还会在不同的硬件上进行配置。

例如,如果您每帧都生成全新的顶点数据,最好查看实现是否可以直接从相干内存中读取顶点数据,这样就根本不需要暂存缓冲区。是的,读取可能会更慢,但整个过程可能比先传输再读取更快。

话又说回来,它可能不会。它在某些硬件上可能更快,而在其他硬件上可能更慢。并且某些硬件可能根本不允许您对任何具有顶点输入用途的缓冲区使用相干内存。即使允许,您也可以在传输过程中做其他工作,因此 GPU 在读取传输数据之前等待的时间最少。有些硬件有一小块设备本地内存,你可以直接从 CPU 写入;此内存适用于这些类型的流应用程序。

但是,如果您打算进行暂存,那么您的选择主要是关于您在哪个队列上提交传输操作(假设硬件有多个队列)。这主要与您愿意忍受的延迟时间有关。

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

如果您处于低延迟情况下,传输的数据需要在该帧中使用,那么将两者提交到同一个队列可能会更好。您可以使用事件而不是信号量来同步它们。但是您也应该努力在传输和渲染操作之间放置一些不相关的工作,以便您可以在操作中利用某种程度的并行性。

关于language-agnostic - 在 Vulkan 中更新顶点缓冲区的最普遍正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62182124/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com