当一个着色器优化而另一个未优化时,为什么我的 GLSL 程序不会 link?
Why won't my GLSL program link when one shader is optimized and the other is not?
我正在使用着色器工具链,我从 GLSL 开始,将其编译为 SPIRV,优化 SPIRV,然后使用 spirv-cross 生成优化的 GLSL。这在大多数情况下运作良好。
但是,我有一种机制,可以通过文本替换将用户生成的片段注入到某些片段着色器中。发生这种情况时,将使用原始未优化的 GLSL,因为用于文本替换的标记无法通过 SPIRV。
然而,我发现在某些情况下,优化的顶点着色器和自定义的片段着色器都可以编译,但程序不会link,而是给出以下错误:
WARNING: warning(#276) Symbol "_normal" usage doesn't match between two stages
ERROR: error(#277) Symbol "_16" usage doesn't match between two stages
优化的顶点着色器和优化的片段着色器link。两个 link 的未优化版本。即使是未优化的顶点着色器和优化的片段着色器 links.
我已将问题缩小到以下声明,它出现在片段着色器中
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,link 错误就会消失(无论我如何命名 UBO)例如,以下更改片段着色器编译并 link 成功。
layout(std140, binding=15) uniform transformCameraBuffer {
TransformCamera _camera;
} _foo;
我显然可以解决这个问题,但我不明白 UBO 声明的不同语法如何完全破坏我程序的 link 阶段。谁能提供一些见解?
此外,如果 glslangValidator
-> spirv-opt
-> spirv-cross
中的某些内容正在更改我的着色器的 link 界面,我是否应该认为这是一个错误并且举报?
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
因为规范是这么说的。 GLSL 4.60 specification,第 4.3.9 节。 "Interface Blocks" 状态(强调我的):
Matched block names within a shader interface (as defined above) must match in terms of having
the same number of declarations with the same sequence of types and the same sequence of
member names, as well as having matching member-wise layout qualification (see next section).
Matched uniform or shader storage block names (but not input or output block names) must also
either all be lacking an instance name or all having an instance name, putting their members at the
same scoping level. When instance names are present on matched block names, it is allowed for the
instance names to differ; they need not match for the blocks to match. [...].
因此,如果您的顶点着色器使用实例名称,则片段着色器也必须使用实例名称。
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?
我不知道他们对程序的各个部分做了什么保证。我不会凭直觉期望您组合未优化和优化部分的工作流程至少能保证正常工作。
我正在使用着色器工具链,我从 GLSL 开始,将其编译为 SPIRV,优化 SPIRV,然后使用 spirv-cross 生成优化的 GLSL。这在大多数情况下运作良好。
但是,我有一种机制,可以通过文本替换将用户生成的片段注入到某些片段着色器中。发生这种情况时,将使用原始未优化的 GLSL,因为用于文本替换的标记无法通过 SPIRV。
然而,我发现在某些情况下,优化的顶点着色器和自定义的片段着色器都可以编译,但程序不会link,而是给出以下错误:
WARNING: warning(#276) Symbol "_normal" usage doesn't match between two stages
ERROR: error(#277) Symbol "_16" usage doesn't match between two stages
优化的顶点着色器和优化的片段着色器link。两个 link 的未优化版本。即使是未优化的顶点着色器和优化的片段着色器 links.
我已将问题缩小到以下声明,它出现在片段着色器中
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,link 错误就会消失(无论我如何命名 UBO)例如,以下更改片段着色器编译并 link 成功。
layout(std140, binding=15) uniform transformCameraBuffer {
TransformCamera _camera;
} _foo;
我显然可以解决这个问题,但我不明白 UBO 声明的不同语法如何完全破坏我程序的 link 阶段。谁能提供一些见解?
此外,如果 glslangValidator
-> spirv-opt
-> spirv-cross
中的某些内容正在更改我的着色器的 link 界面,我是否应该认为这是一个错误并且举报?
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
因为规范是这么说的。 GLSL 4.60 specification,第 4.3.9 节。 "Interface Blocks" 状态(强调我的):
Matched block names within a shader interface (as defined above) must match in terms of having the same number of declarations with the same sequence of types and the same sequence of member names, as well as having matching member-wise layout qualification (see next section). Matched uniform or shader storage block names (but not input or output block names) must also either all be lacking an instance name or all having an instance name, putting their members at the same scoping level. When instance names are present on matched block names, it is allowed for the instance names to differ; they need not match for the blocks to match. [...].
因此,如果您的顶点着色器使用实例名称,则片段着色器也必须使用实例名称。
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?
我不知道他们对程序的各个部分做了什么保证。我不会凭直觉期望您组合未优化和优化部分的工作流程至少能保证正常工作。