blob: 7b2611581fa8e7a7c44e82738164bcc99c26015c [file] [log] [blame]
Name
ARB_multi_bind
Name Strings
GL_ARB_multi_bind
Contact
Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)
Contributors
Jeff Bolz, NVIDIA
Frank Chen, Qualcomm
Piers Daniell, NVIDIA
Daniel Koch, NVIDIA
Jon Leech
Notice
Copyright (c) 2013 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Specification Update Policy
Khronos-approved extension specifications are updated in response to
issues and bugs prioritized by the Khronos OpenGL Working Group. For
extensions which have been promoted to a core Specification, fixes will
first appear in the latest version of that core Specification, and will
eventually be backported to the extension document. This policy is
described in more detail at
https://www.khronos.org/registry/OpenGL/docs/update_policy.php
Status
Complete. Approved by the ARB on June 3, 2013.
Ratified by the Khronos Board of Promoters on July 19, 2013.
Version
Last Modified Date: May 30, 2013
Revision: 10
Number
ARB Extension #147
Dependencies
This extension is written against the OpenGL 4.3 (Compatibility Profile)
Specification, dated August 6, 2012.
OpenGL 3.0 is required.
This extension interacts with OpenGL 3.3 and ARB_sampler_objects.
This extension interacts with OpenGL 4.3 and ARB_vertex_attrib_binding.
Overview
This extension provides a new set of commands allowing applications to
bind or unbind a set of objects in a single call, instead of requiring a
separate call for each bind or unbind operation. Using a single command
allows OpenGL implementations to amortize function call, name space
lookup, and potential locking overhead over multiple bind or unbind
operations. The rendering loops of graphics applications frequently
switch between different states, binding different sets of resources,
including texture objects, sampler objects, textures for image loads and
stores, uniform buffers, and vertex buffers; this extension provides
"multi-bind" entry points for all of these object types.
Each command in this extension includes a <first> and <count> parameter,
specifying a continguous range of binding points to update, as well as an
array of <count> object names specifying the objects to bind. Unlike
single bind commands, multi-bind commands can be used only to bind or
unbind existing objects. Passing a previously unused object name
(generated or not) results in an error and does not create a new object.
For binding points with associated data (e.g., ranges of a buffer),
separate arrays are used to pass the associated data for each binding
point. Passing zero values in the array of object names removes the
object bound to the current bounding point. Additionally, if NULL is
passed as the array of objects, objects bound to the entire range of
binding points are unbound, as though the caller passed an array of
zeroes.
New Procedures and Functions
void BindBuffersBase(enum target, uint first, sizei count,
const uint *buffers);
void BindBuffersRange(enum target, uint first, sizei count,
const uint *buffers, const intptr *offsets,
const sizeiptr *sizes);
void BindTextures(uint first, sizei count, const uint *textures);
void BindSamplers(uint first, sizei count, const uint *samplers);
void BindImageTextures(uint first, sizei count, const uint *textures);
void BindVertexBuffers(uint first, sizei count, const uint *buffers,
const intptr *offsets, const sizei *strides);
New Tokens
None.
Modifications to the OpenGL 4.3 (Compatibility Profile) Specification
Modify Section 2.3.1, Errors, p. 15
(modify third paragraph, p. 16, adding "unless otherwise noted"
qualification to the general rule that commands producing errors have no
side effects)
Table 2.3 summarizes ... if an OUT_OF_MEMORY error has occurred. In
other cases, there are no side effects unless otherwise noted; the command
which generates the error is ignored so that it has no effect on GL state
or framebuffer contents. ...
Modify Section 6.1.1, Binding Buffer Objects To Indexed Targets, p. 55
(insert immediately after the "Errors" block at the end of the section,
p. 56)
The commands
void BindBuffersBase(enum target, uint first, sizei count,
const uint *buffers);
void BindBuffersRange(enum target, uint first, sizei count,
const uint *buffers, const intptr *offsets,
const sizeiptr *sizes);
bind <count> existing buffer objects to bindings numbered <first> through
<first>+<count>-1 in the array of buffer binding points corresponding to
<target>. If <buffers> is not NULL, it specifies an array of <count>
values, each of which must be zero or the name of an existing buffer
object. For BindBuffersRange, <offsets> and <sizes> specify arrays of
<count> values indicating the range of each buffer to bind. If <buffers>
is NULL, all bindings from <first> through <first>+<count>-1 are reset
to their unbound (zero) state. In this case, the offsets and sizes
associated with the binding points are set to default values, ignoring
<offsets> and <sizes>.
BindBuffersBase is equivalent to:
for (i = 0; i < count; i++) {
if (buffers == NULL) {
glBindBufferBase(target, first + i, 0);
} else {
glBindBufferBase(target, first + i, buffers[i]);
}
}
except that the single general buffer binding corresponding to <target>
is unmodified, and that buffers will not be created if they do not
exist.
BindBuffersRange is equivalent to:
for (i = 0; i < count; i++) {
if (buffers == NULL) {
glBindBufferRange(target, first + i, 0, 0, 0);
} else {
glBindBufferRange(target, first + i, buffers[i], offsets[i],
sizes[i]);
}
}
except that the single general buffer binding corresponding to <target>
is unmodified, and that buffers will not be created if they do not
exist.
The values specified in <buffers>, <offsets>, and <sizes> will be checked
separately for each binding point. When values for a specific binding
point are invalid, the state for that binding point will be unchanged and
an error will be generated. However, state for other binding points will
still be changed if their corresponding values are valid.
Errors
An INVALID_ENUM error is generated if <target> is not one of the targets
listed above.
An INVALID_OPERATION error is generated if <first> + <count> is greater
than the number of target-specific indexed binding points, as described
in section 6.7.1.
An INVALID_OPERATION error is generated if any value in <buffers> is not
zero or the name of an existing buffer object (per binding).
An INVALID_VALUE error is generated by BindBuffersRange if any value in
<offsets> is less than zero (per binding).
An INVALID_VALUE error is generated by BindBuffersRange if any value in
<sizes> is less than or equal to zero (per binding).
An INVALID_VALUE error is generated by BindBuffersRange if any pair of
values in <offsets> and <sizes> does not respectively satisfy the
constraints described for those parameters for the specified target, as
described in section 6.7.1 (per binding).
Modify Section 8.1, Texture Objects (p. 155)
(insert after errors section, p. 156)
The command
void BindTextures(uint first, sizei count, const uint *textures);
binds <count> existing texture objects to texture image units numbered
<first> through <first>+<count>-1. If <textures> is not NULL, it
specifies an array of <count> values, each of which must be zero or the
name of an existing texture object. When an entry in <textures> is the
name of an existing texture object, that object is bound to corresponding
texture unit for the target specified when the texture object was created.
When an entry in <textures> is zero, each of the targets enumerated at the
beginning of this section is reset to its default texture for the
corresponding texture image unit. If <textures> is NULL, each target of
each affected texture image unit from <first> through <first>+<count>-1 is
reset to its default texture.
BindTextures is equivalent to
for (i = 0; i < count; i++) {
uint texture;
if (textures == NULL) {
texture = 0;
} else {
texture = textures[i];
}
ActiveTexture(TEXTURE0 + first + i);
if (texture != 0) {
enum target = /* target of texture object textures[i] */;
BindTexture(target, textures[i]);
} else {
for (target in all supported targets) {
BindTexture(target, 0);
}
}
}
except that the active texture selector retains its original value upon
completion of the command, and that textures will not be created if they
do not exist.
The values specified in <textures> will be checked separately for each
texture image unit. When a value for a specific texture image unit is
invalid, the state for that texture image unit will be unchanged and an
error will be generated. However, state for other texture image units
will still be changed if their corresponding values are valid.
Errors
An INVALID_OPERATION error is generated if <first> + <count> is greater
than the number of texture image units supported by the implementation.
An INVALID_OPERATION error is generated if any value in <textures> is
not zero or the name of an existing texture object (per binding).
Modify Section 8.2, Sampler Objects (p. 158)
(insert after errors section, p. 159)
The command
void BindSamplers(uint first, sizei count, const uint *samplers);
binds <count> existing sampler objects to texture image units numbered
<first> through <first>+<count>-1. If <samplers> is not NULL, it
specifies an array of <count> values, each of which must be zero or the
name of an existing sampler object. If <samplers> is NULL, each affected
texture image unit from <first> through <first>+<count>-1 will be reset to
have no bound sampler object.
BindSamplers is equivalent to
for (i = 0; i < count; i++) {
if (samplers == NULL) {
glBindSampler(first + i, 0);
} else {
glBindSampler(first + i, samplers[i]);
}
}
The values specified in <samplers> will be checked separately for each
texture image unit. When a value for a specific texture image unit is
invalid, the state for that texture image unit will be unchanged and an
error will be generated. However, state for other texture image units
will still be changed if their corresponding values are valid.
Errors
An INVALID_OPERATION error is generated if <first> + <count> is greater
than the number of texture image units supported by the implementation.
An INVALID_OPERATION error is generated if any value in <samplers> is
not zero or the name of an existing sampler object (per binding).
Modify Section 8.25, Texture Image Loads and Stores, p. 281
(insert before the next-to-last paragraph, p. 282, "When a shader
accesses...")
The command
void BindImageTextures(uint first, sizei count, const uint *textures);
binds <count> existing texture objects to image units numbered <first>
through <first>+<count>-1. If <textures> is not NULL, it specifies an
array of <count> values, each of which must be zero or the name of an
existing texture object. If <textures> is NULL, each affected image unit
from <first> through <first>+<count>-1 will be reset to have no bound
texture object.
When binding a non-zero texture object to an image unit, the image unit
<level>, <layered>, <layer>, and <access> parameters are set to zero,
TRUE, zero, and READ_WRITE, respectively. The image unit <format>
parameter is taken from the internal format of the texture image at level
zero of the texture object identified by <textures>. For cube map
textures, the internal format of the TEXTURE_CUBE_MAP_POSITIVE_X image of
level zero is used. For multisample, multisample array, buffer, and
rectangle textures, the internal format of the single texture level is
used.
When unbinding a texture object from an image unit, the image unit
parameters <level>, <layered>, <layer>, and <format> will be reset to
their default values of zero, FALSE, 0, and R8, respectively.
BindImageTextures is equivalent to
for (i = 0; i < count; i++) {
if (textures == NULL || textures[i] = 0) {
glBindImageTexture(first + i, 0, 0, FALSE, 0, READ_ONLY, R8);
} else {
glBindImageTexture(first + i, textures[i], 0, TRUE, 0, READ_WRITE,
lookupInternalFormat(textures[i]));
}
}
where lookupInternalFormat returns the internal format of the specified
texture object.
The values specified in <textures> will be checked separately for each
image unit. When a value for a specific image unit is invalid, the state
for that image unit will be unchanged and an error will be generated.
However, state for other image units will still be changed if their
corresponding values are valid.
Errors
An INVALID_OPERATION error is generated if <first> + <count> is greater
than the number of image units supported by the implementation.
An INVALID_OPERATION error is generated if any value in <textures> is
not zero or the name of an existing texture object (per binding).
An INVALID_OPERATION error is generated if the internal format of the
level zero texture image of any texture in <textures> is not found in
table 8.33 (per binding).
An INVALID_OPERATION error is generated if the width, height, or depth
of the level zero texture image of any texture in <textures> is zero
(per binding).
Modify Section 10.3.1, Specifying Arrays For Generic Attributes, p. 340
(insert after first errors section, p. 343)
The command
void BindVertexBuffers(uint first, sizei count, const uint *buffers,
const intptr *offsets, const sizei *strides);
binds <count> existing buffer objects to vertex buffer binding points
numbered <first> through <first>+<count>-1. If <buffers> is not NULL, it
specifies an array of <count> values, each of which must be zero or the
name of an existing buffer object. <offsets> and <strides> specify arrays
of <count> values indicating the offset of the first element and stride
between elements in each buffer, respectively. If <buffers> is NULL, each
affected vertex buffer binding point from <first> through
<first>+<count>-1 will be reset to have no bound buffer object. In this
case, the offsets and strides associated with the binding points are set
to default values, ignoring <offsets> and <strides>.
BindVertexBuffers is equivalent to
for (i = 0; i < count; i++) {
if (buffers == NULL) {
glBindVertexBuffer(first + i, 0, 0, 16);
} else {
glBindVertexBuffer(first + i, buffers[i], offsets[i], strides[i]);
}
}
except that buffers will not be created if they do not exist.
The values specified in <buffers>, <offsets>, and <strides> will be
checked separately for each vertex buffer binding point. When a value for
a specific binding point is invalid, the state for that binding point will
be unchanged and an error will be generated. However, state for other
binding points will still be changed if their corresponding values are
valid.
Errors
An INVALID_OPERATION error is generated if <first> + <count> is greater
than the value of MAX_VERTEX_ATTRIB_BINDINGS.
An INVALID_OPERATION error is generated if any value in <buffers> is not
zero or the name of an existing buffer object (per binding).
An INVALID_VALUE error is generated if any value in <offsets> or
<strides> is negative (per binding).
Modify Section 21.4.1, Commands Not Usable in Display Lists, p. 618
(add a new section below "Debug output", p. 619)
Multi-object binds: BindBuffersBase, BindBuffersRange, BindTextures,
BindSamplers, BindImageTextures, BindVertexBuffers
Additions to the AGL/EGL/GLX/WGL Specifications
None
GLX Protocol
TBD
Dependencies on OpenGL 3.3 and ARB_sampler_objects
If neither OpenGL 3.3 nor ARB_sampler_objects is supported, references to
BindSamplers should be removed.
Dependencies on OpenGL 4.3 and ARB_vertex_attrib_binding
If neither OpenGL 4.3 nor ARB_vertex_attrib_binding is supported,
references to BindVertexBuffers should be removed.
Errors
An INVALID_ENUM error is generated by BindBuffersBase or BindBuffersRange
if <target> is not one of the indexed targets for buffer bindings.
An INVALID_OPERATION error is generated by BindBuffersBase or
BindBuffersRange if <first> + <count> is greater than the number of
target-specific indexed binding points, as described in section 6.7.1.
An INVALID_OPERATION error is generated by BindBuffersBase or
BindBuffersRange if any value in <buffers> is not zero or the name of an
existing buffer object (per binding).
An INVALID_VALUE error is generated by BindBuffersRange if any value in
<offsets> is less than zero (per binding).
An INVALID_VALUE error is generated by BindBuffersRange if any value in
<sizes> is less than or equal to zero (per binding).
An INVALID_VALUE error is generated by BindBuffersRange if any pair of
values in <offsets> and <sizes> do not respectively satisfy the
constraints described for those parameters for the specified target, as
described in section 6.7.1 (per binding).
An INVALID_OPERATION error is generated by BindTextures if <first> +
<count> is greater than the number of texture image units supported by the
implementation.
An INVALID_OPERATION error is generated by BindTextures if any value in
<textures> is not zero or the name of an existing texture object (per
binding).
An INVALID_OPERATION error is generated by BindSamplers if <first> +
<count> is greater than the number of texture image units supported by the
implementation.
An INVALID_OPERATION error is generated by BindSamplers if any value in
<samplers> is not zero or the name of an existing texture object (per
binding).
An INVALID_OPERATION error is generated by BindImageTextures if <first> +
<count> is greater than the number of image units supported by the
implementation.
An INVALID_OPERATION error is generated by BindImageTextures if any value
in <textures> is not zero or the name of an existing texture object (per
binding).
An INVALID_OPERATION error is generated by BindImageTextures if the
internal format of the level zero texture image of any texture in
<textures> is not found in table 8.33 (per binding).
An INVALID_OPERATION error is generated by BindImageTextures if the width,
height, or depth of the level zero texture image of any texture in
<textures> is zero (per binding).
An INVALID_OPERATION error is generated by BindVertexBuffers if <first> +
<count> is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.
An INVALID_OPERATION error is generated by BindVertexBuffers if any value
in <buffers> is not zero or the name of an existing texture object (per
binding).
An INVALID_VALUE error is generated by BindVertexBuffers if any value in
<offsets> or <strides> is negative (per binding).
New State
None.
New Implementation Dependent State
None.
Issues
(1) Regular binding commands such as BindBuffer or BindTexture can be used
either to bind an existing object or to create and bind a new object.
Should the multi-bind commands behave similarly?
RESOLVED: No. Multi-Bind commands will only support binding existing
objects. They will generate an error if any of the provided objects
doesn't already exist.
This extension is intended to provide efficient APIs allowing
applications to bind multiple objects for rendering in a single command.
Implementations of these commands are intended to bind the objects to
consecutive binding points in a loop amortizing function call, name
space lookup, locking, and other overhead over <N> objects. Not
supporting bind-to-create reduces the number of cases that this loop
needs to handle.
Even if bind-to-create were supported, it probably wouldn't be very
useful. When bind-to-create is used in current single-bind APIs, the
binding serves two purposes -- to create the object and to bind it for
use by subsequent "update" APIs defining the state of the new object.
In a multi-Bind API, it wouldn't be possible to bind more than one of
the <N> objects for update.
Additionally, if BindTexture is used to create a texture object, the
texture type is established based on the <target> parameter (e.g.,
TEXTURE_2D). The multi-Bind API for textures doesn't include <target>
parameters, so we wouldn't know what type of texture to create.
(2) Should we provide a command binding multiple texture objects of
different targets (e.g., TEXTURE_2D and TEXTURE_3D) in a single call?
For example, should you be able to bind three 2D textures to the
TEXTURE_2D target of image units 1, 2, and 3, as well as binding two
3D textures to the TEXTURE_3D target of texture image units 0 and 4?
RESOLVED: Yes. The BindTextures() command does not take <target>
enums. Instead, the target used for each texture image unit comes from
the target used when the texture object was created.
(3) Should we support unbinding objects in a multi-bind command? If so,
how does this work for texture objects, where each texture image unit
has multiple binding points (targets)?
RESOLVED: Yes, applications can unbind objects by passing zero in the
array of object names. For textures, passing zero will unbind textures
from all texture targets.
(4) Should we provide a simple way to unbind objects from a collection of
contiguous binding points?
RESOLVED: Yes, passing a NULL pointer instead of an array of object
names does an unbind for all binding points. Basically, it's treated
like an array of zeroes.
(5) Should we support multiple bindings of buffer objects using both the
"BindBufferBase" and the "BindBufferRange" styles? If so, what name
should we use for these APIs?
RESOLVED: Yes. BindBuffersBase() is equivalent to a loop repeatedly
calling BindBufferBase(); BindBuffersRange() is equivalent to a loop
repeatedly calling BindBufferRange().
The name choice for the "plural" forms of BindBufferBase and
BindBufferRange was tricky. "BindBufferRanges" would have been a fine
choice for BindBufferRange, but using "BindBufferBases" would have been
strange since "BindBufferBase" means "bind a buffer from the base of its
storage (offset zero)". We considered "BindBuffers" as the plural for
"BindBufferBase", but decided to use "BindBuffers{Base,Range}".
(6) If we support multiple bindings using the BindBufferRange style, how
should the application specify the ranges?
RESOLVED: Applications will pass separate arrays of offsets and sizes.
Alternate options included:
* a single array where entry 2<N> specifies the offset for binding <N>
and entry 2<N>+1 specifies the size for binding <N>;
* defining a new structure type including an offset and a size, and
accepting an array of <N> structures
(7) Should we create a "multi-bind" command for specifying vertex buffer
bindings (those specified via BindVertexBuffer)?
RESOLVED: Yes.
(8) If we add a "multi-bind" command for specifying vertex buffer
bindings, should we also create a similar command for specifying
multiple vertex formats (VertexAttrib*Format) in a single call?
RESOLVED: No. The design of ARB_vertex_attrib_binding separated
vertex buffer bindings from vertex formats, expecting that many
applications will change bindings frequently but change formats
relatively infrequently. While we could create a command specifying
multiple formats at once, but it would require us to turn several format
parameters (<size>, <type>, <normalized>, <relativeoffset>) into arrays.
Additionally, mutable vertex array objects can already be used to make a
wholesale change of formats and bindings. An application using a small
number of formats with a large number of bindings could create a
separate VAO for each format, and then change bindings with the
"multi-bind" command.
(9) Should we provide a command to specify multiple image unit bindings in
a single command?
RESOLVED: Yes. We decided to support this for completeness, though the
required number of image units is relatively small (8).
(10) Should binding an array of buffer objects via BindBuffersBase or
BindBuffersRange update the generic (non-indexed) binding points for
<target>?
RESOLVED: No.
In unextended OpenGL 4.3, targets like UNIFORM_BUFFER include both an
array of indexed bindings used for shader execution as well as a generic
"non-indexed" binding point that can be used for commands such as
BufferSubData. Calling BindBufferBase or BindBufferRange updates two
binding points -- binding <index> in the array of indexed bindings as
well as the generic binding point. Updating both binding points allows
applications to bind a buffer for manipulation and update in a single
command.
For BindBuffersBase and BindBuffersRange, the caller specifies <count>
separate buffers. We have specified these commands not to update the
generic binding point. Even if we were to update the generic binding
point, we'd have to pick one arbitrarily.
(11) Typically, OpenGL specifies that if an error is generated by a
command, that command has no effect. This is somewhat unfortunate
for multi-bind commands, because it would require a first pass to
scan the entire list of bound objects for errors and then a second
pass to actually perform the bindings. Should we have different
error semantics?
RESOLVED: Yes. In this specification, when the parameters for one of
the <count> binding points are invalid, that binding point is not
updated and an error will be generated. However, other binding points
in the same command will be updated if their parameters are valid and no
other error occurs.
(12) What error should be generated if the <first> and <count> parameters
specified in multi-bind commands specify a range beyond
implementation-dependent limits?
RESOLVED: INVALID_OPERATION is typically generated when the
combination of two values is illegal. INVALID_VALUE would also be
defensible.
(13) How are the <offsets> and <sizes> parameters of BindBuffersRange used
if <buffers> is NULL?
RESOLVED: We specify that these parameters are ignored when buffers
is NULL, so that applications can unbind a range of buffers with:
BindBuffersRange(target, 0, 8, NULL, NULL, NULL);
(14) Should we provide a "multi-bind" API to attach multiple textures to
the color attachments of a framebuffer object? Should we add an API
populating all attachments at once?
RESOLVED: No. We could consider an API like:
void FramebufferColorTextures(enum target, uint first, sizei count,
const uint *textures,
const uint *levels);
One might omit the <levels> parameter, since level 0 is used most
frequently, and non-zero levels could still be handled by creating
spearate views via ARB_texture_view. If we wanted to be able to specify
the full set of attachments at once, we could have:
void FramebufferTextures(enum target, sizei count,
const uint *colorAttachments,
const uint depthAttachment,
const uint stencilAttachment);
This API effectively omits the <first> argument and always starts at
zero. The "all attachments" API could be handled in OpenGL today by
using separate framebuffer objects for each attachment combination.
However, for applications that work with various combinations of
attachments but don't already have a notion of "attachment sets" to map
to framebuffer objects, caching different attachment combinations is
somewhat unwieldy.
(15) Should we provide a multi-bind API that binds pairs of textures and
samplers to a set of consecutive texture image units?
RESOLVED: No. We could provide a command such as:
void BindTexturesSamplers(uint first, sizei count,
const uint *textures,
const uint *samplers);
that would be roughly equivalent to:
BindTextures(first, count, textures);
BindSamplers(first, count, samplers);
If we did this, we'd have to decide how it would interact with the error
semantics in issue (11). If we have an error generated because of an
invalid texture for a given unit, would the sampler state for that unit
still be updated if the sampler provided were valid? Since we chose not
to support this feature, we don't need to address this question.
(16) When binding a non-zero texture to a texture image unit, should
BindTextures implicitly unbind the textures bound to all other
targets of the unit?
RESOLVED: No.
This approach was considered to behave similarly to the proposed
behavior for binding zero in a multi-bind API, where it unbinds any
bound texture for all targets. Applications using BindTextures
exclusively would never have more than one texture bound to the targets
of a texture image unit. A driver implementation might optimize for
this behavior by having a single "primary" binding point for each
texture unit (used by this API) and then "backup" binding points for the
other targets (used by BindTexture). This API would update the
"primary" binding point but would only need to touch the "backup"
binding points if something were bound there via BindTexture. However,
BindTexture would still be available and is commonly used today, so
there would probably be little benefit.
(17) For the BindTextures API, should the <first> parameter be an unsigned
integer (0) or an enum (GL_TEXTURE0)?
RESOLVED: Use an integer unit number.
(18) The BindImageTexture API not only binds a texture to an image unit,
but also sets several additional pieces of state associated with an
image unit (level, layered or not, selected layer, and image unit
format). How should this state be set? Should we provide separate
arrays for each extra parameter?
RESOLVED: Use "default" values for each image unit. When unbinding
textures, reset the state to API defaults (level zero, non-layered,
layer zero, and R8 format). When binding textures, bind all layers of
level zero and take the format from the internal format of the texture
level being bound. Setting <layered> to TRUE in this case is not the
default state, but it seems like the best default choice for cube map or
array textures. For textures without layers, the <layered> parameter
has no effect, so this doesn't cause any problems with other targets
like TEXTURE_2D.
If an application wants to bind levels other than zero, select
individual layers of a level for array textures, or use a format
different from that of the texture, it will be necessary to do
individual bindings via BindImageTexture.
(19) If a texture bound to an image unit via BindImageTextures doesn't
have a defined texture image (i.e., width = height = 0 for 2D
textures), what internal format is associated with the binding?
UNRESOLVED: We will generate INVALID_OPERATION if there is no defined
texture image.
Note that even if a texture level has no texels defined, there is still
an <internalformat> associated with the level, which can be queried with
GetTexLevelParameter. That value could be used, but it would still have
to be checked to see if it's valid for image loads and stores.
BindImageTexture doesn't accept all possible <format> enums.
Additionally, the default internal format is profile-dependent: core
uses "RGBA", compatibility uses "1" (from OpenGL 1.0, meaning
LUMINANCE). Neither is accepted by BindImageTexture, though RGBA might
be mapped internally by a driver to an internal format like RGBA8 that
is accepted.
Given the potential confusion over the internal format for zero-sized
images and default internal formats, it's best to just not accept
textures without defined images.
(20) The BindBuffersRange and BindVertexBuffers accept arrays of "intptr"
and "sizeiptr" values, which will have different sizes on 32- and
64-bit architectures. Is there any problem here?
RESOLVED: The API is fine. Application developers will need to be
careful to use the correct data type for the arrays it passes to these
commands. If the array passed to <offsets> is an array of "int" instead
of "intptr", that code will typically work fine when compiled on 32-bit
architectures if "int" types are stored as 32-bit values. But if the
same code is compiled for a 64-bit architecture, the array will be too
small. We expect that compilers will generate warnings and/or errors
if the caller passes a pointer to the wrong type.
(21) In the compatibility profile, can multi-bind commands be included in
display lists?
RESOLVED: No.
(22) What error should be generated when one of the names passed to a
multi-bind command is not the name of an existing object?
UNRESOLVED: INVALID_OPERATION. For the core profile, as well as for
object types created since OpenGL 3.1, we have spec errors like the
following for BindTexture:
An INVALID_OPERATION error is generated if <texture> is not zero or a
name returned from a previous call to GenTextures, or if such a name
has since been deleted.
In issue (1), we decided that the multi-bind commands could not be used
to create objects, whether or not the object names had previously been
returned by commands like GenTextures. The errors we require for the
multi-bind commands are different from the BindTexture language quoted
immmediately above only in the sense that the multi-bind will
additionally throw an error if a texture name has been generated by
GenTextures but the underlying texture object hasn't yet been created.
However, the errors are similar enough that they should both throw the
same error code (INVALID_OPERATION).
Revision History
Revision 11, August 16, 2013 (Jon Leech)
- Typo fix for BindBuffers* "offsets and strides" -> "offsets and
sizes" (Bug 10685).
Revision 10, July 21, 2013 (Jon Leech)
- Specify that multibind commands are equivalent to repeated calls to
the corresponding single bind commands except that objects are not
created if they do not exist, matching issue 1. The other single
bind commands do not create objects so this clarification is not
needed for them (Bug 10486).
Revision 9, May 30, 2013 (Jon Leech)
- Fix typo for <offsets> "less than to zero" -> "less than zero". Use
"<first> *through* <first> + <count> - 1" consistently.
Revision 8, May 28, 2013
- Change the error thrown when an object name passed to a multi-bind
command doesn't yet exist from INVALID_VALUE to INVALID_OPERATION
(bug 10264).
- Disallow the use of multi-bind commands in display lists (bug 10322).
- Change the <count> parameter in multi-bind commands to use the type
"sizei" to be consistent with other GL commands accepting a <count>
parameter (bug 10323).
- Clarify that passing NULL in arguments like <buffers> only affect
bindings <first> through <first>+<count>-1 (bug 10289).
- In the errors section for multi-bind commands, clarify which errors
apply to only a single binding and which apply to the entire call (bug
10289).
- Clarify in the spec language that BindImageTextures sets <access> to
READ_WRITE for all bindings, which was already in the pseudocode (bug
10289).
- Use the term "general buffer binding" in spec language stating that
BindBuffersBase and BindBuffersRange only affect numbered binding
points (bug 10289).
- Add issues (21) and (22).
Revision 7, May 18, 2013
- Fix typo in the description of BindSamplers.
Revision 6, May 17, 2013
- Modify the pseudocode for BindTextures to add in TEXTURE0 to the
value passed to ActiveTexture, since it takes an enum and not an
integer.
Revision 5, May 10, 2013
- Define lookupInternalFormat in pseudocode example.
Revision 4, May 2, 2013
- Renamed entry points for buffer bindings from BindBuffers() and
BindBufferRanges() to BindBuffersBase() and BindBuffersRange(),
respectively.
- Add an INVALID_OPERATION error if a non-zero texture passed to
BindImageTextures() does not have a defined image array.
- Add an "unless otherwise noted" qualification to the general spec rule
that commands producing errors do not modify the GL state. Multi-bind
commands have special error behavior discussed in issue (11).
- Mark issues resolved based on previous spec reviews.
- Added issue (20).
Revision 3, April 19, 2013
- Add a BindImageTextures API to bind a collection of textures to image
units (for shader image loads/stores).
- Fix the spec to consistently use the parameter name <first> to
identify the first binding point to update.
- Add new issues.
Revision 2, January 20, 2013
- Fix various specification errors.
- Add an issue about whether we should provide a multi-bind API for
framebuffer object attachments.
Revision 1, January 18, 2013
- Initial revision.