1

我正在使用着色器工具链,从 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内容正在更改我的着色器的链接接口,我是否应该认为这是一个错误并报告它?

4

1 回答 1

3

我显然可以解决这个问题,但我不明白 UBO 声明的不同语法如何完全破坏我的程序的链接阶段

因为规范是这样说的。GLSL 4.60 规范,第 4.3.9 节。“接口块”状态(强调我的):

着色器接口(如上定义)中匹配的块名称必须匹配具有相同数量的声明、相同的类型序列和相同的成员名称序列,以及具有匹配的成员布局限定(参见下一个部分)。 匹配的统一或着色器存储块名称(但不是输入或输出块名称)也必须都缺少实例名称或都具有实例名称,将它们的成员置于相同的范围级别。当实例名称出现在匹配的块名称上时,允许实例名称不同;他们不需要匹配块来匹配。[...]。

因此,如果您的顶点着色器使用实例名称,片段着色器也必须使用实例名称。

此外,如果glslangValidator-> spirv-opt->中的某些spirv-cross内容正在更改我的着色器的链接接口,我是否应该认为这是一个错误并报告它?

我不知道他们对程序的各个部分做了什么保证。我不会直观地期望您组合未优化和优化部分的工作流程至少可以保证工作。

于 2018-10-16T18:55:16.720 回答