blob: cd7a4abfd67cc15eb1c4cba5611fa0d0e8aff5fc [file] [log] [blame]
Name
IMG_bindless_texture
Name Strings
GL_IMG_bindless_texture
Contact
Tobias Hector (tobias.hector 'at' imgtec.com)
Contributors
Contributors to the original ARB_bindless_texture
Notice
Copyright (c) 2013 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Status
Draft
Version
Last Modified Date: May 23, 2016
Author Revision: 4
Number
OpenGL ES Extension #270
Dependencies
OpenGL ES 3.1 is required.
This extension is written against the OpenGL ES Shading Language
specification, Language Version 3.10, Document Revision 3 and the
OpenGL ES 3.1 API specification.
This extension interacts with EXT/OES_gpu_shader5.
This extension interacts with EXT/OES_texture_buffer and EXT_buffer_storage.
This extension interacts with OpenGL ES 3.2
Overview
This extension allows OpenGL ES applications to access texture objects in
shaders without first binding each texture to one of a limited number of
texture image units. Using this extension, an application can query a
64-bit unsigned integer texture handle for each texture that it wants to
access and then use that handle directly in GLSL ES. This extensions
significantly reduces the amount of API and internal GL driver overhead
needed to manage resource bindings.
This extension adds no new data types to GLSL. Instead, it uses existing
sampler data types and allows them to be populated with texture handles.
This extension also permits sampler types to be used as uniform block
members as well as default uniforms. Additionally, new APIs are provided to
load values for sampler uniforms with 64-bit handle inputs. The use of
existing integer-based Uniform* APIs is still permitted, in which case the
integer specified will identify a texture image. For samplers with values
specified as texture image units, the GL implementation will translate the
unit number to an internal handle as required.
New Procedures and Functions
uint64 GetTextureHandleIMG(uint texture);
uint64 GetTextureSamplerHandleIMG(uint texture, uint sampler);
void UniformHandleui64IMG(int location, uint64 value);
void UniformHandleui64vIMG(int location, sizei count, const uint64 *value);
void ProgramUniformHandleui64IMG(uint program, int location,
uint64 value);
void ProgramUniformHandleui64vIMG(uint program, int location,
sizei count, const uint64 *values);
New Tokens
None
Additions to Chapter 5 of the OpenGL ES 3.1 API Specification, "Shared Objects
and Multiple Contexts"
Insert a new section 5.4, "Object use by GPU Handles"
GPU handles to objects are valid in all contexts in the share group that
the originating object belongs to, irrespective of whether the object
itself is shared. If the originating object for a handle is deleted or
becomes otherwise invalid, the handle becomes immediately invalid in all
contexts. Using an invalid handle can lead to undefined results,
including program termination.
Additions to Chapter 7 of the OpenGL ES 3.1 API Specification, "Variables and
Types"
Add the following sentence to Section 7.6, Uniform Variables, immediately
before the error block on page 97:
A sampler uniform will consume no more than 2 components.
Add the following commands to the list of Uniform* functions in section
7.6.1, Loading Uniform Variables in the Default Uniform Block:
void UniformHandleui64IMG(int location, uint64 value);
void UniformHandleui64vIMG(int location, sizei count,
const uint64 *value);
Delete the sentence "Only the Uniform1i{v} commands can be used to load
sampler values (see section 7.9)", and add the following paragraph:
The UniformHandleui64{v}IMG commands will load <count> 64-bit unsigned
integer handles into a uniform location corresponding to sampler types.
Only the UniformHandleui64{v}IMG and Uniform1i{v} commands can be used
to load sampler values (see section 7.9).
Add the following error condition to the list of errors for Uniform*
functions:
An INVALID_OPERATION error is generated if the UniformHandleui64{v}IMG
commands are used on a sampler variable with the "bound_sampler" layout
qualifier (see the Language specification, section 4.4.5bindless).
Add the following commands to the list of ProgramUniform* functions in
section 7.6.1, Loading Uniform Variables in the Default Uniform Block:
void ProgramUniformHandleui64IMG(uint program, int location,
uint64 value);
void ProgramUniformHandleui64vIMG(uint program, int location,
sizei count, const uint64 *values);
Edit section 7.6.2.1, "Uniform Buffer Object Storage", to add the following
rules for sampler types to the list at the beginning of p105:
* Members of sampler types are extracted from a buffer object by
reading a single 64-bit value at the specified offset.
Replace Section 7.9, Samplers, with the following, adding the ability to use
samplers in new places as well as describing the behavior of the new
UniformHandleui64{v}IMG APIs:
Samplers are special data types used by the OpenGL ES Shading Language to
identify the texture object used for each texture lookup. Sampler
variables may be used as uniforms in the default block or in user-defined
blocks.
When used as uniforms in the default block, the value of sampler
variables may be specified with either Uniform1i{v} or
UniformHandleui64{v}IMG. If a sampler uniform value is specified by
Uniform1i{v}, the value passed to Uniform1i{v} indicates a texture image
unit that will be accessed, and the value must be in the range from zero
to the implementation-dependent maximum supported number of texture image
units. If a sampler uniform value is specified by UniformHandleui64{v}IMG,
the value passed to UniformHandleui64{v}IMG directly specifies a texture
object by handle, as defined in Section 8.2bindless (Bindless Textures).
When a program is linked, all sampler uniforms are initialized to zero and
considered to be references to texture image units. When used as uniform
block members, the value of the sampler is a 64-bit unsigned integer handle
and never refers to a texture image unit.
When the value of a sampler indicates a texture image unit, the type of
the sampler identifies the target on the texture image unit. The texture
object bound to that texture image unit's target is used for any texture
accesses using that sampler. For example, a variable of type sampler2D
selects the target TEXTURE_2D on its texture image unit. Binding of
texture objects to targets is done as usual with BindTexture. Selecting
the texture image unit to bind to is done as usual with ActiveTexture.
When the value of a sampler indicates a texture handle, the target of the
texture referred to by the handle must match the type of the sampler. For
example, a variable of type sampler2D must be used in conjunction with a
handle of a texture of target TEXTURE_2D. If the value of a sampler
variable is not a valid texture handle, the results of using that sampler
during shader execution are undefined and may lead to program termination.
If the value of a sampler variable is a valid handle of a texture with a
target different from the variable type, the results of using that handle
are undefined but may not include program termination.
Sampler uniforms specified using handles do not count as using any texture
image unit, even if a texture referred to by a handle is currently bound to
one or more texture image units.
Errors
The error INVALID_VALUE is generated if a Uniform1i{v} call is used to
set a sampler uniform to a value less than zero or greater than or
equal to the value of MAX_TEXTURE_IMAGE_UNITS.
It is not allowed to have uniform variables of different sampler types
pointing to the same texture image unit within a program object. This
situation can only be detected at the next rendering command issued,
and an INVALID_OPERATION error will then be generated.
Active samplers are those samplers actually being used in a program
object. When a program is linked by LinkProgram, the GL determines
whether each sampler is active or not. There is no limit on the number of
active sampler variables that may be used by a program or by any
particular shader. However, restrictions on the use of texture image
units imposes an effective limit on the number of non-handle sampler
uniforms. Active samplers used uniforms in the default uniform block are
counted toward implementation-dependent limits on the total number of
uniform components supported by the program. Each active sampler variable
may count as two components against such limits.
Additions to Chapter 8 of the OpenGL ES 3.1 API Specification, "Textures and
Samplers"
Insert a new section 8.2bindless, Bindless Textures, after Section 8.2,
Sampler Objects:
The previous sections describe mechanisms to make texture and sampler
objects available to shaders or fixed-function fragment processing by
binding the objects to texture image units. Additionally, texture objects
may be accessed by shader using texture handles, which are 64-bit unsigned
integers identifying the state of a texture and/or sampler object. The
handle zero is reserved and will never be assigned to a valid texture
handle. To obtain a texture handle, use the commands:
uint64 GetTextureHandleIMG(uint texture);
uint64 GetTextureSamplerHandleIMG(uint texture, uint sampler);
GetTextureHandleIMG will create a texture handle using the current state of
the texture named <texture>, including any embedded sampler state.
GetTextureSamplerHandleIMG will create a texture handle using the current
non-sampler state from the texture named <texture> and the sampler state
from the sampler object <sampler>. In both cases, a 64-bit unsigned
integer handle is returned. If an error occurs, a handle of zero is
returned.
The handle for each texture or texture/sampler pair is unique; the same
handle will be returned if GetTextureHandleIMG is called multiple times
for the same texture or if GetTextureSamplerHandleIMG is called multiple
times for the same texture/sampler pair.
When a texture object is referenced by one or more texture handles, the
texture parameters of the object (Section 8.9) may not be changed. The
contents of the images in a texture object may still be updated via commands
such as TexSubImage*, CopyTexSubImage*, and CompressedTexSubImage*, and by
rendering to a framebuffer object, even if the texture object is referenced
by one or more texture handles. However, once a handle references a texture
object, texel updates via API commands are no longer implicitly
synchronised by the API. Updates to the texture will become visible to the
server after an unspecified period of time, and may occur during other
server operations - though they are guaranteed to be visible to subsequently
issued GL commands with no further action. Applications are responsible for
synchronizing access, to ensure operations have completed in the desired
order - for instance by using FenceSync (see Chapter 4 - Event Model).
[[ If EXT/OES_texture_buffer or OpenGL ES 3.2, and EXT_buffer_storage are supported ]]
If the texture object is a buffer texture, the contents of the buffer object
may still be updated by using MapBuffer* commands with the
MAP_PERSISTENT_BIT_EXT, or via the texture update commands in the same way
as other bindless textures, even if the buffer is bound to a texture while
that buffer texture object is referenced by one or more texture handles.
When a sampler object is referenced by one or more texture handles, the
sampler parameters of the object may not be changed.
Errors
An INVALID_VALUE error is generated if <texture> is zero or is not the
name of an existing texture object or if <sampler> is zero or is not the
name of an existing sampler object.
[[ If EXT/OES_texture_buffer or OpenGL ES 3.2, and EXT_buffer_storage are supported ]]
An INVALID_OPERATION error is generated if the value of <texture>'s
TEXTURE_IMMUTABLE_FORMAT is FALSE (section 8.17), or if <texture> is
a texture buffer and the values of the backing buffer's BUFFER_-
IMMUTABLE_STORAGE_EXT is FALSE, BUFFER_ACCESS_FLAGS includes
DYNAMIC_STORAGE_BIT or does not include MAP_PERSISTENT_BIT_EXT.
[[ Else ]]
An INVALID_OPERATION error is generated if the value of <texture>'s
TEXTURE_IMMUTABLE_FORMAT is FALSE (section 8.17).
[[ If EXT/OES_texture_border_clamp or OpenGL ES 3.2 are supported ]]
An INVALID_OPERATION error is generated if the border color (taken from
the embedded sampler for GetTextureHandleIMG or from the <sampler> for
GetTextureSamplerHandleIMG) is not one of the following allowed values.
If the texture's base internal format is signed or unsigned integer,
allowed values are (0,0,0,0), (0,0,0,1), (1,1,1,0), and (1,1,1,1). If
the base internal format is not integer, allowed values are
(0.0,0.0,0.0,0.0), (0.0,0.0,0.0,1.0), (1.0,1.0,1.0,0.0), and
(1.0,1.0,1.0,1.0).
Additions to Chapter 11 of the OpenGL ES 3.1 API Specification, "Programmable
Vertex Processing"
Add the following sentence to the end of the paragraph in Section 11.1.3.5,
Texture Access, beginning "All active shaders combined cannot use more than
the value of MAX_COMBINED_TEXTURE_IMAGE_UNITS...":
Samplers accessed using texture handles (section 3.9.X) are not counted
against this limit.
Modifications to The OpenGL ES 3.10 Shading Language Specification
Including the following line in a shader can be used to control the
language features described in this extension:
#extension GL_IMG_bindless_texture : <behavior>
where <behavior> is as specified in section 3.4.
New preprocessor #defines are added to the OpenGL ES Shading Language:
#define GL_IMG_bindless_texture 1
Additions to Chapter 4 of the OpenGL ES 3.1 Language Specification, "Variables
and Types"
Add the following paragraph to the end of section 4.1.7.1, Samplers:
The OpenGL ES API allows default block sampler uniforms to be assigned
values referencing either a texture image unit number or a bindless
texture handle, depending on the API function used. All other sampler
variables must be assigned a texture handle. A layout qualifier
specifies which of these is used in the program.
Remove the bullet point "sampler types are not allowed" Section 4.3.7,
Interface Blocks.
Add the following paragraph to the end of section 4.4.5, "Opaque Uniform
Layout Qualifiers":
Sampler variables declared in uniform blocks may not be qualified with
a binding, and a compile-time error will be generated if a shader
specifies this.
Insert a new section 4.4.5bindless, "Bindless Sampler Layout Qualifiers",
after section 4.4.5, "Opaque Uniform Layout Qualifiers":
Sampler types accept a uniform layout qualifier identifier controlling
whether the uniform may be used with a bindless handle:
layout-qualifier-id
bindless_sampler
bound_sampler
These modifiers control whether default-block uniforms of the
corresponding types may have their values set via both UniformHandle*
and Uniform1i (bindless_sampler) or only via Uniform1i (bound_sampler).
These layouts may be specified at global scope to control the default
behavior of uniforms of the corresponding types, e.g.
layout (bindless_sampler) uniform;
They may also be specified on a uniform variable declaration of a
corresponding type, e.g.
layout (bindless_sampler) uniform sampler2D mySampler;
If both bindless_sampler and bound_sampler are declared at global scope
in any compilation unit, a link- time error will be generated. If these
layout qualifiers are applied to other types of default block uniforms,
a compile-time error will be generated. In the absence of these
qualifiers, sampler uniforms are considered "bound". Additionally, if
GL_IMG_bindless_texture is not enabled, these uniforms are considered
"bound".
Declaring a sampler in the uniform default-block with a binding point
qualifier implicitly also declares it with "bound_sampler".
Errors
The error INVALID_OPERATION is generated by SamplerParameter* if <sampler>
identifies a sampler object referenced by one or more texture handles.
The error INVALID_OPERATION is generated by TexParameter* if <target>
identifies a texture object referenced by one or more texture handles.
The error INVALID_OPERATION is generated by {Program}UniformHandleui64{v}IMG
if the sampler or image uniform being updated has the "bound_sampler" layout
qualifier, or an explicit binding qualifier.
[[ If EXT/OES_texture_buffer or OpenGL ES 3.2, and EXT_buffer_storage are supported ]]
The error INVALID_OPERATION is generated by TexBuffer*EXT if <target>
identifies a texture object referenced by one or more texture handles.
The error INVALID_OPERATION is generated by MapBuffer* if <target>
identifies a buffer object bound to a texture that is referenced by one or
more texture handles, and access does not include MAP_PERSISTENT_BIT_EXT.
Examples
To loop through a collection of 256 textures in the OpenGL API using a
conventional GLSL shader and without calling glBindTexture, one might do:
#define NUM_TEXTURES 256
GLuint textures[NUM_TEXTURES];
GLuint64 texHandles[NUM_TEXTURES];
// Initialize the texture objects and handles.
glGenTextures(NUM_TEXTURES, textures);
for (int i = 0; i < NUM_TEXTURES; i++) {
// Initialize the texture images with glTexStorage.
// Initialize the texture parameters as required.
// Get a handle for the texture.
texHandles[i] = glGetTextureHandleIMG(textures[i]);
// At this point, it's no longer possible to modify texture parameters
// for "textures[i]". However, it's still possible to update texture
// data via glTexSubImage.
}
// Compile GLSL shader using sampler uniform <u>. The shader itself
// needs no special #extension directive as long as <u> is a uniform in
// the default partition, and doesn't declare an explicit binding point.
// Link the program, and query the location of <u>, which we will store
// in <location>.
// Render a little bit using each of the texture handles in turn.
for (int i = 0; i < NUM_TEXTURES; i++) {
// Update the single sampler uniform <u> to point at "texHandles[i]".
glUniformHandleui64IMG(location, texHandles[i]);
drawStuff();
}
The GLSL portion of this extension removes the restriction that sampler
variables must be uniforms in the default block. You can store a large
collection of samplers in a uniform block.
To use a "dictionary" of samplers in a uniform block (in combination with
either EXT_gpu_shader5, or OpenGL ES 3.2), you could use a shader like:
#version 310 es
#extension GL_IMG_bindless_texture : require
#extension GL_EXT_gpu_shader5 : require
#define NUM_TEXTURES 256
uniform int whichSampler;
in highp vec2 texCoord;
out lowp vec4 finalColor;
uniform Samplers {
sampler2D allTheSamplers[NUM_TEXTURES];
};
void main()
{
finalColor = texture(allTheSamplers[whichSampler], texCoord);
}
New State
Add new table, Bindless Texture Handles
Initial
Get Value Type Get Command Value Description Sec. Attribute
------------ ---- -------------------- ------- ------------------------- ----------- -------
- Z64 GetTextureHandleIMG n/a texture handle 8.2bindless -
or GetTextureSampler-
HandleIMG
- Z+ - n/a texture object used 8.2bindless -
- Z+ - n/a sampler object used 8.2bindless -
Issues
See original issues in ARB_bindless_texture.
(1) How does IMG_bindless_texture differ from ARB_bindless_texture?
RESOLVED:
- Bindless images are not supported.
- Bindless samplers are only supported via uniforms/uniform buffers.
- No constructors between opaque and integer types
- No residency functions
- This extension does not add dynamic indexing, as it is introduced by EXT/OES_shader_gpu5 (or OpenGL ES 3.2)
- Only immutable textures and buffers (for buffer textures) are usable with bindless handles.
- Texture uploads are considered asynchronous to usage, and must be manually synchronized with fences in order to avoid race conditions
- For buffer texture objects, the only allowed buffer update mechanism is persistent mapping
(2) Should texture uploads/copies still be allowed?
RESOLVED:
The original ARB_bindless_texture allows texture uploads, with the
expectation that the commands are still serialized relative to surrounding
draw calls.
Such an implementation would prove difficult for a tile-based
architecture; attempting to serialize resource updates between draw calls
requires significant amounts of additional overhead. Without bindless,
the driver is able to track resources to make it work as expected - which
is impossible with bindless textures.
So we've decided to remove this particular requirement, instead
saying that texture uploads and copies occur asynchronously to other
commands, and require explicit synchronisation, in order to be
completed at predictable times.
(2) Should buffer uploads/copies for buffer texture objects still be allowed?
RESOLVED:
Only persistent mapping is allowed.
Revision History
Rev. Date Author Changes
---- ---------- -------- -----------------------------------------
1 2015-08-21 thector Initial revision
2 2015-08-24 thector Fixed references to "EXT_buffer_storage", added error for TexBuffer*EXT functions
3 2015-12-04 thector Texture data uploads are now entirely asynchronous
4 2016-05-23 thector Ensured that example in spec is actually compilable