描述符池

描述符集不能被直接创建,需要通过描述符池来分配。我们添加一个叫做createDescriptorPool的函数来进行描述符池的创建:描述符集不能被直接创建,需要通过描述符池来分配。我们添加一个叫做createDescriptorPool的函数来进行描述符池的创建:

void initVulkan() {
        ...
    createUniformBuffer();
    createDescriptorPool();
        ...
}

        ...

void createDescriptorPool() {

}

我们通过VkDescriptorPoolSize结构体来对描述符池可以分配的描述符集进行定义:

VkDescriptorPoolSize poolSize = {};
poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSize.descriptorCount = static_cast<uint32_t>(swapChainImages.size());

我们会在每一帧分配一个描述符。描述符池的大小需要通过VkDescriptorPoolCreateInfo结构体定义:

VkDescriptorPoolCreateInfo poolInfo = {};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSize;

除了可用的最大独立描述符个数外,我们还需要指定可以分配的最大描述符集个数:

poolInfo.maxSets = static_cast<uint32_t>(swapChainImages.size());

VkDescriptorPoolCreateInfo结构体有一个用于优化的标记,它决定了独立的描述符集是否可以被清除掉:VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT。由于我们在描述符集创建后,就不再对其进行操作,所以我们不需要使用这一标记,将其设置为0来使用它的默认值。

VkDescriptorPool descriptorPool;

...

if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS) {
    throw std::runtime_error("failed to create descriptor pool!");
}

我们添加了一个新的类成员变量来存储使用vkCreateDescriptorPool函数创建的描述符池对象。应用程序退出前,我们需要清除我们创建的描述符池对象:

void cleanup() {
    cleanupSwapChain();

    vkDestroyDescriptorPool(device, descriptorPool, nullptr);

        ...
}