来自先前管道的 VkDescriptorSet 提供性能警告

VkDescriptorSet from previous pipeline giving performance warning

Vulkan 允许多组输入描述。在我的用例中,我用 2 组渲染一个特定对象。将具有 2 个偏移量的 0 设置到包含两个不同偏移位置上的帧数据和对象数据的动态缓冲区中。设置 1 为每个对象更改的纹理。所以在我第一次通过后,我有 2 套绑定。现在,当我开始下一个子通道并绑定不同的管道时,这两个集合仍然绑定,然后当我尝试绑定集合 0(我现在不需要集合 1)时,我收到关于不兼容的性能警告。

DescriptorSetDS 0x10 previously bound as set #0 is incompatible with set 0x668cec8 newly bound as set #0 so set #1 and any subsequent sets were disturbed by newly bound pipelineLayout (0x64)

现在我清楚了,我知道第 1 组是 "disturbed"。但我不知道该怎么做才能告诉 vulkan 这是正确的,因此不再给出警告(设计总是出现此错误的软件似乎是错误的)。我希望像重置绑定的集合一样,"unbinding" 集合。但我想我遗漏了一些东西,因为我什么也没看到。

当然,也许我做错了什么,或者缺少一些相关命令,所以我简化的完成调用顺序:

vkCmdBeginRenderPass vkCmdBindPipeline vkCmdBindDescriptorSets -> bind sets: 0, 1 vkCmdBindVertexBuffers vkCmdDraw vkCmdNextSubpass vkCmdBindPipeline (different pipeline) vkCmdBindDescriptorSets -> bind set: 0 -> error about set disturbance

目前还没有很好的答案。你目前正在做的事情在性能方面应该是非常好的。只是无法将您的意图充分传达给调试层。

Vulkan API 没有办法让你说 "I'm setting set 0 and I don't care about any of the later sets." 因此,验证层无法区分它和 "I'm setting set 0 and I want to retain the later sets." 实际驱动程序没有没关系,但是验证层需要知道你的意图。

我建议只接受警告。如果你试图做一些事情,比如让它使用第 1 组或第 2 组,你只会让事情变得更困难。您必须发明一个管道布局,其中集 0 是一个空集,但随后您必须实际将一个空集绑定到集 0。这意味着您必须创建一个空描述符集以绑定到那里。

这只是误报。