Vulkan中的描述符集计数歧义

时间:2018-08-06 21:34:47

标签: c++ 3d game-engine vulkan

我想在vulkan中绘制两个对象。为此,我遵循为每个模型创建两个不同描述符集的过程。但是,我对指定所需描述符集计数的结构感到困惑。让我感到困惑的几点如下:

  1. VkDescriptorSetLayoutBinding

    处指定描述符计数
    VkDescriptorSetLayoutBinding stagingLayoutBinding = {};
    ...
    stagingLayoutBinding.descriptorCount = 1;   <- i have one mat4 element for each descriptors 
    
  2. VkDescriptorPoolSize

    指定描述符计数
    VkDescriptorPoolSize stagingPoolSize = {};
    ...
    stagingPoolSize.descriptorCount = static_cast<uint32_t>(model.size());  <- allocate two descriptor sets from one descriptor pool
    
  3. VkDescriptorPoolCreateInfo

    处指定最大集
    VkDescriptorPoolCreateInfo poolInfo = {};
    ...
    poolInfo.maxSets = model.size();   <- max descriptor sets = 2
    
  4. 最终在 VkDescriptorSetAllocateInfo

    中指定描述符集的创建
    VkDescriptorSetAllocateInfo allocInfo = {};
    ...
    allocInfo.descriptorSetCount = static_cast<uint32_t>(model.size());
    

但是,在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)

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

    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 !");
    }

我想我在某个地方输入了错误的描述符集计数。

1 个答案:

答案 0 :(得分:6)

问题可能出在这里:

allocInfo.descriptorSetCount = static_cast<uint32_t>(model.size());

如果要绘制2个对象,我假设model.size()返回2。但是,您仅提供一种描述符集布局:

VkDescriptorSetLayout layouts[] = { descriptorSetLayout };

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

至于令人困惑的字段:

    descriptorCount结构的
  1. VkDescriptorSetLayoutBinding成员是绑定中包含的描述符的数量,在着色器中以数组形式访问。通常,这里会提供1,除非您要创建给定类型的描述符数组(例如,采样图像数组),否则您需要提供更大的值。
  2. descriptorCount
  3. VkDescriptorPoolSize成员指定可以从给定池中分配给定类型的描述符的数量。此值与总的描述符集无关,例如,您可以创建一个描述符池,从该池中可以总共分配3个描述符集,但总共只能分配2个存储映像。
  4. maxSets结构的
  5. VkDescriptorPoolCreateInfo成员定义可以从给定的池中分配多少个描述符集(可以从池中分配的集的总数)。同样,该值定义“整个”集合,而前一个值(来自项目符号2)定义特定的描述符。
  6. descriptorSetCount结构的
  7. VkDescriptorSetAllocateInfo成员指定您要在给定时刻(在vkAllocateDescriptorSets()函数调用期间)分配多少个描述符集。例如,您可以创建一个池,从中可以分配10个描述符集,但是您想通过一次调用vkAllocateDescriptorSets()函数10次来一次只分配一个描述符集。