Terminology: texture target vs texture unit vs texture image unit, etc... help!

Is a “texture target” the same thing as a “texture unit” is the same as a “texture image unit”??
And what exactly happens when we “bind” a texture to a target/unit?
And how many (binding points) are there?

Do these map to specific SW (i.e. in OpenGL driver stack) and/or HW (on GPU) components?

Similar questions for buffer and image binding/units/targets.

Is it correct to think of these “binding units” as distinct arrays/structures/physical components for each of textures vs buffer vs image, such that if I for example bind to texture binding=0 and also image binding=0, are these binding to different “places”???

“Texture unit” is short for “texture image unit”. Each texture unit has multiple targets corresponding to different types of textures (e.g. GL_TEXTURE_2D, GL_TEXTURE_3D, etc), although a shader can only access one target for each unit, determined by the type of the uniform variable used to access it (e.g. a sampler2D variable accesses the texture bound to the GL_TEXTURE_2D target of the unit whose index is stored in the variable via glUniform1i). Executing a shader with two (or more) sampler uniforms of different types referring to the same texture unit generates a GL_INVALID_OPERATION error.

Functions which use a target to identify a texture operate upon the texture bound to that target (of the active texture unit).

Since OpenGL 4.5, most functions which identify objects (e.g. textures, buffers) via a target have alternative functions which allow the object to be referenced directly via its name (handle). The alternatives have “Texture” in the name where the original has “Tex” (e.g. glTextureParameter rather than glTexParameter).

The glBindTexture reference page lists the targets to which a texture can be bound. One slight complication is that functions which upload data (glTexImage2D, glTexSubImage2D etc) have a different set of targets, as each face of a cube map is treated as a different target (although a cube map is a single texture).

Texture targets or texture units?

I believe that the individual targets were originally dedicated hardware on the original SGI systems. OpenGL 1.0 didn’t have texture objects; glBindTexture was added in 1.1. Texture units didn’t exist prior to 1.3.

Image units don’t have targets; a specific texture is bound by name (handle) to a specific image unit.

Buffers have targets but not units. Unlike textures, buffers aren’t typed. Binding an unused texture name to a target creates a texture of the corresponding type; thereafter, the texture can only be bound to the target which matches its type. Whereas any buffer can be bound to any target (or to multiple targets simultaneously). Each target affects a specific set of operations; e.g. binding a buffer to GL_PIXEL_UNPACK_BUFFER causes the buffer to be used as a source of data for texture image uploads (glTexImage2D etc), binding a buffer to GL_PIXEL_PACK_BUFFER causes it to be used as the destination for pixel data reads (glReadPixels, glGetTexImage, etc).

As with textures, 4.5 added functions which can reference buffers by name rather than a target. These have ‘NamedBuffer’ in the function name instead of ‘Buffer’, e.g. glNamedBufferData rather than glBufferData.

Yes. Texture units, image units and indexed buffer targets are distinct arrays.


Your answer

answers well which targets can be bound, but I also want to understand how many units are available to bind to, specifically, what is the largest integer I can use in the shader layout qualifier layout (binding=X) (and is the number the same for textures, images, and buffers?).

maybe I’m asking (per previous above) what determines how many units are available?

So… is it correct to think of the units as “available slots” which can be filled with a specific object type (e.g. texture or image), whereas the target identifies a specific typed object which is filling a given unit??

GLint num_units;

The minimum value for this parameter varies with the OpenGL version. In 2.1, the minimum value is 2; in 4.6 the minimum value is 80.

Note that there are also limits on the maximum number of texture units which can be accessed from each shader stage. Search for “TEXTURE_IMAGE_UNITS” in the glGet reference page.

For textures, the state can be considered an array of structures, where the array size is the number of units and the structure contains a member for each target, i.e. each texture unit can hold one texture of each type. Each image unit can only reference a single texture.

The situation with textures is a historical artifact. With modern OpenGL, there’s seldom any reason to bind multiple textures to a single texture unit. A shader cannot access multiple targets within a single texture unit.

Actually, targets themselves are largely a historical artifact; the direct state access (DSA) functions which were added in 4.5 largely eliminate the need to use them; the ARB_bindless_texture extension eliminates the need to bind textures to texture units, but that still isn’t part of any core OpenGL version.