【问题标题】:OpenGL Uniform Buffer std140 layout, a driver bug or did I misunderstand the specification?OpenGL 统一缓冲区 std140 布局、驱动程序错误还是我误解了规范?
【发布时间】:2011-11-19 01:42:15
【问题描述】:

OpenGL 规范的谎言(或者这是一个错误?)...参考 std140 的布局,共享统一缓冲区,它指出:

"表 L-1 中显示的规则集被 GLSL 编译器用于 std140 限定的统一块中的布局成员。的偏移量 块中的成员根据 块中的先前成员(在变量之前声明的那些 问题)和起始偏移量。第一个的起始偏移量 成员始终为零。

标量变量类型 (bool, int, uint, float) - 标量的大小 基本机器类型”

(http://www.opengl-redbook.com/appendices/AppL.pdf)

因此,有了这些信息,我在我的着色器中设置了一个统一块,看起来像这样:

// Spotlight.

layout (std140) uniform Spotlight
{
    float Light_Intensity;
    vec4  Light_Ambient;
    vec3  Light_Position;   
};

... 只是发现它不适用于我在 CPU 端设置的后续 std140 布局。也就是说,前 4 个字节是浮点数(GLfloat 的机器标量类型的大小),接下来的 16 个字节是 vec4,接下来的 12 个字节是 vec3(考虑到规则,最后剩下 4 个字节vec3 确实是 vec4)。

当我更改 CPU 端以将浮点数指定为与 vec4 相同的大小(即 16 字节)并在此假设下做我的偏移量和缓冲区大小时,着色器按预期工作。

所以,要么是规范错误,要么我误解了“标量”在这种情况下的含义,或者 ATI 存在驱动程序错误。谁能解开这个谜团?

【问题讨论】:

    标签: opengl uniform


    【解决方案1】:

    您链接到的那个 PDF 不是OpenGL specification。我不知道你从哪里得到它,但这肯定不是完整的规则列表。始终检查您的来源;该规范并不像许多人声称的那样难以理解。

    是的,基本类型变量的大小与基本机器类型的大小相同(即:4字节)。但是大小本身并不能决定变量的位置

    每种类型都有一个基本对齐方式,无论该类型在统一块中的哪个位置找到,它的总字节偏移必须符合该对齐方式。 vec4 的基本对齐方式是 4 * 其基本类型的对齐方式(即:float)。所以vec4 的基本对齐是 16。

    因为Light_Intensity 在 4 个字节后结束,编译器必须插入 12 个字节的填充,因为Light_Ambient 不能位于 4 字节边界上。它必须在 16 字节的边界上,因此编译器使用 12 字节的空白空间。

    ATI 确实存在一些围绕 std140 布局的驱动程序错误,但这不是其中之一。

    作为一般规则,我喜欢在我的结构中显式地添加填充,并且我避免使用vec3(因为它具有 16 字节对齐)。这样做通常会减少编译器错误以及对事情的去向和实际占用多少空间的意外误解。

    【讨论】:

    • "……规范并不像许多人声称的那样难以理解。"非常真实。大约 12 年前我迷上了 OpenGL,从 RedBook 学习,然后是第二版,我只通过阅读规范来跟踪所有进一步的发展。
    • 好的,我假设基本对齐为 0,如所述(!)整个结构,而不是结构的单个组件。所以它现在起作用的事实是有道理的。
    • 实际上,我链接的表格似乎具有误导性,因为它指定了“偏移”,而实际上它的意思是“对齐”。
    猜你喜欢
    • 2012-06-02
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多