What does vkUpdateDescriptorSets exactly do?

I am trying to understand this API function: vkUpdateDescriptorSets.

void vkUpdateDescriptorSets(
VkDevice device,
uint32_t descriptorWriteCount,
const VkWriteDescriptorSet* pDescriptorWrites,
uint32_t descriptorCopyCount,
const VkCopyDescriptorSet* pDescriptorCopies);

I know it is trying to update the contents of a descriptor set object. But what exactly is happening, and, how the following APIs calls used the result? Most other functions do something explicitly, e.g., creating an object or binding resource, but this one seems update nothing: the content in pDescriptorWrites do not have changes.

So Vulkan driver has to internally keep track/update the descriptor set object?

Sorry for the dumb question.

1 Like

… yes. That’s what a VkDescriptorSet object is: a descriptor set.

Descriptor sets contain resources (buffers/images) used by pipelines. The update function is used to set which resources are used by a descriptor set. That’s what the pDescriptorWrites array contains. Each VkWriteDescriptorSet is a struct that contains a VkDescriptorSet object, a descriptor binding within that set to write to, and the resource(s) to attach to that descriptor binding.

The main thing to remember about this function is that it is not recorded into a command buffer; it executes immediately. So if the descriptor set(s) being modified are in use by a command buffer that’s being executed in a queue, then you have a race condition and undefined behavior. So you cannot modify a descriptor set unless you know that the GPU is finished with it.

1 Like

Thanks, this is helpful. I think I understand it now. This function call is to bind “dstSet” from the VkWriteDescriptor with the resource created, and dstSet is later bound with pipeline layout using the function call vkCmdBindDescriptorSets.

typedef struct VkWriteDescriptorSet {
VkStructureType sType;
const void* pNext;
VkDescriptorSet dstSet;
uint32_t dstBinding;
uint32_t dstArrayElement;
uint32_t descriptorCount;
VkDescriptorType descriptorType;
const VkDescriptorImageInfo* pImageInfo;
const VkDescriptorBufferInfo* pBufferInfo;
const VkBufferView* pTexelBufferView;
} VkWriteDescriptorSet;

vkCmdBindDescriptorSets
(
VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout layout,
uint32_t frstSet,
uint32_t descriptorSetCount,
const VkDescriptorSet* pDescriptorSets,
uint32_t dynamicOffsetCount,
const uint32_t* pDynamicOffsets);