Reputation: 14308
If I want to have one big array of descriptors for sampled images, and index into them. The descriptor layout looks like:
binding = 0;
descriptorCount = 8192;
descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
This means much less binding of descriptors, everything is indexed with information passed to a shader or read from a storage buffer. The problem is in updating the entries this image table/descriptors. Let's just say I issue a draw call that reads from this descriptor array from range [0 - 16]. The draw call is still being processed, and I want to update descriptor array element [28]. No previous commands are using element [28]. Is my understanding correct that this is illegal/undefined because you are NOT ALLOWED to update a descriptor set (the entire set) if it's still being used? Does this mean every time I want to update an element in the descriptor array I need to allocate a new descriptor? If I have to wait for the command buffer to be finished with using that descriptor set to update the descriptor then it's likely I'll have to wait on a fence, because descriptor updates are immediate.
This system of having one large descriptor array when draw calls simply index into the large array to get the right texture seems ideal as you don't bind descriptors as much, but I want to know whether updating it like this is illegal/undefined.
Upvotes: 4
Views: 585
Reputation: 474266
As with many things, this is covered by the descriptor indexing feature. If this feature is not available, then you're out of luck.
With descriptor indexing, the VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT
flag does exactly what it says. It allows you to update unused descriptors while a command buffer the descriptor is bound to is pending.
What "unused" means depends on a separate flag. If VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
is set, then "unused" refers to any descriptor which is not "dynamically used". That is, the rendering command will not access it based on any of the data used by that rendering command. If this bit is set, then "unused" refers to any descriptor which is "statically used". And "statically used" is rather more broad: if your SPIR-V has any instruction that accesses the OpVariable
containing the descriptor at all, then it is considered "static use".
And yes, since an arrayed descriptor is a single OpVariable
, unless you use the partially bound bit, you cannot use the array at all if you want to modify even part of it. But then again, the partially bound bit also is what makes it possible to have descriptors in the array that do not have valid values. So you probably already have that anyway if you're trying to do this sort of thing at all.
These flags are part of the descriptor set layout's creation info (using an extension structure).
Upvotes: 4