vulkan pipeline layout compatibility

1.2k views Asked by At

Two pipeline layouts are defined to be “compatible for push constants” if they were created with identical push constant ranges. Two pipeline layouts are defined to be “compatible for set N” if they were created with identically defined descriptor set layouts for sets zero through N, and if they were created with identical push constant ranges.

vkCmdBindDescriptorSets causes the sets numbered [firstSet.. firstSet+descriptorSetCount-1] to use the bindings stored in pDescriptorSets[0..descriptorSetCount-1] for subsequent rendering commands (either compute or graphics, according to the pipelineBindPoint). Any bindings that were previously applied via these sets are no longer valid.

suppose there are two pipeline layout, first pipeline layout contain one set #0, second pipeline layout contain two set #0 #1。First set 0 and second set 0 are identical descriptor set layout。also they have same push constant ranges,Therefore as distribution above, both pipeline layout’s set #0 are compatible?

// create set 0
...

VkDescriptorSetLayout setLayout0;
...
vkCreateDescriptorSetLayout(logicalDevice,
                            &layoutInfo,
                            nullptr,
                            &setLayout0);
...
VkDescriptorSet set0; 
VkDescriptorSetAllocateInfo allocInfo0 = {};
allocInfo0.descriptorSetCount = 1;
allocInfo0.pSetLayouts = &setLayout0;
...
vkAllocateDescriptorSets(logicalDevice,
                         &allocInfo0,
                         &set0);
...

// create first pipeline layout 
VkPipelineLayoutCreateInfo firstPipelineLayoutInfo = {};
firstPipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
firstPipelineLayoutInfo.setLayoutCount = 1;
firstPipelineLayoutInfo.pSetLayouts = &setLayout0;                           // <--- use set0


VkPipelineLayout firstPiplineLayout;
vkCreatePipelineLayout(logicalDevice,
                       &firstPipelineLayoutInfo,
                       nullptr,
                       &firstPiplineLayout);


// create set 1
...

VkDescriptorSetLayout setLayout1;
...
vkCreateDescriptorSetLayout(logicalDevice,
                            &layoutInfo,
                            nullptr,
                            &setLayout1);
...
VkDescriptorSet set1; 
VkDescriptorSetAllocateInfo allocInfo1 = {};
allocInfo1.descriptorSetCount = 1;
allocInfo1.pSetLayouts = &setLayout1;
...
vkAllocateDescriptorSets(logicalDevice,
                         &allocInfo1,
                         &set1);
...

// create second pipeline layout 
array<VkDescriptorSetLayout, 2> setLayout0And1 = {setLayout0, setLayout1} // <---use set0 set1

VkPipelineLayoutCreateInfo secondPipelineLayoutInfo = {};
secondPipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
secondPipelineLayoutInfo.setLayoutCount = 2;
secondPipelineLayoutInfo.pSetLayouts = &setLayout0And1;

VkPipelineLayout secondPiplineLayout;
vkCreatePipelineLayout(logicDevice,
                       &secondPipelineLayoutInfo,
                       nullptr,
                       &secondPiplineLayout);

// create pipeline
VkGraphicsPipelineCreateInfo pipelineInfo = {};
...
pipelineInfo.layout = secondPiplineLayout;

VkPipeline pipeline;
vkCreateGraphicsPipelines(logicDevice,
                          VK_NULL_HANDLE,
                          1,
                          &pipelineInfo,
                          nullptr,
                          &pipeline);

After that, call vkCmdBindDescriptorSets to bind when draw.

...
vkCmdBindDescriptorSets(commandBuffer,
                        VK_PIPELINE_BIND_POINT_GRAPHICS,
                        firstPiplineLayout,
                        0,
                        1,
                        &set0,
                        0,
                        nullptr);

// When call vkCmdBindDescriptorSets with first set > 0 then the bound descriptor sets index [0 ... firstSet-1] will remain the same.
vkCmdBindDescriptorSets(commandBuffer,
                        VK_PIPELINE_BIND_POINT_GRAPHICS,
                        secondPiplineLayout,
                        1,
                        1,
                        &set1,
                        0,
                        nullptr);

vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
...
vkCmdDrawIndexed(commandBuffer,
                 indicesCount,
                 1, 0, 0, 0);
...

After that validation layer: VkPipeline 0x42 uses set #0 but that set is not bound.

Why is there an error? Where did I get it wrong?

0

There are 0 answers