Vulkan Descriptor绑定过程

发布时间 2023-08-09 23:36:11作者: 风中奔跑

如果shader中的资源是这么排布的:

//vs
layout(set = 0, binding = 0, std140) uniform UBO
{
    mat4 projection;
    mat4 view;
    mat4 model;
} ubo;
layout(location = 0) in vec3 inPos;
layout(location = 0) out vec3 outUVW;


//fs
layout(set = 0, binding = 1) uniform samplerCube samplerCubeMap;
layout(location = 0) in vec3 inUVW;
layout(location = 0) out vec4 outFragColor;

 

对应的代码如下:

//DescriptorSetLayout描述了shader所包含的uniform、sampler等Descriptor的绑定信息 
VkDescriptorSetLayout setLayout;
{
	std::vector<VkDescriptorSetLayoutBinding> setlayoutBind(2);
	setlayoutBind[0].binding = 0;
	setlayoutBind[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	setlayoutBind[0]ayoutBinding.descriptorCount = 1;
	setlayoutBind[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;

	setlayoutBind[1].binding = 1;
	setlayoutBind[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
	setlayoutBind[1].descriptorCount = 1;
	setlayoutBind[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;

	VkDescriptorSetLayoutCreateInfo descriptorLayout = {};
	descriptorLayout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
	descriptorLayout.bindingCount = 2;
	descriptorLayout.pBindings = setlayoutBind.data();
	VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &setLayout));
}

// 基于Descriptor的布局创建 descriptorPool
VkDescriptorPool descriptorPool;
{
	VkDescriptorPoolCreateInfo descriptorPoolInfo = {};
	descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
	descriptorPoolInfo.maxSets = 5;
	descriptorPoolInfo.poolSizeCount = 2;
	std::vector<VkDescriptorPoolSize> poolSizes = {
		{.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 8;}
		{.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorCount = 6};
	}
	descriptorPoolInfo.pPoolSizes = poolSizes.data();
	VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
}
		
// 基于上面setLayout,从descriptorPool中分配DescriptorSet
VkDescriptorSet descriptorSet;
{
	VkDescriptorSetAllocateInfo allocInfo = {};
	allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
	allocInfo.descriptorPool = descriptorPool;
	allocInfo.descriptorSetCount = 1;
	allocInfo.pSetLayouts = &setLayout;
	VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
}

// 将Descriptor组装更新到DescriptorSet中,下面示例绑定了一个buffer和一个imageview
{
	std::vector<VkWriteDescriptorSet> writeDescriptors(2);
	VkDescriptorBufferInfo descBufferInfo927 = {.buffer = buffer927, .offset = 0, .range = VK_WHOLE_SIZE};
	writeDescriptors[0].pBufferInfo = &descBufferInfo927;
	writeDescriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writeDescriptors[0].dstSet = descriptorSet;
	writeDescriptors[0].dstBinding = 0;
	writeDescriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writeDescriptors[0].descriptorCount = 1;

	VkDescriptorImageInfo descImageInfo920 = {.imageView = imageView920, .sampler = sampler919, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
	writeDescriptors[1].pImageInfo = &descImageInfo920;
	writeDescriptors[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writeDescriptors[1].dstSet = descriptorSet;
	writeDescriptors[1].dstBinding = 1;
	writeDescriptors[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
	writeDescriptors[1].descriptorCount = 1;
	
	vkUpdateDescriptorSets(device, descriptorWriteSets.size(), writeDescriptors.data(), 0, nullptr);
}

		
// 将包装好的DescriptorSet绑定到commandbuffer上
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);