Specialization constant for input_attachment_index

Hello community,

Is there a specific reason not to introduce input_attachment_index_id for input_attachment_index just as there is local_size_x_id etc for compute shaders local sizes?

The reason is I am writing a VK backend for an engine, which tries to merge what the engine exposes as a graphics pass into what vulkan knows as renderpass with subpasses and when the algorithm finds that it can merge many passes, sometimes there are multiple resources part of that single renderpass that in the shaders both are referred to by the same id. If I could just set the input_attachment_index via a specialization constant, that would be handy.

Currently when i create materials preruntime which use InputAttachments my generator produces 4 versions, 1 for each of sampler2D / sampler2DMS / subpassInput and subpassInputMS and for the subpassInput(MS) versions analyses the spirv for the offset of the InputAttachmentIndex so at runtime I can pick the appropriate spirv (depending on whether it was merged or not I pick sampler2D or subpassInput version and in case the resource is multisampled I use the MS versions thereof), then modify the spirv at the offset found preruntime to the index that is needed at runtime.
It works but with an input_attachment_index_id I could get rid of modifying the spirv at runtime.

Since it works one can argue that it is not VKs job to expose such functionality, but then is there a reason to expose local_size_x_id etc when I could just modify the spirv at runtime in that case, too?
I assume there is an advantage in having only a single module and producing different versions using specialization constants versus modifying the spirv at runtime and producing multiple modules?


Hm, wouldn’t it work to index the input attachment array by specialization constant?

1 Like

Thanks for the reply.
I didn’t find anything in the SPIRV spec regarding InputAttachmentIndex and specialization constants so I just tried:

#version 450
layout (constant_id = 0) const int IAIDX = 0;
layout(input_attachment_index = IAIDX, set = 0, binding = 0) uniform subpassInput g_Scene;

Which results in:

main:2: error: 'input_attachment_index' : needs a literal integer

Hence my question, but if I understand you correctly I can instead use:

#version 450
layout (constant_id = 0) const int IA_IDX = 0;
layout (constant_id = 1) const int MAX_IAS = 1;
layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput[MAX_IAS] g_Scenes;

and it increments the input_attachment_index for each element in the array? So if I adjusted the snippet to read input_attachment_index = 1 specifying MAX_IAS to 2 and IA_IDX to 0 or 1 refer to the InputAttachments at indices 1 or 2 respectively? Just to make sure I understand, because I failed to find that in the spec and that would indeed solve the problem.

That was my first thought when I read this question earlier. But I also realized that it didn’t make sense why input_attachment_index_id would need to even exist if you could just use a user-defined specialization constant.

So I found this: constant expressions in a layout block are explicitly forbidden from being specialization constants:

integer-constant-expression is defined in “Constant Expressions” as constant integral expression, with it being a compile-time error for integer-constant-expression to be a specialization constant.

Hence my question, but if I understand you correctly I can instead use:

Yes, that’s the idea.

I don’t know if you can use it and haven’t tested it.

I failed to find that in the spec and that would indeed solve the problem.

As I recall, there’s a part about input attachment index assignment, and so the array declaration should work that way.

I haven’t used much of specialization constants. I assume one can use them to index certain arrays. Not sure if it will allow you to declare that array size, but 4 seems to be always allowed I think.

Yes, you are right. Not sure how I missed it but it clearly states

If the subpass input variable is declared as an array of size N, it consumes N consecutive input attachments, starting with the index specified.

Vulkan® 1.2.211 - A Specification 3rd paragraph, 2nd sentence

Problem solved, thank you both for idea and references.