Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to use the block index as the binding point for UniformBufferObject, ShaderStorageBufferObjects, etc?

Tags:

opengl

glsl

I'm curious about the *BlockBinding argument used in several of OpenGLs buffer object related functions.

For example the uniformBlockBinding parameter in glUniformBlockBinding, storageBlockBinding​ in glShaderStorageBlockBinding, and the corresponding index parameter in glBindBufferRange and glBindBufferBase.

I know that calls to glUniformBlockBinding and glShaderStorageBlockBinding aren't necessary if binding points are set in the shaders using layout qualifiers such as:

layout (binding = 0) blockName {...}

and from testing around on my machine I've noticed three things:

1) setting binding points with glUniformBlockBinding and glShaderStorageBlockBinding override binding points set in the shader using layout qualifiers.

2) block indices returned from glGetUniformBlockIndex and glGetProgramResourceIndex are ordered 0 to n for each block of the same type. For example if the shader contains 3 uniform blocks and 2 buffer blocks the indices returned would be [0,1,2] and [0,1] respectively.

3) binding points, set either way, do not conflict across types. For example, setting a uniform block to binding = 0 and a buffer block to binding = 0 is completely safe.

With these assumptions in mind (please correct me if any aren't necessarily true and are simply coincidence), are there any reasons why I shouldn't just have my code automatically set the *BlockBinding argument to the corresponding block index and save myself the trouble of ever specifying them manually via gl*BlockBinding or with layout qualifiers.

like image 818
kbirk Avatar asked Aug 08 '14 21:08

kbirk


1 Answers

I once had the same question. After some exploration, and especially reading the authoritative source of information on GL: https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object] I'm pretty sure this is why the separation between block index and binding point.

Think of a GL render context as a port, and a glsl program object as a ship. The binding points are harbors of the port and block indices are doors to ship's storage compartments. A ship needs to dock at the port with one of its door aligned with a specific harbor to load cargo onto the ship (or the other way around). Similarly, a block index needs to be associated with a binding point for the data to be transferred between the shader's blocks and the context's buffers.

Due to this design, the block indices and binding points are independent entities. Therefore it's not safe to simply equating binding point to block index, as that may unintentionally overrides binding points (that may have been docked by other ships).

Your observations can be also explained:

  • The block indices and binding points start counting from 0 contiguously (as what you observed in (2)).
  • Each type of buffers (since they reside on the context) have a set of binding points that are separate from the other types (hence your observation 3).
  • As to your observation 1, yes, setting the association on the application side preempts the hard-coded binding in the shader.
like image 200
danielyan86129 Avatar answered Oct 03 '22 18:10

danielyan86129