创建描述符集合
本节的代码是
09-init_descriptor_set.cpp
回到“管线布局”示例,你定义了描述符集合布局,但并没有真正为它分配内存。回想一下,您定义的描述符集用于通知GPU如何将uniform 缓冲区中包含的数据映射到shader程序的统一变量。现在,您可以继续分配和初始化描述符集合。
描述符池
与命令缓冲区一样,描述符集合是从池中分配的。所以您必须首先创建池。因为您知道,对于uniform 缓冲区,您只需要一个描述符集,所以创建池是非常简单的:
VkDescriptorPoolSize type_count[1];
type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
type_count[0].descriptorCount = 1;
VkDescriptorPoolCreateInfo descriptor_pool = {};
descriptor_pool.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptor_pool.pNext = NULL;
descriptor_pool.maxSets = 1;
descriptor_pool.poolSizeCount = 1;
descriptor_pool.pPoolSizes = type_count;
res = vkCreateDescriptorPool(info.device, &descriptor_pool, NULL,
&info.desc_pool);
从池中分配一个描述符集合
现在您可以从池中分配一个描述符集。注意,您必须提供您在管道布局样例中定义的描述符集合布局。这个布局描述了如何分配描述符集。
VkDescriptorSetAllocateInfo alloc_info[1];
alloc_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info[0].pNext = NULL;
alloc_info[0].descriptorPool = info.desc_pool;
alloc_info[0].descriptorSetCount = NUM_DESCRIPTOR_SETS;
alloc_info[0].pSetLayouts = info.desc_layout.data();
info.desc_set.resize(NUM_DESCRIPTOR_SETS);
res = vkAllocateDescriptorSets(info.device, alloc_info, info.desc_set.data());
更新描述符集合
请注意,您还没有真正地在任何地方使用Uniform缓冲区的句柄。当你创建Uniform缓冲区时,你将Uniform缓冲区的信息保存在
VkDescriptorBufferInfo
结构体中,结构体变量名为
VkDescriptorBufferInfo
。 在函数
init_uniform_buffer()
来观察
info.uniform_data.buffer_info
是如何初始化的。
info.uniform_data.buffer_info
是一个下面结构体的实例:
typedef struct VkDescriptorBufferInfo {
VkBuffer buffer;
VkDeviceSize offset;
VkDeviceSize range;
} VkDescriptorBufferInfo;
其中
buffer
成员包含了Uniform缓冲区的句柄。
VkWriteDescriptorSet writes[1];
writes[0] = {};
writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[0].pNext = NULL;
writes[0].dstSet = info.desc_set[0];
writes[0].descriptorCount = 1;
writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
writes[0].pBufferInfo = &info.uniform_data.buffer_info;
writes[0].dstArrayElement = 0;
writes[0].dstBinding = 0;
vkUpdateDescriptorSets(info.device, 1, writes, 0, NULL);
上面的步骤本质上是将
VkDescriptorBufferInfo
复制到描述符中,描述符在设备内存中。
这个缓冲区信息包括对uniform 缓冲区的句柄,以及在uniform 缓冲区中访问的数据的偏移量和大小。在这种情况下,uniform 缓冲区只包含MVP转换,所以偏移量为0,大小是MVP的大小,这是由
info.uniform_data.buffer_info
中的管道布局示例设置的。
描述符的精确的字节布局可能是特定于实现的,因此对您来说是不透明的。这就是为什么您使用Vulkan驱动函数来操作描述符,而不是自己映射和编写它们。
© Copyright 2016 LunarG, Inc