Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update an VkDescriptorSet inside a renderPass

Lets say I have multiple meshes I want to render with different materials. I know I can use push constants for this example, but this question is more to understand how vkDescriptorset is suppose to work.

struct Material {
    vec4 color;
    vkDescriptorset descriptorSet;
    VkDescriptorBufferInfo descriptorBufferInfo;
};

I only call vkUpdateDescriptorSets for _descriptorBufferInfo after the buffer for the data has been created. Everything works fine.

I tested another solution. Instead of having one vkDescriptorset per material, I have only one for all of them. And inside the rendepass I call vkUpdateDescriptorSets for the each of the material VkDescriptorBufferInfo.

vkDescriptorset globalDescriptorSet;
struct Material {
  vec4 color;
  VkDescriptorBufferInfo descriptorBufferInfo;
};

beginCommandBuffer
beginRenderPass
for (auto &mesh : meshes) {
    ...
    writeDescriptorSets.dstSet = globalDescriptorSet;
    writeDescriptorSets.pBufferInfo = &mesh.material.descriptorBufferInfo;
    ....
    vkUpdateDescriptorSets(device, 1, &writeDescriptorSets, 0, nullptr);
    renderMesh(mesh);
}
endRenderPass
endCommandBuffer

But when I do this, it does not work. The validation layer says you have to call beginCommandBuffer before calling any of the commands, vkCmdBindDescriptorSets, vkCmdBindPipeline etc for second mesh I render.

So what is the problem here, can I not share an vkDescriptorset between multiple VkDescriptorBufferInfo, or can I not update it inside a renderPass?

like image 931
hidayat Avatar asked Jul 09 '16 18:07

hidayat


People also ask

What is the use of update function in vkwritedescriptorset?

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.

What is a vkdescriptorset?

Think of a single descriptor as a handle or pointer into a resource. That resource being a Buffer or a Image, and also holds other information, such as the size of the buffer, or the type of sampler if it’s for an image. A VkDescriptorSet is a pack of those pointers that are bound together.

How do I use a renderpass?

A Renderpass will render into a Framebuffer. The framebuffer links to the images you will render to, and it’s used when starting a renderpass to set the target images for rendering. The general use of a renderpass when encoding commands is like this: When beginning a renderpass, you set the target framebuffer, and the clear color (if available).

How to modify a vkcmddraw descriptor set?

Once a descriptor set is allocated, you need to write it to make it point into your buffers/textures. Once you bind a descriptor set and use it in a vkCmdDraw () function, you can no longer modify it unless you specify the VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag.


1 Answers

From the Vulkan specification:

The descriptor set contents bound by a call to vkCmdBindDescriptorSets may be consumed during host execution of the command, or during shader execution of the resulting draws, or any time in between. Thus, the contents must not be altered (overwritten by an update command, or freed) between when the command is recorded and when the command completes executing on the queue.

(emphasis added)

Presumably, your renderMesh call binds the descriptor set to the command buffer. From that moment forward, you are not allowed to modify that descriptor set in any way until the commands in that command buffer have completed (or the CB was destroyed).

This is why dynamic uniform/storage buffers exist. They allow you to change the base offset of a uniform/storage buffer without being considered a modification of the actual descriptor set. So you can use the same descriptor set in multiple places with a different buffer offset.

like image 130
Nicol Bolas Avatar answered Oct 05 '22 16:10

Nicol Bolas