Contents

Storage

When creating a regular texture, the user calls glGenTextures​, binds the texture object to a particular texture type glBindTexture​, and then calls glTexImage* one or more times to create the storage for the data. Creating buffer textures is very similar.

glGenTextures​ is still used to create the texture object. And glBindTexture​ is still used to bind the texture. For buffer textures, the texture is bound to the GL_TEXTURE_BUFFER target. Creating the storage for the buffer object is the main difference.

Buffer textures are defined by the fact that the storage for the texels comes directly from a buffer object. Therefore, glTexImage calls are not appropriate for buffer textures; calling any of the gl*Image functions on the GL_TEXTURE_BUFFER will result in an error.

Instead of creating storage for a buffer texture, the user associates a buffer texture with an already existing buffer object. This association is made by binding the buffer texture to the GL_TEXTURE_BUFFER target and then calling this function:

The target​ parameter can only be GL_TEXTURE_BUFFER. The internalFormat​ is the Image Format describing how the pixel data is stored in the buffer object. The buffer​ is a previously created buffer object. 0 can be used to detach a buffer from a buffer texture.

The buffer object must have been created before this call. The buffer object target GL_TEXTURE_BUFFER can be used as a bind point for creating and modifying such buffer objects, but as stated in the Buffer Object article, this is not required (though it is encouraged).

Note that, while this attaches the entire buffer object's storage to the texture, the texture can only access up to GL_MAX_TEXTURE_BUFFER_SIZE texels. Any storage beyond this is inaccessible.

Buffer texture range

The above method binds the entire buffer object; the shader can access any value stored in the buffer. While a texture certainly can choose to restrict itself from accessing outside of a certain range, it requires the shader to be specially written for this. Also, it means trusting the shader to not do something illegal.

If you want to restrict a buffer texture's storage to only a range of a buffer, you must use this function:

The offset​ specifies a byte offset from the beginning of the buffer. It must be aligned to GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT. size​ is the byte size of the valid range. Note that the useable count of actually accessible elements depends on the format; half-pixels and such are inaccessible.

Image formats

Internal Format

Base Type

Count

Norm

Components

GL_R8

ubyte

1

YES

R

0

0

1

GL_R16

ushort

1

YES

R

0

0

1

GL_R16F

half

1

NO

R

0

0

1

GL_R32F

float

1

NO

R

0

0

1

GL_R8I

byte

1

NO

R

0

0

1

GL_R16I

short

1

NO

R

0

0

1

GL_R32I

int

1

NO

R

0

0

1

GL_R8UI

ubyte

1

NO

R

0

0

1

GL_R16UI

ushort

1

NO

R

0

0

1

GL_R32UI

uint

1

NO

R

0

0

1

GL_RG8

ubyte

2

YES

R

G

0

1

GL_RG16

ushort

2

YES

R

G

0

1

GL_RG16F

half

2

NO

R

G

0

1

GL_RG32F

float

2

NO

R

G

0

1

GL_RG8I

byte

2

NO

R

G

0

1

GL_RG16I

short

2

NO

R

G

0

1

GL_RG32I

int

2

NO

R

G

0

1

GL_RG8UI

ubyte

2

NO

R

G

0

1

GL_RG16UI

ushort

2

NO

R

G

0

1

GL_RG32UI

uint

2

NO

R

G

0

1

GL_RGB32F

float

3

NO

R

G

B

1

GL_RGB32I

int

3

NO

R

G

B

1

GL_RGB32UI

uint

3

NO

R

G

B

1

GL_RGBA8

ubyte

4

YES

R

G

B

A

GL_RGBA16

ushort

4

YES

R

G

B

A

GL_RGBA16F

half

4

NO

R

G

B

A

GL_RGBA32F

float

4

NO

R

G

B

A

GL_RGBA8I

byte

4

NO

R

G

B

A

GL_RGBA16I

short

4

NO

R

G

B

A

GL_RGBA32I

int

4

NO

R

G

B

A

GL_RGBA8UI

ubyte

4

NO

R

G

B

A

GL_RGBA16UI

ushort

4

NO

R

G

B

A

GL_RGBA32UI

uint

4

NO

R

G

B

A

Normal textures hide the internal binary representation of image data from the user. Since buffer objects are unformatted memory, this is not possible for buffer textures. Therefore, the user is somewhat limited in the Image Formats that are allowed for use with buffer textures.

To the left is a list of the specific formats that can be used. Note that the three-component formats can only be used in GL 4.0 or with ARB_texture_buffer_object_rgb32.

The byte-order for each component is native for the CPU platform in use. So if the user's code is running on a little-endian, then the floats, 32-bit integers, or 16-bit integers are stored in little-endian order. However the order of components is always RGBA in memory, regardless of the endian order.

Texture size

Every texture has a size. For buffer textures, the size of the texture is the size of the storage of the buffer object attached to the texture, divided by the byte size of a component (based on the internal format. GL_R32F takes up 4 bytes, while GL_RGBA16 takes 8). This is clamped to the implementation-defined limit on the size of all buffer textures (see Limitations below).

Texture parameters

Access in shaders

In GLSL, buffer textures can only be accessed with the texelFetch​ function. This function takes pixel offsets into the texture rather than normalized texture coordinates. The sampler types for buffer textures are gsamplerBuffer​.

Limitations

Buffer textures have a size limit, separate from the standard one-dimensional texture size. The buffer texture size limit is typically much larger than that of one-dimensional texture. This size, in texels, is queried with the GL_MAX_TEXTURE_BUFFER_SIZE token. The smallest number this will return is 65536, and the actual value may well be a good deal larger (generally on the order of the size of GPU memory).

Buffer textures are not mip-mapped; they can only store a single image. They also cannot use any filtering. In essence, a buffer texture is simply a way for the shader to directly access a large array of data, generally larger than uniform buffer objects allow.