稀疏的VkDescriptorSetLayoutBinding的用例是什么?

时间:2019-08-08 01:25:50

标签: vulkan

我很难弄清楚VkDescriptorSetLayoutBinding :: binding的任何用例,这里是struct:

struct VkDescriptorSetLayoutBinding 
{
    uint32_t              binding;
    VkDescriptorType      descriptorType;
    uint32_t              descriptorCount;
    VkShaderStageFlags    stageFlags;
    const VkSampler*      pImmutableSamplers;
};

在这里用于创建DescriptorSetLayout:

struct VkDescriptorSetLayoutCreateInfo 
{
    VkStructureType                        sType;
    const void*                            pNext;
    VkDescriptorSetLayoutCreateFlags       flags;
    uint32_t                               bindingCount;
    const VkDescriptorSetLayoutBinding*    pBindings;
};

我想知道为什么不能从pBindings数组的索引中推断出“ binding”变量。 经过一番研究,我发现vulkan规格说:

  

上面的布局定义允许稀疏指定描述符绑定,以便不需要在pBindings数组中指定0到最大绑定数之间的所有绑定数。未指定的绑定的描述符计数和stageFlags为零,并且描述符类型的值未定义。但是,即使没有使用所有描述符绑定,VkDescriptorSetLayoutCreateInfo :: pBindings数组中介于0和最大绑定数之间的所有绑定数可能会消耗描述符集布局中的内存,尽管它不应消耗描述符池中的额外内存。

我找不到在那种情况下可以使用那些稀疏的绑定的原因,为什么还要留下一个空的未使用空间?

1 个答案:

答案 0 :(得分:2)

绑定索引被硬编码到着色器中(您可以通过特殊化常量定义绑定索引,但是,它们是着色器代码的一部分)。因此,让我们假设您具有着色器阶段的代码。您想在两个不同的管道(A和B)中使用它。假设这些管道的描述符集布局不​​兼容。我们只想重用着色器。

好吧,着色器中的绑定索引没有改变;他们不能更改。因此,如果此着色器在集0的绑定3中具有UBO,则它与一起使用的任何描述符集布局必须在集0的绑定3中具有UBO。

也许在流水线A中,除了我们重用的着色器以外,其他某些着色器可能会使用集合0中的绑定0、1和2。但是,如果流水线B的其他着色器都不需要绑定索引2,该怎么办?也许流水线A中的片段着色器使用了3个描述符资源,但流水线B中的一个片段着色器仅需要2个。

具有稀疏描述符绑定,您可以重新使用编译的着色器模块而无需,而不必在着色器中重新分配绑定索引。哦,是的,您必须确保所有这些着色器彼此兼容(它们不会以不同的方式使用相同的set + binding索引),但是除此之外,您可以自由地进行混合和匹配。 / p>

并且应该注意,连续绑定几乎从来不是任何API的要求。在OpenGL中,着色器管道可以使用2、40和32纹理单元,这是100%好的。

为什么Vulkan会因为它的资源绑定模型更抽象而与众不同?