为啥 GL_MAX_UNIFORM_BLOCK_SIZE 的值会发生变化?

Posted

技术标签:

【中文标题】为啥 GL_MAX_UNIFORM_BLOCK_SIZE 的值会发生变化?【英文标题】:Why does the value of GL_MAX_UNIFORM_BLOCK_SIZE change?为什么 GL_MAX_UNIFORM_BLOCK_SIZE 的值会发生变化? 【发布时间】:2020-04-10 11:03:47 【问题描述】:

根据khronos.org, GL_MAX_UNIFORM_BLOCK_SIZE 指统一块的基本机器单位的最大尺寸。该值必须至少为 16384。

我有一个片段着色器,我在其中声明了一个统一接口块并将一个统一缓冲区对象附加到它。

#version 460 core

layout(std140, binding=2) uniform primitives
    vec3 foo[3430];
;
...

如果我查询GL_MAX_UNIFORM_BLOCK_SIZEwith的大小:

 GLuint info;
    glGetUniformiv(shaderProgram.getShaderProgram_id(), GL_MAX_UNIFORM_BLOCK_SIZE, reinterpret_cast<GLint *>(&info));
    cout << "GL_MAX_UNIFORM_BLOCK_SIZE: " << info << endl;

我得到:GL_MAX_UNIFORM_BLOCK_SIZE:22098。没关系,但是例如:当我将数组的大小更改为 3000(而不是 3430)时,我得到 GL_MAX_UNIFORM_BLOCK_SIZE: 21956

据我所知,GL_MAX_UNIFORM_BLOCK_SIZE 应该是一个常数,具体取决于我的 GPU。那为什么在我修改数组的大小时它会改变呢?

【问题讨论】:

Don't use vec3 in UBOs. 另外,初始化你的变量。 是的,这也是一个问题。我将 glm::vec3 从 C++ 发送到 GLSL 中的 vec3。因为 glsl vec3 有 16 字节的基本对齐,所以它将下一个 vec3 的第一个元素作为前一个 vec3 的第四个元素,这实际上是一个 vec4。我在 C++ 端切换到 vec4,现在它给了我正确的顶点。但是,我不清楚当我在 glsl 中切换到 vec4 时,着色器存储中的值是错误的。据我所知,glsl vec3 和 vec4 有 16 个字节作为基本对齐。 【参考方案1】:

GL_MAX_UNIFORM_BLOCK_SIZE 可以使用glGetIntegerv 正确查询。它是由实现定义的常量,它告诉您实现定义的最大值。 glGetUniform 返回给定程序中制服的值。您可能会遇到某种 OpenGL 错误,因为 GL_MAX_UNIFORM_BLOCK_SIZE 不是有效的统一位置,因此您的整数从未被写入。所以你只是在读取未初始化的数据。

【讨论】:

以上是关于为啥 GL_MAX_UNIFORM_BLOCK_SIZE 的值会发生变化?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?