我正在使用着色器工具链,从 GLSL 开始,将其编译为 SPIRV,优化 SPIRV,然后使用 spirv-cross 生成优化的 GLSL。这在大多数情况下运作良好。
但是,我有一种机制,用户生成的片段可以通过文本替换注入到一些片段着色器中。发生这种情况时,将使用原始未优化的 GLSL,因为用于文本替换的标记无法通过 SPIRV 传输。
但是,我发现在某些情况下优化的顶点着色器和自定义的片段着色器都会编译,但程序不会链接,而是给出以下错误:
WARNING: warning(#276) Symbol "_normal" usage doesn't match between two stages
ERROR: error(#277) Symbol "_16" usage doesn't match between two stages
优化的顶点着色器和优化的片段着色器链接。两个链接的未优化版本。甚至未优化的顶点着色器和优化的片段着色器链接。
我已将问题缩小到以下声明,该声明出现在片段着色器中
struct TransformCamera {
mat4 _view;
mat4 _viewInverse;
mat4 _projectionViewUntranslated;
mat4 _projection;
mat4 _projectionInverse;
vec4 _viewport;
vec4 _stereoInfo;
};
layout(std140, binding=15) uniform transformCameraBuffer {
TransformCamera _camera;
};
在未将整个 UBO 优化为未使用的着色器的优化版本中,声明变为
layout(binding = 15, std140) uniform transformCameraBuffer
{
TransformCamera _camera;
} _16;
如果我手动修改未优化的片段着色器以使用类似的机制来命名 UBO,链接错误就会消失(不管我如何命名 UBO),例如,对片段着色器的以下更改编译并成功链接。
layout(std140, binding=15) uniform transformCameraBuffer {
TransformCamera _camera;
} _foo;
我显然可以解决这个问题,但我不明白 UBO 声明的不同语法如何完全破坏我的程序的链接阶段。谁能提供一些见解?
此外,如果glslangValidator
-> spirv-opt
->中的某些spirv-cross
内容正在更改我的着色器的链接接口,我是否应该认为这是一个错误并报告它?