2
votes

In the chapter 'Descriptor Set Binding' in the Vulkan spec the following statement is made:

A compatible descriptor set must be bound for all set numbers that any shaders in a pipeline access, at the time that a draw or dispatch command is recorded to execute using that pipeline.

Where is 'compatible descriptor' defined? I haven't found the definition in the spec. I wonder whether a descriptor set must match the set layout in the shader exactly or whether the descriptor set is allowed to have a resource bound to a binding point which does not exist in the shader.

The reason for this question is the following: assume I have two shaders which are almost identical (consider them 'variations' of a template shader), they have the same layouts, except one of them doesn't use one particular binding point (i.e. this could be a 'fast path', derived from the generic path by an #ifdef, resulting into one binding point being optimized away). Assume I have two draw calls, the first using one shader and the second using the other, and assume the resources required are identical, except that there is an additional resource for that one shader which has that special binding point. Also assume that I use the same descriptor set layout which maps exactly to the one shader which has the additional binding point. In this situation I would prefer to use the same descriptor set for both shaders to reduce the number of updates/binds of descriptor sets. The set would match the one shader exactly and it would contain a resource binding which does not exist in the other shader.

1

1 Answers

3
votes

Shaders do not have a layout; pipelines have a layout. When you build a pipeline, the VkPipelineLayout has to agree with what is defined in the shader... to some extent.

That is, the resources a shader declares have to match the resources specified by the VkPipelineLayout. But the pipeline layout can also define other resources that aren't used by the shaders in that pipeline.

The descriptor sets bound when rendering with a pipeline have to exactly match the descriptor set layouts defined for that pipeline (you can bind descriptors for sets higher than the highest set used by the pipeline, but everything up to the highest set used by the pipeline must match). So if you want to do what you're trying to do, just give both pipelines the same layout.