Am I supposed to use a descriptor set per object, or per pipeline?

vkguide.dev(the older version) is mentioning

A common thing to do is to default to some high numbers, like 1000 descriptors, and when the descriptor pool is out of space, allocating a new descriptor will return with an error. Then you can just go and create a new pool to hold more descriptors.

Alternatively, a couple of times already, I have seen comments to the tune of “figure out up front your pipelines and which descriptors they need, then you can set the exact amount”.

Now I’m thinking, in the context of a game, you don’t know up front what the player is going to do, and how often they will e.g. cause a certain bullet to spawn.

Of course we can just create a new pool for the next 1000 bullets, but by that time most of the first 1000 are probably already gone again. But, I also don’t know if it’s all of them, so I can’t safely destroy the whole pool either. It just sounds… like a memory leak.

Now, regarding figuring everything out up front - that left me confused. I first thought that every e.g. bullet is supposed to have its own descriptor set. I still gave it a try to bind only one descriptor set for my pipeline and have different objects update the buffers it points to. The validation layer complained and it didn’t work. I have also seen other comments mentioning that you can’t update a descriptor after it has been added to the command buffer.

Then there’s apparently VK_KHR_push_descriptors which makes this whole question moot, but I’m not sure about its availability. I think there were also a bunch of Android devices did not support it or something, can’t find that comment again right now, though. Even if that is the best solution, though, I’m still interested in what those first two options meant, as it sounds like I’m not understanding descriptor sets correctly.

… why would another bullet need a new descriptor?

In any case, it’s rather difficult to give advice about a specific problem without knowledge of the specifics of what you’re trying to do. Not all descriptors are equal.

For example, if the implementation supports dynamic indexing of sampler arrays (not array samplers, a descriptor of samplers which has a non-one array count), then you can just put all the textures you plan to use in the same descriptor and pass an integer for the individual meshes to tell them which texture(s) to use.

But that trick doesn’t work for buffers. What does work for them is putting all of their per-object data in one big SSBO and passing a second index to tell them where to find it in that SSBO. There are multiple strategies for pulling this off.

The overall goal is not to have one descriptor set for everything. Instead, the goal is to not have the number of descriptor sets increase with the complexity of the scene. That is, adding more entities shouldn’t add more descriptor sets.

1 Like

… why would another bullet need a new descriptor?

I tried to reuse one descriptor for the whole pipeline, but when I update that with the data for the next bullet, the validation layer complains.

However if I understand you correctly, the idea is not to change where the descriptor points to - but instead to put a list of things there, and then provide an index to that to the shader, e.g. via push constant. And that would indeed make the descriptor sets one needs very predictable.

Thank you very much!