Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Descriptor Set count ambiguity in Vulkan

I want to draw two objects in vulkan. To achieve this I follow the procedure where you create two different descriptor sets for each model. However, I am confused about the structs that specify the required descriptor set count. The points that confuses me are as follows:

  1. specifying the descriptor count at VkDescriptorSetLayoutBinding

    VkDescriptorSetLayoutBinding stagingLayoutBinding = {};
    ...
    stagingLayoutBinding.descriptorCount = 1;   <- i have one mat4 element for each descriptors 
    
  2. specifying the descriptor count at VkDescriptorPoolSize

    VkDescriptorPoolSize stagingPoolSize = {};
    ...
    stagingPoolSize.descriptorCount = static_cast<uint32_t>(model.size());  <- allocate two descriptor sets from one descriptor pool
    
  3. specifying the max sets at VkDescriptorPoolCreateInfo

    VkDescriptorPoolCreateInfo poolInfo = {};
    ...
    poolInfo.maxSets = model.size();   <- max descriptor sets = 2
    
  4. finally specifying the descriptor set creation at VkDescriptorSetAllocateInfo

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

however, an exception is thrown at vkAllocateDescriptorSets(device, &allocInfo, descriptorSet.data()) and the debugging message in validation layer is as follows:-

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)

my descriptor creation code is as follows:

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

I presume I am feeding the wrong descriptor set count somewhere.

like image 368
BulBul Avatar asked Aug 06 '18 21:08

BulBul


1 Answers

The problem lays probably here:

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

If You want to draw 2 objects than I assume model.size() returns 2. Yet, You provide only one descriptor set layout:

VkDescriptorSetLayout layouts[] = { descriptorSetLayout };

If You want to allocate 2 (or more) descriptor sets, You need to provide 2 (or more) descriptor set layouts. If You want the descriptor sets to share the layout, You just need to provide the same layout multiple times.

As for the confusing fields:

  1. descriptorCount member of the VkDescriptorSetLayoutBinding structure is the number of descriptors contained in the binding, accessed in a shader as an array. Usually 1 will be provided here, unless You want to create an array of descriptors of a given type (for example an array of sampled images), then You need to provide a larger value.
  2. descriptorCount member of the VkDescriptorPoolSize specifies how many descriptors of a given type can be allocated from a given pool. This value is independent of the total descriptor sets, for example You can create a descriptor pool from which You can allocate 3 descriptor sets in total, but only 2 storage images in total.
  3. maxSets member of the VkDescriptorPoolCreateInfo structure defines how many descriptor sets can be allocated from a given pool (the total number of sets which can be allocated from the pool). Again, this value defines "whole" sets, while the previous value (from the bullet 2) defines specific descriptors.
  4. descriptorSetCount member of the VkDescriptorSetAllocateInfo structure specifies how many descriptor sets You want to allocate at a given moment (during vkAllocateDescriptorSets() function call). For example, You can create a pool from which You can allocate 10 descriptor sets, but You want to allocate only one descriptor set at a time, by calling the vkAllocateDescriptorSets() function 10 times.
like image 92
Ekzuzy Avatar answered Oct 08 '22 11:10

Ekzuzy