【发布时间】:2012-06-02 15:08:41
【问题描述】:
我试图在 GeForce 8600 GT 上通过统一块(一切都根据 GLSL“#version 330”)将整数数组传递给片段着色器。
在我拥有的应用程序方面:
int MyArray[7102];
…
//filling, binding, etc
…
glBufferData(GL_UNIFORM_BUFFER, sizeof(MyArray), MyArray, GL_DYNAMIC_DRAW);
在我的片段着色器中,我根据块声明如下:
layout (std140) uniform myblock
{
int myarray[7102];
};
问题是glCompileShader成功后glLinkProgram返回一个错误,说不能绑定合适的存储资源。
一些额外的事实:
1) GL_MAX_UNIFORM_BLOCK_SIZE 返回值 65536
2) 如果我将元素数量减少到 4096,它可以正常工作,并且无论我使用“int”还是“ivec4”作为数组类型都没有区别。任何高于 4096 的东西都会给我同样的“存储错误”
3) 如果我使用“共享”或“打包”,一切都会正常运行
在咨询了 std140 的 GLSL 3.3 规范后,我假设对齐/填充存在问题:
“1) 如果成员是一个消耗 N 个基本机器单元的标量,则基本对齐 是 N。
...
4) 如果成员是标量或向量数组,则基对齐和数组 stride 设置为匹配单个数组元素的基本对齐方式,根据 符合规则 (1)、(2) 和 (3),并向上舍入到 vec4 的基本对齐方式。这 数组末尾可能有填充;以下成员的基本偏移量 数组向上舍入到基本对齐的下一个倍数。”
我的问题:
1) “myblock” 占用的空间是 7102*4=28408 字节的 4 倍,这是真的吗? IE。 std140 将 myarray 的每个成员扩展为 vec4,实际内存使用量为 7102*4*4=113632 字节,这是问题的原因吗?
2) 它与“共享”或“打包”一起工作的原因是因为优化消除了这些差距?
3) 可能是驱动程序错误?所有事实都表明“......并向上舍入到 vec4 的基本对齐”是原因,但很难接受像整数数组这样简单的东西在内存限制方面的效率降低了 4 倍。
4) 如果不是bug,那么在std140的情况下我应该如何组织和访问一个数组?我可以使用“ivec4”来优化数据分布,但是我不得不牺牲性能来代替简单的 x=myarray[i/4][i%4] 来引用每个 ivec4 的各个元素?还是我遗漏了什么并且有明显的解决方案?
【问题讨论】: