gpt4 book ai didi

vulkan - 如何为多个交错缓冲区正确使用描述符集?

转载 作者:行者123 更新时间:2023-12-04 23:37:33 24 4
gpt4 key购买 nike

我有一个统一的缓冲区,应该每帧更新一次。为了避免大停顿,我想创建 3 个缓冲区(按我的帧缓冲区的数量),它们应该每帧交错(0-1-2-0-1-2-...)。但我不明白如何创建描述符并绑定(bind)它们。这就是我现在的做法:

  • 我创建了一个 VkDescriptorSetLayout我指定我想在某个着色器阶段的绑定(bind)位置 0 处使用统一缓冲区。
  • 我创建了一个 VkDescriptorPool统一缓冲区的大小为 3 个描述符。
  • 接下来我需要分配描述符集,但这里需要多少个描述符集?我只有一个VkDescriptorSetLayout我希望得到一个VkDescriptorSet .
  • 接下来我需要更新创建的描述符集。由于我的着色器中只有一个绑定(bind) (0),我只能在 VkDescriptorBufferInfo 中使用一个 one 缓冲区。将传递给 VkWriteDescriptorSet将传递给 vkUpdateDescriptorSets .但是其他两个缓冲区呢?在哪里指定它们?
  • 当我需要记录命令时,我需要绑定(bind)我的描述符集。但到目前为止,我有一个描述符集,它只为一个缓冲区更新。其他人呢?

  • 我需要创建 3 VkDescriptorSetLayout - 每帧一个?接下来我需要用相应的缓冲区分配和更新相应的描述符集吗?在此之后,我需要创建 3 个不同的命令缓冲区,我应该在其中指定相应的描述符集。

    看起来工作量很大 - 数据几乎相同 - 所有绑定(bind),状态保持不变,只有缓冲区发生变化。

    这一切听起来很困惑,所以请不要犹豫澄清。

    最佳答案

    Descriptor Set Layouts 定义了一个描述符集合的内容——给定集合包含哪些类型的资源(描述符)。当您需要具有单个统一缓冲区的多个描述符集时,您可以使用相同的布局创建所有这些描述符集(布局只是一个描述,一个规范)。这样你只需告诉司机:“嘿,司机!给我 3 个描述符集。但它们都应该完全相同”。

    但是因为它们是从相同的布局创建的,并不意味着它们必须包含相同的资源句柄。所有它们(在您的情况下)都必须包含一个统一的缓冲区。但是这个统一缓冲区将使用什么资源取决于你。因此,每个描述符集都可以使用单独的缓冲区进行更新。

    现在,当您想在三个连续的帧中一个接一个地使用 3 个缓冲区时,您可以通过几种不同的方式进行操作:

  • 您可以有一个描述符集。然后在每一帧中,在您开始准备命令缓冲区之前,您使用下一个缓冲区更新描述符集。但是,当您更新描述符集时,任何已提交(且尚未完成)的命令缓冲区都不能使用它。所以这将需要额外的同步,并且与使用单个缓冲区没有太大区别。这样您也不能“预先记录”命令缓冲区。
  • 您可以有一个描述符集。要更改其内容(在其中使用不同的缓冲区)您可以通过 VK_KHR_descriptor_update_template 扩展中添加的函数对其进行更新。它允许将描述符更新记录在命令缓冲区中,因此同步应该更容易一些。它应该允许您预先记录命令缓冲区。但它需要支持扩展,因此在不支持它的平台上它不是一个选项。
  • 您可能想到的方法 - 您可以拥有 3 个单独的描述符集。所有这些都使用具有统一缓冲区的相同布局进行分配。然后你用不同的缓冲区更新每个描述符集(你可以使用第一个缓冲区和第一个描述符集,第二个缓冲区和第二个描述符集和第三个缓冲区和第三个描述符集)。现在在记录命令缓冲区期间,当您想使用第一个缓冲区时,您只需绑定(bind)第一个描述符集。在下一帧中,您只需绑定(bind)第二个描述符集,依此类推。

  • 方法 3 可能是最容易实现的,因为它不需要描述符同步(如果您有,则只需要每帧级同步)。它还允许您预先记录命令缓冲区,并且不需要启用任何其他扩展。但正如您所指出的,它需要创建和管理更多资源。

    不要忘记,您需要创建一个足够大的描述符池以包含 3 个统一缓冲区,但同时您还必须指定要从中分配 3 个描述符集(每个描述符集一个统一缓冲区)。

    您可以在 Intel 的 API without Secrets: Introduction to Vulkan - Part 6 中阅读有关描述符集的更多信息。教程。

    至于你的问题:

    Do I need to create 3 VkDescriptorSetLayout - one for every frame?



    否 - 单个布局就足够了(只要所有描述符集在相同绑定(bind)中包含相同类型的资源。

    Next do I need to allocate and update corresponding descriptor set with a corresponding buffer?



    根据选项 3 - 是的。

    And after this do I need to create 3 different command buffers where I should specify corresponding descriptor set.



    这取决于您是每帧重新记录命令缓冲区还是预先预先记录它们。通常命令缓冲区每帧都会重新记录。但是由于拥有单个命令缓冲区需要等待其提交完成,您可能需要为每个帧设置一组命令缓冲区,它们对应于您的帧缓冲区图像(和描述符集)。因此,在第 0 帧中,您使用命令缓冲区 #0(或为第 0 帧保留的多个命令缓冲区)。在第 1 帧中,您使用命令缓冲区 #1 等。

    现在您可以记录给定帧的命令缓冲区,并且在记录期间您提供与给定帧关联的描述符集。

    关于vulkan - 如何为多个交错缓冲区正确使用描述符集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48867995/

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