I have a uniform buffer which should be updated every frame. In order to avoid big stalls I want to create 3 buffers (by the number of my frame buffers) which should be interleaved every frame (0-1-2-0-1-2-...). But I can't understand how to create descriptors and bind them. This is how I'm doing it now:
VkDescriptorSetLayout
where I specified that I want to use a uniform buffer at binding position 0 in some shader stage.VkDescriptorPool
with a size for 3 descriptors for uniform buffers.VkDescriptorSetLayout
and I'm expecting to get one VkDescriptorSet
.VkDescriptorBufferInfo
which will be passed to VkWriteDescriptorSet
which will be passed to vkUpdateDescriptorSets
. But what about other two buffers? Where to specify them?Do I need to create 3 VkDescriptorSetLayout
- one for every frame? Next do I need to allocate and update corresponding descriptor set with a corresponding buffer? And after this do I need to create 3 different command buffers where I should specify corresponding descriptor set.
It seems it's a lot of work - the data is almost the same - all bindings, states stays the same, only the buffer changes.
All it sounds very confusing so please don't hesitate to clarify.
Descriptor Set Layouts defines the contents of a descriptor set - what types of resources (descriptors) given set contains. When You need several descriptor sets with a single uniform buffer, You can create all of these descriptor sets using the same layout (layout is only a description, a specification). This way You just tell the driver: "Hey, driver! Give me 3 descriptor sets. But all of them should be exactly the same".
But because they are created from the same layout it doesn't mean they must contain the same resource handles. All them (in Your case) must contain a uniform buffer. But what resource will be used for this uniform buffer depends on You. So each descriptor set can be updated with separate buffer.
Now when You want to use 3 buffers one after another in three consecutive frames, You can do it in several different ways:
The method 3 is probably the easiest to implement as it requires no synchronization for descriptors (only per frame-level synchronization is required if You have such). It also allows You to pre-record command buffers and it doesn't require any additional extensions to be enabled. But as You noted, it requires more resources to be created and managed.
Don't forget that You need to create a descriptor pool that is big enough to contain 3 uniform buffers but at the same You must also specify that You want to allocate 3 descriptor sets from it (one uniform buffer per descriptor set).
You can read more about descriptor sets in Intel's API without Secrets: Introduction to Vulkan - Part 6 tutorial.
As for Your questions:
Do I need to create 3 VkDescriptorSetLayout - one for every frame?
No - a single layout is enough (as soon as all descriptor sets contain the same types of resources in the same bindings.
Next do I need to allocate and update corresponding descriptor set with a corresponding buffer?
As per option 3 - yes.
And after this do I need to create 3 different command buffers where I should specify corresponding descriptor set.
It depends whether You re-record command buffers every frame or if You pre-record them up front. Usually command buffers are re-recorded each frame. But as having a single command buffer requires waiting until its submission is finished, You probably may need a set(s) of command buffers for each frame, that correspond to Your framebuffer images (and descriptor sets). So in frame 0 You use command buffer #0 (or multiple command buffers reserved for frame 0). In frame 1 You use command buffer #1 etc.
Now You can record a command buffer for a given frame and during recording You provide a descriptor set that is associated with a given frame.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With