用于数组大小的专业化常量

时间:2018-09-05 18:06:45

标签: opengl glsl spir-v

我正在尝试使用SPIR-V 专业化常数来定义统一块中数组的大小。

#version 460 core

layout(constant_id = 0) const uint count = 0;

layout(binding = 0) uniform Uniform
{
    vec4 foo[count];
    uint bar[count];
};

void main() {}

在着色器中声明为count = 0时,编译失败并显示为:

array size must be a positive integer

使用count = 1和5的特殊化,可以编译代码,但是在运行时链接失败,并出现别名别名:

error: different uniforms (named Uniform.foo[4] and Uniform.bar[3]) sharing the same offset within a uniform block (named Uniform) between shaders
error: different uniforms (named Uniform.foo[3] and Uniform.bar[2]) sharing the same offset within a uniform block (named Uniform) between shaders
error: different uniforms (named Uniform.foo[2] and Uniform.bar[1]) sharing the same offset within a uniform block (named Uniform) between shaders
error: different uniforms (named Uniform.foo[1] and Uniform.bar[0]) sharing the same offset within a uniform block (named Uniform) between shaders

在专业化期间,统一块的布局(每个成员的偏移)似乎没有受到影响,因此foobar重叠。

显式偏移量也不起作用,并导致相同的链接错误:

layout(binding = 0, std140) uniform Uniform
{
    layout(offset = 0) vec4 foo[count];
    layout(offset = count) uint bar[count];
};

这是预期的行为吗?忽视了? 可以使用专业化常量来定义数组的大小吗?

1 个答案:

答案 0 :(得分:3)

这是ARB_spir_v的古怪之处。来自the extension specification

  

块内的数组可以使用特殊化常量来调整大小,但是该块将具有静态布局。更改专用尺寸将不会重新布局图块。在没有显式偏移的情况下,布局将基于数组的默认大小。

由于默认大小为0,因此块中的结构将被布局为数组大小为零。

基本上,您可以使用特殊化常量使数组比默认数组短,但不能使它们比 longer 长。而且即使您将它们缩短,它们仍然会占用默认空间。

因此,实际上,在块数组长度中使用特殊化常数只是将数组声明为默认值作为其长度,然后用特殊化常数/表达式替换使用name.length()的地方的简便方法。纯粹是语法糖。