VkDescriptorPoolCreateInfo.pPoolSizes 这样理解对吗?

Is this understanding of VkDescriptorPoolCreateInfo.pPoolSizes correct?

在 Vulkan 中,我了解到描述符池用于分配一些布局的描述符集以供在着色器中使用,但是在传递给 vkCreateDescriptorPoolVkDescriptorPoolCreateInfo 中,有一个字段 pPoolSizes 需要一堆包含描述符类型和数字的对象。

文档似乎有些含糊,但这是说给定的描述符池只能在描述符集中分配一定数量的每种类型的描述符吗?如果是这样,我如何预先确定我需要多少?如果用完了怎么办?

您对描述符池的理解是正确的。

If so, how do I determine how many I will need beforehand?

这取决于您和您的应用程序的需求。

如果您的应用程序需要完全灵活和自由形式,那么您将需要根据需要动态创建描述符池。如果您的应用程序对场景的外观有更多的预知,那么您的应用程序将需要更少的此类体操。

许多严肃的 Vulkan 应用程序试图避免让描述符集的数量基于场景中的对象数量。推送常量 and/or 动态 UBO/SSBO 描述符允许在不更改描述符本身的情况下使用不同的每个对象状态。许多对象的纹理可以一起捆绑到数组纹理中,或者根据硬件,纹理数组。

在一个完美的世界中,可以使用完全相同的描述符集来渲染一种类型的所有网格(例如,蒙皮网格),使用一些每个对象的状态来获取该对象的正确 matrix/texture 数据。

但这就是他们呈现的方式。这样的应用程序可以严格控制它们渲染的对象种类、每个对象的数据是什么样的,等等。其他应用程序可能有不同的需求。

Vulkan 是一个工具;如何使用它完全取决于您。

What happens if it runs out?

那么你不能从那个池中分配更多的描述符。如果需要分配另一个描述符集,则需要创建另一个池。

我的方法是让一个 class 最初分配 N 个描述符,如果它用完,它将创建另一个包含 N*2 个条目的池。它的体积会不断翻倍。它使用一个简单的链表,在分配时,它只尝试第一个,如果已满则移至下一个。

这一切都非常低效,所以我还让我的代码在必须创建第二个池时触发一个断言,这样我就可以确保我选择了一个足够大的 N 值,以便零售版本应该永远不必这样做(但如果由于某些不可预见的情况而以某种方式设法做到,它仍然会正确呈现)。

当时,我记得诅咒规范并希望描述符池能像命令池一样自动增长。我仍然认为他们有一个很好的理由。