我很难弄清楚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和最大绑定数之间的所有绑定数可能会消耗描述符集布局中的内存,尽管它不应消耗描述符池中的额外内存。>
我找不到在那种情况下可以使用那些稀疏的绑定的原因,为什么还要留下一个空的未使用空间?
答案 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会因为它的资源绑定模型更抽象而与众不同?