Vulkan 专业常量数组

Vulkan Array of Specialization Constants

是否可以有一个专门化常量数组,使 glsl 代码看起来类似于以下内容:

layout(constant_id = 0) const vec2 arr[2] = vec2[] (
    vec2(2.0f, 2.0f),
    vec2(4.0f, 4.0f)
);

或者,或者:

layout(constant_id = 0) const float arr[4] = float[] (
    2.0f, 2.0f,
    4.0f, 4.0f
);

据我所知,可以使用的专业化常量的数量没有限制,所以感觉很奇怪,这是不可能的,但是当我尝试上述操作时,SPIR-V 编译器通知我'constant_id' 只能应用于标量。目前我正在使用统一缓冲区来提供数据,但我想消除后备缓冲区和在绘制之前绑定缓冲区的需要,并允许系统在可能的情况下在管道创建期间优化代码。

而 Vulkan 风格的 GLSL requires that specialization constants are scalars, SPIR-V itself is not so restrictive。您可以声明一个特化常量数组,就像您可以声明一个非特化常量数组一样。后者在提供专业化常量时有效地成为前者。 Vulkan 中用于特化常量的接口承认被特化的不同常量具有不同大小的可能性,因此从 API 的角度来看,它们的数组是有效的。

但是只要您坚持使用 GLSL,就必须忍受它的限制。至少,就SPIR-V一代而言。

但是,如果您愿意在生成 SPIR-V 后对它进行一些手术,您可以构建您需要的东西。给定相关数组的名称,您可以找到与该数组名称匹配的 OpName。一旦找到它,就可以找到 OpName 操作码指定的 ResultID(每个 SPIR-V 操作码都有一个)。该操作码应该是 OpConstantComposite.

您需要做的就是将此 OpConstantComposite 操作码转换为 OpSpecConstantComposite。这两个代码使用相同的参数等等,因此您只需将操作码换成另一个。