vulkan - 稀疏 VkDescriptorSetLayoutBinding 有哪些用例?

标签 vulkan

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

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;
};

我想知道为什么“绑定(bind)”变量不是从 pBindings 数组中的索引推导出来的。 经过一些研究,我发现 vulkan 规范说:

The above layout definition allows the descriptor bindings to be specified sparsely such that not all binding numbers between 0 and the maximum binding number need to be specified in the pBindings array. Bindings that are not specified have a descriptorCount and stageFlags of zero, and the value of descriptorType is undefined. However, all binding numbers between 0 and the maximum binding number in the VkDescriptorSetLayoutCreateInfo::pBindings array may consume memory in the descriptor set layout even if not all descriptor bindings are used, though it should not consume additional memory from the descriptor pool.

我找不到在什么情况下可以使用这些稀疏的绑定(bind),为什么要留下一个空的未使用空间?

最佳答案

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

嗯,着色器中的绑定(bind)索引没有改变;他们无法改变。因此,如果此着色器在集合 0 的绑定(bind) 3 中具有 UBO,则与它一起使用的任何描述符集布局都必须在集合 0 的绑定(bind) 3 中具有 UBO。

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

通过稀疏描述符绑定(bind),您可以重用已编译的着色器模块,而无需在着色器内重新分配绑定(bind)索引。哦,是的,您必须确保所有此类着色器彼此兼容(它们不会以不同的方式使用相同的集合+绑定(bind)索引),但除此之外,您可以自由混合和匹配。

应该指出的是,连续绑定(bind)几乎从来都不是任何 API 的要求。在 OpenGL 中,您的着色器管道可以使用纹理单元 2、40 和 32,这 100% 没问题。

为什么 Vulkan 应该有所不同,仅仅因为它的资源绑定(bind)模型更加抽象?

关于vulkan - 稀疏 VkDescriptorSetLayoutBinding 有哪些用例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57404083/

相关文章:

java - 在 Swing 中显示 vulkan 渲染

c++ - vkWaitForFences 和 vkDeviceWaitIdle 不等待

vulkan - 模板传递写入颜色缓冲区吗?

memory-management - 应如何正确使用 Staging Buffer 以提高性能?

c++ - 调用 vkCreateInstance() 时出现奇怪的错误

directx-12 - DirectX 12/Mantle/Vulkan 和 HSA

c++ - 如何将 Vulkan-hpp 包含在 glfw 中?

c++ - 提交的命令缓冲区出现 CoreValidation-DrawState-InvalidImageLayout 错误

c++ - 使用计算着色器的错误结果

c++ - 如何将一组统一缓冲区对象加载到着色器中?