Reputation: 1812
I'm following the Vulkan tutorial about uniform buffers and I'm confused as to why we need to provide descriptor set layouts where all the informations they provide seem to already be in the VkWriteDescriptorSet
structures with pass in to function vkUpdateDescriptorSets
.
Why does Vulkan need both pieces of information and not just what we provide through vkUpdateDescriptorSets
?
From the tutorial's code:
VkWriteDescriptorSet descriptorWrite{};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.dstSet = descriptorSets[i];
descriptorWrite.dstBinding = 0;
descriptorWrite.dstArrayElement = 0;
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrite.descriptorCount = 1;
descriptorWrite.pBufferInfo = &bufferInfo;
void createDescriptorSetLayout() {
VkDescriptorSetLayoutBinding uboLayoutBinding{};
uboLayoutBinding.binding = 0;
uboLayoutBinding.descriptorCount = 1;
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding.pImmutableSamplers = nullptr;
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = 1;
layoutInfo.pBindings = &uboLayoutBinding;
if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor set layout!");
}
}
Upvotes: 1
Views: 1102
Reputation: 474536
You need a descriptor set layout before you write to a descriptor set for the same reason you need a class before you can instantiate it. You can't do A a;
for some type A
before you define what A
is. VkWriteDescriptorSet
is like doing a.x = whatever
; it doesn't make sense until you know what a
is, and that requires having the class definition for A
.
Descriptor set layouts define what a descriptor set looks like. It specifies all of the things that go into one. vkAllocateDescriptorSets
is how you create an instance of a descriptor set layout (in our analogy, it's A a;
, with the set being a
). VkWriteDescriptorSet
is how you provide the data that goes into a descriptor set (in our analogy, it's like a.x = whatever;
, only potentially for multiple members).
VkWriteDescrptorSet
has a lot of data that is redundantly specified in the descriptor set layout so that the implementation does not have to store the set layout as raw data.
Let's say that binding 2 in a descriptor set is a UBO of length X. And you want to attach a buffer range to that UBO descriptor. To do that, the implementation may need to know that it is a UBO descriptor and what its length is. If it does need to know that, then it would also need to store that information inside the descriptor set.
That forces the implementation to store extra data that's only useful for writing to the descriptor. If that descriptor is only set once and never again or otherwise modified infrequently (as descriptors often are), the implementation has to keep a bunch of information around for no reason.
So Vulkan makes you decide whether to keep the information around or not.
Upvotes: 7