Vulkan中的描述符集计数歧义

Bul*_*Bul 7 c++ 3d graphics vulkan

我想在vulkan中绘制两个对象.为此,我按照为每个模型创建两个不同描述符集的过程进行操作.但是,我对指定所需描述符集计数的结构感到困惑.困扰我的要点如下:

  1. VkDescriptorSetLayoutBinding指定描述符计数

    VkDescriptorSetLayoutBinding stagingLayoutBinding = {};
    ...
    stagingLayoutBinding.descriptorCount = 1;   <- i have one mat4 element for each descriptors 
    
    Run Code Online (Sandbox Code Playgroud)
  2. VkDescriptorPoolSize指定描述符计数

    VkDescriptorPoolSize stagingPoolSize = {};
    ...
    stagingPoolSize.descriptorCount = static_cast<uint32_t>(model.size());  <- allocate two descriptor sets from one descriptor pool
    
    Run Code Online (Sandbox Code Playgroud)
  3. VkDescriptorPoolCreateInfo中指定最大值集

    VkDescriptorPoolCreateInfo poolInfo = {};
    ...
    poolInfo.maxSets = model.size();   <- max descriptor sets = 2
    
    Run Code Online (Sandbox Code Playgroud)
  4. 最后在VkDescriptorSetAllocateInfo中指定描述符集创建

    VkDescriptorSetAllocateInfo allocInfo = {};
    ...
    allocInfo.descriptorSetCount = static_cast<uint32_t>(model.size());
    
    Run Code Online (Sandbox Code Playgroud)

但是,抛出异常vkAllocateDescriptorSets(device, &allocInfo, descriptorSet.data())并且验证层中的调试消息如下: -

validation Layer: Object: 0xcccccccccccccccc (Type = 20) | Invalid DescriptorSetLayout Object 0xcccccccccccccccc. The spec valid usage text states 'pSetLayouts must be a valid pointer to an array of descriptorSetCount valid VkDescriptorSetLayout handles' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter)
Run Code Online (Sandbox Code Playgroud)

我的描述符创建代码如下:

    VkDescriptorSetLayout layouts[] = { descriptorSetLayout };

    descriptorSet.resize(model.size());
    VkDescriptorSetAllocateInfo allocInfo = {};
    allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
    allocInfo.descriptorPool = descriptorPool[0];
    allocInfo.descriptorSetCount = static_cast<uint32_t>(model.size());
    allocInfo.pSetLayouts = layouts;

    if (vkAllocateDescriptorSets(device, &allocInfo, descriptorSet.data()) != VK_SUCCESS)
    {
        throw std::runtime_error("failed to allocate descriptor set !");
    }
Run Code Online (Sandbox Code Playgroud)

我认为我在某处提供了错误的描述符集计数.

Ekz*_*uzy 10

问题可能在这里:

allocInfo.descriptorSetCount = static_cast<uint32_t>(model.size());
Run Code Online (Sandbox Code Playgroud)

如果你想绘制2个对象而不是我假设model.size()返回2.但是,您只提供一个描述符集布局:

VkDescriptorSetLayout layouts[] = { descriptorSetLayout };
Run Code Online (Sandbox Code Playgroud)

如果要分配2个(或更多)描述符集,则需要提供2个(或更多)描述符集布局.如果您希望描述符集共享布局,则只需多次提供相同的布局.

至于令人困惑的领域:

  1. descriptorCountVkDescriptorSetLayoutBinding结构的成员是绑定中包含的描述符的数量,在着色器中作为数组访问.1除非您想要创建给定类型的描述符数组(例如采样图像数组),否则通常会在此处提供,然后您需要提供更大的值.
  2. descriptorCount该成员VkDescriptorPoolSize指定可以从给定池分配给定类型的描述符的数量.此值与总描述符集无关,例如,您可以创建一个描述符池,您可以从中分配总共3个描述符集,但总共只能分配2个存储库.
  3. maxSetsVkDescriptorPoolCreateInfo结构的成员定义可以从给定池分配多少个描述符集(可以从池中分配的集合总数).同样,此值定义"整个"集,而前一个值(来自项目符号2)定义特定描述符.
  4. descriptorSetCountVkDescriptorSetAllocateInfo结构的成员指定在给定时刻(在vkAllocateDescriptorSets()函数调用期间)要分配的描述符集数量.例如,您可以创建一个池,您可以从中分配10个描述符集,但是您希望通过调用该vkAllocateDescriptorSets()函数10次,一次只分配一个描述符集.

  • @BulBul`&descriptorSetLayout`指向单个描述符集布局.你应该有类似的东西:`VkDescriptorSetLayout layouts [] = {descriptorSetLayout,descriptorSetLayout};`和`allocInfo.pSetLayouts = layouts;`. (2认同)