天天看點

Vulkan【10】建立描述符集合建立描述符集合

建立描述符集合

本節的代碼是

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