了解GL_SHADER_STORAGE_BLOCK绑定

Understanding GL_SHADER_STORAGE_BLOCK binding

本文关键字:BLOCK 绑定 STORAGE SHADER GL 了解      更新时间:2023-10-16

在使用计算着色器时,我看到大多数示例只是创建了GL_SHADER_STORAGE_BUFFERS,就像普通缓冲区一样:

glGenBuffers, glBindBuffer, glBufferData

然后它们是这样使用的:

    glUseProgram(computeShader);
    glBindBufferRange(GL_SHADER_STORAGE_BUFFER, **3**, bufferA, 0, bufferSize);
    glBindBufferRange(GL_SHADER_STORAGE_BUFFER, **4**, bufferB, 0, bufferSize);
    glDispatchCompute(computeShader);

在计算着色器中,缓冲区声明如下:

layout ( **binding = 3** ) buffer
buffer1
{
vec4    data1[];
};
layout ( **binding = 4** ) buffer
buffer2
{
vec4    data2[];
};

然后我得到了一些建议,在初始化后我应该做这样的事情:

GLuint index = glGetProgramResourceIndex(computeShader, GL_SHADER_STORAGE_BLOCK, "buffer1");
    glShaderStorageBlockBinding(shader, index, index);

为什么这是必要的?

它有什么用途,因为 glBindBufferRange 需要 layout(binding = x) 指定的索引?

在这种情况下,它没有任何目的。您已经在着色器中显式设置了绑定 - 但如果查询着色器存储块的索引,也可以手动设置绑定。您可能希望在加载时更改它,而不是将其硬编码到着色器中,因为着色器存储缓冲区对象可以使用全局绑定点共享,与统一缓冲区对象非常相似。

事实上,它们与UBO非常相似,甚至几乎相同的API。真正的区别在于您可以:

  1. 在着色器中写入它们(如果这样做,最好使用内存屏障)
  2. 使用更大的存储(最低 16 MiB)
  3. 具有可变长度。

当引入 UBO 时,ARB_shading_language_420pack (给出 layout (binding = ...) ) 尚未创建;这可能就是为什么您看到明确绑定 SSB 索引的建议的原因。