I'm using a shader toolchain where I start with GLSL, compile it to SPIRV, optimize the SPIRV, and then use spirv-cross to generate optimized GLSL. This is working well for the most part.
However, I have a mechanism whereby user generate snippets can be injected into some fragment shaders via text replacement. When this happens, the original un-optimized GLSL is used since the markers for text replacement can't survive the passage through SPIRV.
However, I've discovered that in some cases the optimized vertex shader and the customized fragment shader will both compile, but the program won't link, instead giving the following error:
WARNING: warning(#276) Symbol "_normal" usage doesn't match between two stages
ERROR: error(#277) Symbol "_16" usage doesn't match between two stages
The optimized vertex shader and the optimized fragment shader link. The unoptimized versions of both links. Even the unoptimized vertex shader and the optimized fragment shader links.
I've narrowed down the issue to the following declaration, which appears in the fragment shader
struct TransformCamera {
mat4 _view;
mat4 _viewInverse;
mat4 _projectionViewUntranslated;
mat4 _projection;
mat4 _projectionInverse;
vec4 _viewport;
vec4 _stereoInfo;
};
layout(std140, binding=15) uniform transformCameraBuffer {
TransformCamera _camera;
};
In the optimized versions of shaders where the entire UBO isn't optimized away as unused, the declaration becomes
layout(binding = 15, std140) uniform transformCameraBuffer
{
TransformCamera _camera;
} _16;
If I manually modify the unoptimized fragment shader to use a similar mechanism to name the UBO, the link error goes away (regardless of what I name the UBO) so for instance, the following change to the fragment shader compiles and links successfully.
layout(std140, binding=15) uniform transformCameraBuffer {
TransformCamera _camera;
} _foo;
I can obviously work around the issue, but I don't understand how the different syntax for the UBO declaration completely breaks the link phase of my program. Can anyone provide some insight?
Also, if something in the glslangValidator
-> spirv-opt
-> spirv-cross
is changing the link interface for my shader, should I consider that a bug and report it?