描述符池
描述符集不能被直接创建,需要通过描述符池来分配。我们添加一个叫做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);
...
}