| Name |
| |
| ARB_bindless_texture |
| |
| Name Strings |
| |
| GL_ARB_bindless_texture |
| |
| Contact |
| |
| Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com) |
| Pat Brown, NVIDIA Coproration (pbrown 'at' nvidia.com) |
| |
| Contributors |
| |
| Graham Sellers, AMD |
| Pierre Boudier, AMD |
| Daniel Koch, NVIDIA |
| |
| Notice |
| |
| Copyright (c) 2013 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| 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: February 13, 2017 |
| Author Revision: 5 |
| |
| Number |
| |
| ARB Extension #152 |
| |
| Dependencies |
| |
| This extension is written against the OpenGL 4.0 (Compatibility Profile) |
| and OpenGL Shading Language 4.00 Specifications. |
| |
| OpenGL 4.0 or later versions is required. |
| |
| This extension interacts with OpenGL 4.0 (Core Profile). |
| |
| This extension interacts with OpenGL 3.3 and ARB_sampler_objects. |
| |
| This extension interacts with OpenGL 4.2, ARB_shader_image_load_store, and |
| EXT_shader_image_load_store. |
| |
| This extension interacts with NV_vertex_attrib_integer_64bit. |
| |
| This extension interacts with NV_gpu_shader5. |
| |
| This extension interacts with EXT_direct_state_access. |
| |
| This extension interacts with ARB_seamless_cube_map and |
| AMD_seamless_cubemap_per_texture. |
| |
| This extension interacts with NV_gpu_program4, NV_gpu_program5, and |
| EXT_shader_image_load_store. |
| |
| This extension interacts with GLSL 4.20. |
| |
| This extension interacts with NV_bindless_texture. |
| |
| |
| Overview |
| |
| This extension allows OpenGL 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 or assembly-based |
| shaders. The ability to access textures without having to bind and/or |
| re-bind them is similar to the capability provided by the |
| NV_shader_buffer_load extension that allows shaders to access buffer |
| objects without binding them. In both cases, these extensions |
| significantly reduce the amount of API and internal GL driver overhead |
| needed to manage resource bindings. |
| |
| This extension also provides similar capability for the image load, store, |
| and atomic functionality provided by OpenGL 4.2 and the |
| ARB_shader_image_load_store and EXT_shader_image_load_store extensions, |
| where a texture can be accessed without first binding it to an image unit. |
| An image handle can be extracted from a texture object using an API with a |
| set of parameters similar to those for BindImageTextureEXT. |
| |
| This extension adds no new data types to GLSL. Instead, it uses existing |
| sampler and image data types and allows them to be populated with texture |
| and image handles. This extension does permit sampler and image data |
| types to be used in more contexts than in unextended GLSL 4.00. In |
| particular, sampler and image types may be used as shader inputs/outputs, |
| temporary variables, and uniform block members, and may be assigned to by |
| shader code. Constructors are provided to convert unsigned integer values |
| to and from sampler and image data types. Additionally, new APIs are |
| provided to load values for sampler and image 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 or image unit. For samplers and images with values specified as |
| texture image or image units, the GL implemenation will translate the unit |
| number to an internal handle as required. |
| |
| To access texture or image resources using handles, the handles must first |
| be made resident. Accessing a texture or image by handle without first |
| making it resident can result in undefined results, including program |
| termination. Since the amount of texture memory required by an |
| application may exceed the amount of memory available to the system, this |
| extension provides API calls allowing applications to manage overall |
| texture memory consumption by making a texture resident and non-resident |
| as required. |
| |
| |
| New Procedures and Functions |
| |
| uint64 GetTextureHandleARB(uint texture); |
| uint64 GetTextureSamplerHandleARB(uint texture, uint sampler); |
| |
| void MakeTextureHandleResidentARB(uint64 handle); |
| void MakeTextureHandleNonResidentARB(uint64 handle); |
| |
| uint64 GetImageHandleARB(uint texture, int level, boolean layered, |
| int layer, enum format); |
| |
| void MakeImageHandleResidentARB(uint64 handle, enum access); |
| void MakeImageHandleNonResidentARB(uint64 handle); |
| |
| void UniformHandleui64ARB(int location, uint64 value); |
| void UniformHandleui64vARB(int location, sizei count, const uint64 *value); |
| void ProgramUniformHandleui64ARB(uint program, int location, |
| uint64 value); |
| void ProgramUniformHandleui64vARB(uint program, int location, |
| sizei count, const uint64 *values); |
| |
| boolean IsTextureHandleResidentARB(uint64 handle); |
| boolean IsImageHandleResidentARB(uint64 handle); |
| |
| |
| // Inherited from NV_vertex_attrib_integer_64bit: |
| |
| void VertexAttribL1ui64ARB(uint index, uint64EXT x); |
| void VertexAttribL1ui64vARB(uint index, const uint64EXT *v); |
| void GetVertexAttribLui64vARB(uint index, enum pname, uint64EXT *params); |
| |
| |
| New Tokens |
| |
| // Inherited from NV_vertex_attrib_integer_64bit: |
| |
| Accepted by the <type> parameter of VertexAttribLPointer: |
| |
| UNSIGNED_INT64_ARB 0x140F |
| |
| |
| Additions to Chapter 2 of the OpenGL 4.0 (Compatibility Profile) Specification |
| (OpenGL Operation) |
| |
| Modify Section 2.7, Vertex Specification, p. 30 |
| |
| Replace the paragraph from NV_vertex_attrib_integer_64bit describing the |
| behavior of VertexAttribL*: |
| |
| These commands specify one, two, three or four values. Note that attribute |
| variables declared with "double" types must be loaded with |
| VertexAttribL*d{v}EXT; loading attributes with VertexAttrib*d{v} will |
| produce undefined results. Similarly, attributes declared with 64-bit |
| integer types, sampler types, or image types must be loaded with |
| VertexAttribL*{i64,ui64}{v}. |
| |
| ... |
| |
| The full set of VertexAttrib* commands specify generic attributes with |
| components one of eight data types: |
| |
| * floating-point values (VertexAttrib*), |
| * signed or unsigned integers (VertexAttribI*), |
| * double-precision floating-point values (VertexAttribL*d*), and |
| * 64-bit signed or unsigned integers, images, or samplers |
| (VertexAttribL*{i64,ui64}*). |
| |
| |
| Modify Section 2.14.3, Vertex Attributes, p. 94 |
| |
| Edit Table X.1 of NV_vertex_attrib_integer_64bit (Scalar and vector |
| vertex attribute types and VertexAttrib* commands used to set the values |
| of the corresponding generic attribute.). Change the line describing |
| VertexAttribL1ui64NV to allow it for sampler and image types. |
| |
| Data type Command |
| ------------------------------- ---------------------------------- |
| uint64_t VertexAttribL1ui64NV |
| sampler* isampler* usampler* |
| image* iimage* uimage* |
| |
| Modify Section 2.14.4, Uniform Variables, p. 97 |
| |
| (Modify second paragraph, p. 98) ... uniform components, respectively. A |
| scalar or vector uniform with double-precision or 64-bit integer |
| components will consume no more than 2n components, where n is 1 for |
| scalars, and the component count for vectors. A sampler or image uniform |
| will consume no more than two components. A link error is generated... |
| |
| |
| (Edit Table 2.15, "OpenGL Shading Language type tokens returned by |
| GetActiveUniform and GetActiveUniformsiv...", pp. 104-106. In particular, |
| add dots to the "Attrib" and "Xfb" columns for all SAMPLER and IMAGE |
| types.) |
| |
| |
| (Edit the subsection "Loading Uniform Variables In The Default Uniform |
| Block", p. 108) |
| |
| (Add the following commands to the list of uniform functions on p. 108.) |
| |
| void UniformHandleui64ARB(int location, uint64 value); |
| void UniformHandleui64vARB(int location, sizei count, |
| const uint64 *value); |
| void ProgramUniformHandleui64ARB(uint program, int location, |
| uint64 value); |
| void ProgramUniformHandleui64vARB(uint program, int location, |
| sizei count, const uint64 *values); |
| |
| (Delete the sentence: "Only the Uniform1i{v} commands can be used to load |
| sampler values (see below)." from p. 108.) |
| |
| (Insert a new paragarph after the second paragraph, p. 109) |
| |
| The UniformHandleui64{v}ARB commands will load <count> 64-bit unsigned |
| integer handles into a uniform location corresponding to sampler or image |
| variable types. Only the UniformHandleui64{v}ARB and Uniform1i{v} commands |
| can be used to load sampler and image values as described in Section |
| 2.14.6 (Samplers). |
| |
| An INVALID_OPERATION error is generated if the UniformHandleui64{v}ARB |
| commands are used on a sampler or image variable with the "bound_sampler" |
| or "bound_image" layout qualifier (see the GLSL spec Section 4.4.6). |
| |
| |
| Edit Subsection "Uniform Buffer Object Storage", p. 110: |
| |
| (Add rules for sampler and image types to the list at the beginning of |
| p. 111.) |
| |
| * Members of sampler types are extracted from a buffer object by |
| reading a single 64-bit value at the specified offset. |
| |
| * Members of image types are extracted from a buffer object by reading |
| a single 64-bit value at the specified offset. |
| |
| |
| Modify Section 2.14.6, Samplers, p. 117 |
| |
| (Replace the section with the following, adding the ability to use |
| samplers in new places as well as describing the behavior of the new |
| UniformHandleui64{v}ARB APIs.) |
| |
| Samplers are special data types used by the OpenGL Shading Language to |
| identify the texture object used for each texture lookup. Sampler |
| variables may be used as shader inputs and outputs, uniforms in the |
| default block or in user-defined blocks, or as temporaries. |
| |
| When used as uniforms in the default block, the value of sampler |
| variables may be specified with either Uniform1i{v} or |
| UniformHandleui64{v}ARB. 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. 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. If a sampler uniform value |
| is specified by UniformHandleui64{v}ARB, the value passed to |
| UniformHandleui64{v}ARB directly specifies a texture object by handle, as |
| defined in Section 3.9.X (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 shader inputs, outputs, |
| uniform block members, or temporaries, 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 or is not resident (section 3.9.X), |
| 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. |
| |
| 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. 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. |
| |
| 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 as shader inputs, shader outputs, or |
| uniforms in the default uniform block are counted toward |
| implementation-dependent limits on the total number of input, output, or |
| uniform components supported by the program. Each active sampler variable |
| may count as two components against such limits. |
| |
| |
| Modify Section 2.14.X, Images, from EXT_shader_image_load_store |
| |
| (Replace the section with the following, adding the ability to use images |
| in new places as well as describing the behavior of the new |
| UniformHandleui64{v}ARB APIs.) |
| |
| Images are special data types used in the OpenGL Shading Language to |
| identify a level of a texture to be read or written using image load, |
| store, and atomic built-in functions in the manner described in Section |
| 3.9.X of the EXT_shader_image_load_store specification. Image variables |
| may be used as shader inputs and outputs, uniforms in the default block or |
| in user-defined blocks, or as temporaries. |
| |
| When used as uniforms in the default block, the value of image variables |
| may be specified with either Uniform1i{v} or UniformHandleui64{v}ARB. If |
| an image uniform value is specified by Uniform1i{v}, the value passed to |
| Uniform1i{v} indicates an image unit that will be accessed, and the value |
| must be in the range from zero to the implementation-dependent maximum |
| supported number of image units. The error INVALID_VALUE is generated if |
| a Uniform1i{v} call is used to set an image uniform to a value less than |
| zero or greater than or equal to the value of MAX_IMAGE_UNITS_EXT. Note |
| that image units used for image variables are independent from the texture |
| image units used for sampler variables; the number of units provided by the |
| implementation may differ. Textures are bound independently and |
| separately to image and texture image units. If an image uniform value is |
| specified by UniformHandleui64{v}ARB, the value provided directly specifies |
| a texture object by handle, as defined in Section 3.9.X (Bindless |
| Textures). When a program is linked, all image uniforms are initialized |
| to zero and considered to be references to image units. When used as |
| shader inputs, outputs, uniform block members, or temporaries, the value |
| of an image variable is a 64-bit unsigned integer handle and never refers |
| to an image unit. |
| |
| The type of an image variable must match the texture target of the image |
| currently bound to the image unit or referenced by the image handle. |
| Otherwise, the results of load, store, or atomic operations using the |
| image variable are undefined (see Section 4.1.X of the OpenGL Shading |
| Language specification edits in EXT_shader_image_load_store for more |
| detail) but may not include program termination. Additionally, if the |
| value of an image variable is not a valid image handle or is not resident |
| (section 3.9.X), the results of using that image variable during shader |
| execution are undefined and may lead to program termination. |
| |
| Active image variables are those variables actually being used in a |
| program object. When a program is linked by LinkProgram, the GL |
| determines whether each image variable is active or not. There is no |
| limit on the number of active image variables that may be used by a |
| program or by any particular shader. However, the limited number of image |
| units imposes an effective limit on the number of unique non-handle image |
| variables. Active image variables used as shader inputs, shader outputs, |
| or uniforms in the default uniform block are counted toward |
| implementation-dependent limits on the total number of input, output, or |
| uniform components supported by the program. Each active image variable |
| may count as two components against such limits. |
| |
| |
| Modify Section 2.14.7, Varying Variables, p. 118 |
| |
| (modify first paragraph, p. 119) ... Each component of variables declared |
| as double-precision floating-point scalars, vectors, or matrices, as |
| 64-bit integer scalars or vectors, or as samplers or images may be counted |
| as consuming two components. |
| |
| (replace second paragraph, p. 121) For the purposes of counting the total |
| number of components to capture, each component of outputs declared as |
| double-precision floating-point scalars, vectors, or matrices, as 64-bit |
| integer scalars or vectors, or as samplers or images may be counted as |
| consuming two components. |
| |
| |
| Modify Section 2.14.8, Shader Execution, p. 122 |
| |
| (modify second paragraph, p. 126) ... against the |
| MAX_COMBINED_TEXTURE_IMAGE_UNITS limit. Samplers accessed using texture |
| handles (section 3.9.X) are not counted against this limit. |
| |
| (modify last paragraph of "Texture Access", p. 127) Using a sampler in a |
| shader will return (R,G,B,A) = (0,0,0,1) if the sampler's associated |
| texture is not complete, as defined in section 3.9.14. Textures referred |
| to by valid texture handles (section 3.9.X) will always be complete. |
| |
| |
| Additions to Chapter 3 of the OpenGL 4.0 Specification (Rasterization) |
| |
| Insert new section after Section 3.9.2, Sampler Objects, p. 257 |
| |
| Section 3.9.X, Bindless Textures |
| |
| 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 GetTextureHandleARB(uint texture); |
| uint64 GetTextureSamplerHandleARB(uint texture, uint sampler); |
| |
| GetTextureHandleARB will create a texture handle using the current state of |
| the texture named <texture>, including any embedded sampler state. |
| GetTextureSamplerHandleARB 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. The error INVALID_VALUE 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. The |
| error INVALID_OPERATION is generated if the texture object <texture> is |
| not complete (section 3.9.14). If an error occurs, a handle of zero is |
| returned. |
| |
| The error INVALID_OPERATION is generated if the border color (taken from |
| the embedded sampler for GetTextureHandleARB or from the <sampler> for |
| GetTextureSamplerHandleARB) 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). |
| |
| The handle for each texture or texture/sampler pair is unique; the same |
| handle will be returned if GetTextureHandleARB is called multiple times |
| for the same texture or if GetTextureSamplerHandleARB 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 3.9.8) may not be changed, and |
| the size and format of the images in the texture object (Section 3.9.3) |
| may not be re-specified. The error INVALID_OPERATION is generated if the |
| functions TexImage*, CopyTexImage*, CompressedTexImage*, TexBuffer*, or |
| TexParameter* are called to modify a texture object referenced by one or |
| more texture handles. 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. |
| |
| The error INVALID_OPERATION is generated by BufferData if it is called to |
| modify a buffer object bound to a buffer texture while that texture object |
| is referenced by one or more texture handles. The contents of the buffer |
| object may still be updated via buffer update commands such as |
| BufferSubData and MapBuffer*, or via the texture update commands, 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. The error |
| INVALID_OPERATION is generated when calling SamplerParameter* functions to |
| modify a sampler object referenced by one or more texture handles. |
| |
| To make a texture handle accessible to shaders for texture mapping |
| operations, a texture handle must first be made resident by calling: |
| |
| void MakeTextureHandleResidentARB(uint64 handle); |
| |
| While the texture handle is resident, it may be used in texture mapping |
| operations. If a shader attempts to perform a texture mapping operation |
| using a handle that is not resident, the results of that operation are |
| undefined and may lead to application termination. When a texture handle |
| is resident, the texture it references is also considered resident for the |
| purposes of the AreTexturesResident command. The error INVALID_OPERATION |
| is generated if <handle> is not a valid texture handle, or if <handle> is |
| already resident in the current GL context. |
| |
| A texture handle may be made inaccessible to shaders by calling: |
| |
| void MakeTextureHandleNonResidentARB(uint64 handle); |
| |
| The error INVALID_OPERATION is generated if <handle> is not a valid |
| texture handle, or if <handle> is not resident in the current GL context. |
| |
| |
| Modify Section 3.9.10, Cube Map Texture Selection, p. 291 |
| |
| (insert new paragraph before last paragraph of section, p. 293) |
| |
| When accessing cube map textures using texture handles, the seamless cube |
| map enable is ignored and treated as disabled. |
| |
| |
| Modify Section 3.9.11, Texture Minification, p. 293 |
| |
| [[Compatibility profile-only]] |
| (modify last paragraph, p. 293) ... <bias_texunit> is zero for textures |
| referred to by handle, and is otherwise the value of TEXTURE_LOD_BIAS for |
| the current texture unit (as described in section 3.9.16). ... |
| |
| |
| Add to Section 3.9.X (Texture Image Loads and Stores) of |
| EXT_shader_image_load_store: |
| |
| While texture levels may be made available to shaders by binding them to |
| image units using BindImageTextureEXT, they may also be accessed using |
| image handles. Image handles are 64-bit integers that identify a level of |
| a texture object, layer information for array and cube map textures, and |
| an associated image format. The handle zero is reserved and will never be |
| assigned to a valid image handle. The command |
| |
| uint64 GetImageHandleARB(uint texture, int level, boolean layered, |
| int layer, enum format); |
| |
| creates and returns an image handle for level <level> of the texture |
| named <texture>. If <layered> is TRUE, a handle is created for the |
| entire texture level. If <layered> is FALSE, a handle is created for |
| only the layer <layer> of the texture level. <format> specifies a |
| format used to interpret the texels of the image when used for image |
| loads, stores, and atomics, and has the same meaning as the <format> |
| parameter of BindImageTextureEXT(). A 64-bit unsigned integer handle |
| is returned if the command succeeds; otherwise, zero is returned. |
| |
| The error INVALID_VALUE is generated by GetImageHandleARB if: |
| |
| * <texture> is zero or not the name of an existing texture object; |
| |
| * the image for the texture level <level> doesn't exist (i.e., has a |
| size of zero in <texture>); or |
| |
| * <layered> is FALSE and <layer> is greater than or equal to |
| the number of layers in the image at level <level>. |
| |
| The error INVALID_OPERATION is generated by GetImageHandleARB if: |
| |
| * the texture object <texture> is not complete (section 3.9.14); |
| |
| * <layered> is TRUE and the texture is not a three-dimensional, |
| one-dimensional array, two dimensional array, cube map, or cube map |
| array texture. |
| |
| When a texture object is referenced by one or more image handles, the |
| texture parameters of the object (Section 3.9.8) may not be changed, and |
| the size and format of the images in the texture object (Section 3.9.3) |
| may not be re-specified. The error INVALID_OPERATION is generated when |
| calling TexImage*, CopyTexImage*, CompressedTexImage*, TexBuffer*, or |
| TexParameter* functions while a texture object is referenced by one or |
| more image handles. 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 image handles. |
| |
| The error INVALID_OPERATION is generated by BufferData if it is called to |
| modify a buffer object bound to a buffer texture while that texture object |
| is referenced by one or more image handles. The contents of the buffer |
| object may still be updated via buffer update commands such as |
| BufferSubData and MapBuffer*, or via the texture update commands, even if |
| the buffer is bound to a texture while that buffer texture object is |
| referenced by one or more image handles. |
| |
| The handle returned for each combination of <texture>, <level>, <layered>, |
| <layer>, and <format> is unique; the same handle will be returned if |
| GetImageHandleARB is called multiple times with the same parameters. |
| |
| To make an image handle accessible to shaders for image loads, stores, and |
| atomic operations, the handle must be made resident by calling: |
| |
| void MakeImageHandleResidentARB(uint64 handle, enum access); |
| |
| <access> specifies whether the texture bound to the image handle will be |
| treated as READ_ONLY, WRITE_ONLY, or READ_WRITE. If a shader reads from |
| an image handle made resident as WRITE_ONLY, or writes to an image handle |
| made resident as READ_ONLY, the results of that shader operation are |
| undefined and may lead to application termination. The error |
| INVALID_OPERATION is generated if <handle> is not a valid image handle, or |
| if <handle> is already resident in the current GL context. |
| |
| While the image handle is resident, it may be used in image load, store, |
| and atomic operations. If a shader attempts to perform an image operation |
| using a handle that is not resident, the results of that operation are |
| undefined and may lead to application termination. When an image handle |
| is resident, the texture it references is not necessarily considered |
| resident for the purposes of the AreTexturesResident command. |
| |
| An image handle may be made inaccessible to shaders by calling: |
| |
| void MakeImageHandleNonResidentARB(uint64 handle); |
| |
| The error INVALID_OPERATION is generated if <handle> is not a valid image |
| handle, or if <handle> is not resident in the current GL context. |
| |
| |
| Modify Section 3.12.2, Shader Execution, p. 323 |
| |
| (replace second-to-last paragraph of "Texture Access", p. 324) Using a |
| sampler in a shader will return (R,G,B,A) = (0,0,0,1) if the sampler's |
| associated texture is not complete, as defined in section 3.9.14. |
| Textures referred to by valid texture handles will always be complete. |
| |
| |
| Additions to Chapter 5 of the OpenGL 4.0 Specification (Special Functions) |
| |
| Modify Section 5.5.1, Commands Not Usable In Display Lists, p. 413 |
| |
| (add a new category to the list on pp. 413-414) |
| |
| Handle residency management: MakeTextureHandleResidentARB, |
| MakeTextureHandleNonResidentARB, MakeImageHandleResidentARB, |
| MakeImageHandleNonResidentARB. |
| |
| (note: GetTextureHandleARB, GetTextureSamplerHandleARB, GetImageHandleARB, |
| IsTextureHandleResidentARB, and IsImageHandleResidentARB are also |
| non-listable, but are covered by the blanket rules for Get* and Is* |
| commands in "Other queries") |
| |
| |
| Additions to Chapter 6 of the OpenGL 4.0 Specification (Queries) |
| |
| Modify Section 6.1.4, Texture Queries, p. 427 |
| |
| (add to the end of the section) The commands: |
| |
| boolean IsTextureHandleResidentARB(uint64 handle); |
| boolean IsImageHandleResidentARB(uint64 handle); |
| |
| return TRUE if the specified texture or image handle is resident in the |
| current context. The error INVALID_OPERATION will be generated by |
| IsTextureHandleResidentARB or IsImageHandleResidentARB if <handle> is not |
| a valid texture or image handle, respectively. In the case of an error, |
| FALSE is returned. |
| |
| |
| Additions to Appendix D of the OpenGL 4.0 Specification (Shared Objects and |
| Multiple Contexts) |
| |
| Modify Section D.1.2, Deleted Object and Object Name Lifetimes |
| |
| (modify first paragraph, p. 534) ... A buffer, texture, sampler, or |
| renderbuffer object is in use while it is attached to any container object |
| or bound to a context bind point in any context. A texture or sampler |
| object is also in use if any texture or image handle referencing the |
| object is resident for any context. Texture and image handles are not |
| deleted until either the underlying texture or sampler object used to |
| create the handle are deleted. A sync object ... |
| |
| Modify/replace Section D.X of NV_shader_buffer_load |
| |
| Object Use by GPU Address or Handle |
| |
| The GPU address of a buffer object is valid in all contexts in the share |
| group that the buffer belongs to. Similarly, texture and image handles |
| extracted from texture and/or sampler objects are also valid in all |
| contexts in the share group. Buffers, texture handles, and image handles |
| must be made resident separately in each context referencing them by GPU |
| address or handle to allow the GL to determine which resources may be used |
| in each command stream. If a GPU address or handle is used by a given |
| context where the buffer or handle has not been made resident in that |
| context, undefined results including program termination may occur. Such |
| undefined results may occur even if the buffer or handle in question has |
| been made resident for other contexts belonging to the context's share |
| group. |
| |
| |
| Modifications to The OpenGL Shading Language Specification, Version 4.00 |
| |
| Including the following line in a shader can be used to control the |
| language features described in this extension: |
| |
| #extension GL_ARB_bindless_texture : <behavior> |
| |
| where <behavior> is as specified in section 3.3. |
| |
| New preprocessor #defines are added to the OpenGL Shading Language: |
| |
| #define GL_ARB_bindless_texture 1 |
| |
| |
| Replace Section 4.1.7 (Samplers), p. 25 |
| |
| Sampler types (e.g., sampler2D) are effectively opaque handles to texture |
| and sampler objects. They are used with the built-in texture functions |
| (described in section 8.9 "Texture Lookup Functions") to specify which |
| texture to access and how it is to be filtered. Samplers are represented |
| using 64-bit integer handles, and may be converted to and from 64-bit |
| integers using constructors. Samplers may not be implicitly converted to |
| and from 64-bit integers, and may not be used in arithmetic expressions. |
| Samplers may be declared as shader inputs and outputs, as uniform |
| variables, as temporary variables, and as function parameters. Samplers |
| aggregated into arrays within a shader (using square brackets []) can be |
| indexed with arbitrary integer expressions. Samplers can be used as |
| l-values, so can be assigned into and used as "out" and "inout" function |
| parameters. As function parameters, samplers may be only passed to |
| samplers of matching type. As uniforms in the default uniform block, |
| samplers may be initialized only with the OpenGL API; they cannot be |
| declared with an initializer in a shader. |
| |
| The OpenGL API allows default block sampler uniforms to be assigned values |
| referencing either a texture image unit number or a texture handle, |
| depending on the API function used. All other sampler variables must be |
| assigned a texture handle. When a sampler uniform is assigned to a |
| texture image unit, texture functions using it will reference the texture |
| bound to the corresponding target of the selected texture image unit. |
| When a texture function uses a sampler variable assigned to a texture |
| handle, the value of the handle must be a valid handle returned by the |
| OpenGL API (Section 3.9.X, Bindless Textures) that has been made resident, |
| and that texture must have a target matching the sampler variable type. |
| Using a sampler whose the texture target does not match that sampler type |
| produces undefined results but not program termination. Using a sampler |
| that is not a texture image unit reference and is not a valid and resident |
| texture handle produces undefined results including possible program |
| termination. |
| |
| |
| Replace Section 4.1.X, (Images) |
| |
| Like samplers, images are effectively handles to one-, two-, or three- |
| dimensional images corresponding to all or a portion of a single level of |
| a texture image. Images are represented using 64-bit integer handles, and |
| may be converted to and from 64-bit integers using constructors. Samplers |
| may not be implicitly converted to and from 64-bit integers, and may not |
| be used in arithmetic expressions. There are distinct image variable |
| types for each texture target, and for each of float, integer, and |
| unsigned integer data types. Image accesses should use an image type that |
| matches the target of the texture whose level is being accessed, or for |
| non-layered bindings of 3D or array images should use the image type that |
| matches the dimensionality of the layer of the image (i.e. a layer of 3D, |
| 2DArray, Cube, or CubeArray should use image2D, a layer of 1DArray should |
| use image1D, and a layer of 2DMSArray should use image2DMS). If the image |
| target type does not match the image being accessed in this manner, if the |
| data type does not match the bound image, or if the "size" layout |
| qualifier does not match the image format as described in Section 3.9.X of |
| the OpenGL Specification, the results of image accesses are undefined but |
| may not include program termination. |
| |
| Image variables are used in the image load, store, and atomic functions |
| described in Section 8.X, "Image Functions" to specify an image to access. |
| Images may be declared as shader inputs and outputs, as uniform variables, |
| as temporary variables, and as function parameters. Images may be |
| aggregated into arrays within a shader (using square brackets []) and can |
| be indexed with general integer expressions. Images can be used as |
| l-values, so can be assigned into and used as "out" and "inout" function |
| parameters. As uniforms in the default uniform block, images may be |
| initialized only with the OpenGL API; they cannot be declared with an |
| initializer in a shader. As function parameters, images may be only |
| passed to images of matching type. |
| |
| The OpenGL API allows default block image uniforms to be assigned to |
| reference either an image unit number or an image handle, depending on the |
| API function used. All other image variables must be assigned an image |
| handle. When an image uniform is assigned to an image unit, image |
| functions using it will reference the texture and image state |
| corresponding to the selected image unit. When an image function uses a |
| variable assigned to an image handle, the value of the handle must be a |
| valid handle returned by the OpenGL API (Section 3.9.X of |
| EXT_shader_image_load_store, Texture Image Loads and Stores, as modified |
| by this extension) that has been made resident, and that contains image |
| data compatible with the variable type as described above. Using an image |
| variable that is not an image unit reference and is not a valid and |
| resident image handle produces undefined results including possible |
| program termination. |
| |
| |
| Modify Section 4.3.4, Inputs, p. 34 |
| |
| (modify third paragraph of the section to allow sampler and image types) |
| ... Vertex shader inputs can only be float, single-precision |
| floating-point scalars, single-precision floating-point vectors, matrices, |
| signed and unsigned integers and integer vectors, sampler and image types. |
| |
| (modify last paragraph, p. 35, allowing samplers and images as fragment |
| shader inputs) ... Fragment inputs can only be signed and unsigned |
| integers and integer vectors, floating point scalars, floating-point |
| vectors, matrices, sampler and image types, or arrays or structures of |
| these. Fragment shader inputs that are signed or unsigned integers, |
| integer vectors, or any double-precision floating- point type, or any |
| sampler or image type must be qualified with the interpolation qualifier |
| "flat". |
| |
| |
| Modify Section 4.3.6, Outputs, p. 36 |
| |
| (modify second paragraph, p. 37, to allow sampler and image outputs) |
| ... Output variables can only be floating-point scalars, floating-point |
| vectors, matrices, signed or unsigned integers or integer vectors, sampler |
| or image types, or arrays or structures of any these. |
| |
| (do not modify the last paragraph, p. 38; samplers and images are not |
| allowed as fragment shader outputs) |
| |
| |
| Modify Section 4.3.7, Interface Blocks, p. 38 |
| |
| (remove the following bullet from the last list on p. 39, thereby |
| permitting sampler types in interface blocks; image types are also |
| permitted in blocks by this extension) |
| |
| * sampler types are not allowed |
| |
| |
| Modify Section 4.4.6 Opaque-Uniform Layout Qualifiers of the GLSL 4.30 spec |
| |
| Image and sampler types accept a uniform layout qualifier identifier |
| controlling whether the uniform may be used with a bindless handle: |
| |
| layout-qualifier-id |
| bindless_sampler |
| bindless_image |
| bound_sampler |
| bound_image |
| |
| These modifiers control whether default-block uniforms of the |
| corresponding types may have their values set via both UniformHandle* and |
| Uniform1i (bindless_sampler and bindless_image) or only via Uniform1i |
| (bound_sampler and bound_image). 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, or bindless_image and |
| bound_image, 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, or variables with non-uniform |
| storage, a compile-time error will be generated. In the absence of these |
| qualifiers, sampler and image uniforms are considered "bound". |
| Additionally, if GL_ARB_bindless_texture is not enabled, these uniforms are |
| considered "bound". |
| |
| Modify Section 5.4.1, Conversion and Scalar Constructors, p. 60 |
| |
| (add the following constructors:) |
| |
| // In the following four constructors, the low 32 bits of the sampler |
| // type correspond to the .x component of the uvec2 and the high 32 bits |
| // correspond to the .y component. |
| uvec2(any sampler type) // Converts a sampler type to a |
| // pair of 32-bit unsigned integers |
| any sampler type(uvec2) // Converts a pair of 32-bit unsigned integers to |
| // a sampler type |
| uvec2(any image type) // Converts an image type to a |
| // pair of 32-bit unsigned integers |
| any image type(uvec2) // Converts a pair of 32-bit unsigned integers to |
| // an image type |
| |
| |
| Additions to the AGL/EGL/GLX/WGL Specifications |
| |
| None |
| |
| Interactions with OpenGL 4.0 (Core Profile) |
| |
| If the core profile of OpenGL 4.0 (or any version since 3.0) is supported, |
| references to fixed-function fragment processing and display lists should |
| be removed. References to the TEXTURE_LOD_BIAS for the current texture |
| unit should also be removed. |
| |
| Interactions with OpenGL 3.3 and ARB_sampler_objects |
| |
| If neither OpenGL 3.3 nor ARB_sampler_objects is supported, the portion of |
| this extension referring to the sampler object type introduced in OpenGL |
| 3.3 should be removed. In particular, the GetTextureSamplerHandleARB API |
| will not be supported. |
| |
| Interactions with OpenGL 4.2, ARB_shader_image_load_store, and |
| EXT_shader_image_load_store |
| |
| If OpenGL 4.2, ARB_shader_image_load_store, and |
| EXT_shader_image_load_store are not supported, the portion of this |
| extension supporting image handles and image loads, stores, and atomics |
| should be removed. In particular, the functions GetImageHandleARB, |
| MakeImageHandleResidentARB, MakeImageHandleNonResidentARB should be removed. |
| |
| Portions of this extension have been written against the |
| EXT_shader_image_load_store, since OpenGL 4.2 and the ARB extension did |
| not exist when the specification was first written. Similar edits would |
| apply to the OpenGL 4.2 and ARB_shader_image_load_store specifications. |
| |
| Interactions with NV_vertex_attrib_integer_64bit |
| |
| If NV_vertex_attrib_integer_64bit is not supported, this extension inherits |
| the {Get}VertexAttribL1ui64{v}ARB entry points and UNSIGNED_INT64_ARB enum, as |
| well as the functional edits describing them. However, references to the |
| uint64_t type in the shader and providing 64-bit unsigned integer data to |
| the shader are removed. |
| |
| Interactions with NV_gpu_shader5 |
| |
| If NV_gpu_shader5 is not supported, edits to Section 4.1.7 of the GLSL |
| Specification describing sampler indexing should be changed to read |
| "Sampler values passed into texture built-in functions must be dynamically |
| uniform, otherwise results are undefined." Make a similar edit for images. |
| This is the language found in unextended OpenGL 4.0, modified not to be |
| specific to uniform arrays; NV_gpu_shader5 extends it to allow non-uniform |
| samplers and images. |
| |
| Interactions with EXT_direct_state_access |
| |
| In this extension, INVALID_OPERATION is generated when calling various |
| functions to modify the state of a texture object from which handles have |
| been extracted. If EXT_direct_state_access is suported, this error |
| behavior is further extended to cover similar functions provided by |
| EXT_direct_state access. In particular, this error will be generated by: |
| TextureImage*EXT, CopyTextureImage*EXT, CompressedTextureImage*EXT, |
| TextureBufferEXT, TextureParameterEXT, MultiTexImage*EXT, |
| CopyMultiTexImage*EXT, CompressedMultiTexImage*EXT, MultiTexBufferEXT, and |
| MultiTexParameter*EXT. |
| |
| Interactions with ARB_seamless_cubemap and AMD_seamless_cubemap_per_texture |
| |
| If ARB_seamless_cubemap (or OpenGL 4.0, which includes it) is supported, |
| the per-context seamless cubemap enable is ignored and treated as disabled |
| when using texture handles. |
| |
| If AMD_seamless_cubemap_per_texture is supported, the seamless cube map |
| texture parameter of the underlying texture does apply when texture |
| handles are used. |
| |
| Interactions with NV_gpu_program4, NV_gpu_program5, and |
| EXT_shader_image_load_store |
| |
| If NV_gpu_program5 is supported, the following edits are made to the |
| NV_gpu_program4, NV_gpu_program5, and EXT_shader_image_load_store |
| specifications: |
| |
| Modify Section 2.X.2, Program Grammar of NV_gpu_program5 |
| |
| (add new grammar rules allowing textures to be referred to by handles, |
| e.g., "TEX result, coords, handle(texHandle.x), 2D") |
| |
| <textureUseV> ::= "handle" "(" <addrUseS> ")" |
| |
| <imageUnit> ::= "handle" "(" <addrUseS> ")" |
| |
| |
| Modify Section 2.X.4.4, Program Texture Access, of NV_gpu_program4 |
| |
| (modify the paragraph beginning with "The texture used by TextureSample" |
| to permit the use of handles) The texture used by TextureSample() is |
| identified according to the <textureUseV> grammar rule. If <textureUseV> |
| expands to the grammar rule containing "handle", the texture used is |
| identified by taking the scalar value specified in that rule as a texture |
| handle. Otherwise, the texture corresponding to the texture image unit |
| specified by <textureUseV> is used. The texture target... |
| |
| If the instruction uses a named texture variable, the <nvTexImageUnit> |
| grammar rule, or the "texture" grammar rule, then the texture used by |
| TextureSample() is one of the textures bound to the texture image unit |
| whose number is specified in the instruction according to the |
| <texImageUnit> grammar rule, and the texture target accessed is specified |
| according to the <texTarget> grammar rule and Table X.17. If the |
| instruction uses the "handle" grammar rule, then the specified texture |
| handle will select which texture is used, and the target of that texture |
| must match the target specified by the <texTarget> grammar rule or else |
| the result is undefined. Fixed-function texture enables are always ignored |
| when determining which texture to access in a program. |
| |
| |
| Section 2.X.5.Y, Program Options |
| |
| If a program (in any shader stage) specifies the option |
| "ARB_bindless_texture", the grammar edits described in section 2.X.2 |
| will apply. |
| |
| |
| Modify Section 2.X.8.Z, LOADIM: Image Load, of EXT_shader_image_load_store |
| |
| (modify the first paragraph) The LOADIM instruction ... from the texture |
| specified by <imageUnit>. If <imageUnit> expands to the grammar rule |
| containing "handle", the texture used is identified by taking the scalar |
| value specified in that rule as an image handle. Otherwise, the texture |
| corresponding to the image unit specified by <imageUnit> is used. |
| Unformatted loads read... |
| |
| Modify Section 2.X.8.Z, STOREIM: Image Store, of |
| EXT_shader_image_load_store |
| |
| (modify the first paragraph) The STOREIM instruction ... to the texture |
| specified by <imageUnit> using the data specified in the first vector |
| operand. If <imageUnit> expands to the grammar rule containing "handle", |
| the texture used is identified by taking the scalar value specified in |
| that rule as an image handle. Otherwise, the texture corresponding to the |
| image unit specified by <imageUnit> is used. The store is performed in |
| the manner described in Section 3.9.X. |
| |
| |
| Modify Section 2.X.8.Z, ATOMIM: Image Atomic Memory Operation, of |
| EXT_shader_image_load_store |
| |
| (modify the first paragraph) The ATOMIM instruction takes ...image load |
| from the texture specified by <imageUnit>, performs ... returns the loaded |
| value in the vector result. If <imageUnit> expands to the grammar rule |
| containing "handle", the texture used is identified by taking the scalar |
| value specified in that rule as an image handle. Otherwise, the texture |
| corresponding to the image unit specified by <imageUnit> is used. The |
| atomic operation is performed in the manner described in Section 3.9.X. |
| |
| Interactions with GLSL 4.20 |
| |
| Without GLSL 4.20 support, sampler and image uniforms may only be |
| initialized through the OpenGL API. With GLSL 4.20, sampler and image |
| uniforms may be initialized in the shader using |
| |
| layout(binding = integer-constant) |
| |
| as described in section 4.4.4 "Opaque-Uniform Layout Qualifiers". When |
| ARB_bindless_texture is supported, these initial binding values are always |
| taken to mean a texture image or image unit number, not a bindless handle. |
| |
| Interactions with NV_bindless_texture |
| |
| If both extensions are supported, handles generated by *ARB functions may |
| be used with *NV entry points and vice versa. GetTexture*HandleARB can not |
| be used to create handles for textures/samplers with arbitrary border |
| colors. However, if NV_bindless_texture is supported, handles created by |
| GetTexture*HandleNV can be used with this extension as though no border |
| color restriction existed. |
| |
| Errors |
| |
| The error INVALID_VALUE is generated by GetTextureHandleARB or |
| GetTextureSamplerHandleARB if <texture> is zero or not the name of an |
| existing texture object. |
| |
| The error INVALID_VALUE is generated by GetTextureSamplerHandleARB if |
| <sampler> is zero or is not the name of an existing sampler object. |
| |
| The error INVALID_OPERATION is generated by GetTextureHandleARB or |
| GetTextureSamplerHandleARB if thetexture object specified by <texture> is |
| not complete. |
| |
| The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*, |
| CompressedTexImage*, TexBuffer*, TexParameter*, as well as other functions |
| defined in terms of these, if the texture object to be modified is |
| referenced by one or more texture or image handles. |
| |
| The error INVALID_OPERATION is generated by BufferData, or any function |
| defined in terms of this, if the buffer object to be modified is bound |
| to a buffer texture that is referenced by one or more texture or image |
| handles. |
| |
| 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 MakeTextureHandleResidentARB if |
| <handle> is not a valid texture handle, or if <handle> is already resident |
| in the current GL context. |
| |
| The error INVALID_OPERATION is generated by MakeTextureHandleNonResidentARB |
| if <handle> is not a valid texture handle, or if <handle> is not resident |
| in the current GL context. |
| |
| The error INVALID_VALUE is generated by GetImageHandleARB if <texture> is |
| zero or not the name of an existing texture object, if the image for |
| <level> does not existing in <texture>, or if <layered> is FALSE and |
| <layer> is greater than or equal to the number of layers in the image at |
| <level>. |
| |
| The error INVALID_OPERATION is generated by GetImageHandleARB if the |
| texture object <texture> is not complete or if <layered> is TRUE and |
| <texture> is not a three-dimensional, one-dimensional array, two |
| dimensional array, cube map, or cube map array texture. |
| |
| The error INVALID_OPERATION is generated by MakeImageHandleResidentARB if |
| <handle> is not a valid image handle, or if <handle> is already resident |
| in the current GL context. |
| |
| The error INVALID_OPERATION is generated by MakeImageHandleNonResidentARB |
| if <handle> is not a valid image handle, or if <handle> is not resident in |
| the current GL context. |
| |
| The error INVALID_OPERATION will be generated by IsTextureHandleResidentARB |
| and IsImageHandleResidentARB if <handle> is not a valid texture or image |
| handle, respectively. |
| |
| The error INVALID_OPERATION is generated by UniformHandleui64{v}ARB if the |
| sampler or image uniform being updated has the "bound_sampler" or |
| "bound_image" layout qualifier. |
| |
| |
| 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 glTexImage/glTexStorage. |
| // Initialize the texture parameters as required. |
| |
| // Get a handle for the texture. |
| texHandles[i] = glGetTextureHandleARB(textures[i]); |
| |
| // At this point, it's no longer possible to resize/reallocate |
| // texture images or modify texture parameters for "textures[i]". |
| // However, it's still possible to update texture data via |
| // glTexSubImage. |
| |
| // Make the handle resident before using it. |
| glMakeTextureHandleResidentARB(texHandles[i]); |
| } |
| |
| // 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. 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]". |
| glUniformHandleui64ARB(location, texHandles[i]); |
| |
| drawStuff(); |
| } |
| |
| ... |
| |
| // If the application doesn't need to use texHandles[10] for a while, it |
| // can make it non-resident to reduce the overall memory footprint. |
| glMakeTextureHandleNonResidentARB(texHandles[10]); |
| |
| // After this point, the texture data associated with texHandles[10] is |
| // not guaranteed to be resident, and using it in a draw call could |
| // result in exceptions. Use glMakeTextureHandleResidentARB() to make it |
| // resident again before it's needed for rendering. |
| |
| 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, pass them through the pipeline |
| as 64-bit integers. |
| |
| To use a "dictionary" of samplers in a uniform block, you could use a |
| shader like: |
| |
| #version 400 |
| #extension GL_ARB_bindless_texture : require |
| #define NUM_TEXTURES 256 |
| |
| flat in int whichSampler; |
| in vec2 texCoord; |
| out vec4 finalColor; |
| |
| uniform Samplers { |
| sampler2D allTheSamplers[NUM_TEXTURES]; |
| }; |
| |
| void main() |
| { |
| finalColor = texture(allTheSamplers[whichSampler], texCoord); |
| } |
| |
| In the following example, the sampler to use is selected in a vertex |
| shader, passed to the fragment shader as a (flat) input, and then used for |
| a texture lookup. |
| |
| #version 400 |
| #extension GL_ARB_bindless_texture : require |
| |
| flat in sampler2D theSampler; |
| in vec2 texCoord; |
| out vec4 finalColor; |
| |
| void main() |
| { |
| finalColor = texture(theSampler, texCoord); |
| } |
| |
| |
| New State |
| |
| Add new table, Bindless Texture Handles |
| |
| Initial |
| Get Value Type Get Command Value Description Sec. Attribute |
| ------------ ---- -------------------- ------- ------------------------- ------ ------- |
| - Z64 GetTextureHandleARB n/a texture handle 3.9.X - |
| or GetTextureSampler- |
| HandleARB |
| - Z+ - n/a texture object used 3.9.X - |
| - Z+ - n/a sampler object used 3.9.X - |
| - nxB IsTextureHandle- FALSE is bindless texture handle 3.9.X - |
| ResidentARB resident for the current |
| context (separate state per |
| context/handle pair) |
| |
| Add new table, Bindless Image Handles |
| |
| Initial |
| Get Value Type Get Command Value Description Sec. Attribute |
| ------------ ---- -------------------- ------- ------------------------- ------ ------- |
| - Z64 GetImageHandleARB n/a image handle 3.9.X - |
| - Z+ - n/a texture object used 3.9.X - |
| - Z+ - n/a texture object level 3.9.X - |
| - B - n/a is image handle layered? 3.9.X - |
| - Z+ - n/a selected layer for non- 3.9.X - |
| layered images |
| - Z_<n> - n/a image internal format enum 3.9.X - |
| - nxB IsImageHandle- FALSE is bindless image handle 3.9.X - |
| ResidentARB resident for the current |
| context (separate state |
| per context/handle pair) |
| |
| Issues |
| |
| (1) Could this have been specified as simply making the maximum number of |
| texture image units and image units arbitrarily large and then |
| indexing into an array of samplers or images? |
| |
| RESOLVED: Perhaps, but this approach doesn't involve any arbitrarily |
| limits. Allowing the implementation to choose the GPU handle can avoid |
| the need for some kind of unit->address translation. It's also |
| beneficial for the GPU handles to be static. |
| |
| (2) Should we add commands to allow prioritizing which allocations belong |
| in dedicated video memory? |
| |
| RESOLVED: Defer to a future extension. |
| |
| (3) How should we handle separate samplers? |
| |
| RESOLVED: OpenGL 3.3 created separate sampler objects, and provided |
| separate binding points in a texture image unit. When referencing a |
| texture image unit with a sampler object bound, the state of that object |
| is used; otherwise, sampler state embedded in the texture is used. In |
| either case, each texture image unit consists of a texture/sampler pair, |
| and no capability is provided to mix the texture from one unit with |
| samplers from another. |
| |
| This extension provides support for use of OpenGL 3.3-style sampler |
| objects via the GetTextureSamplerHandleARB entry point, which can be used |
| to create a handle for each pair of texture/sampler objects the |
| application wishes to use. GLSL samplers can be used with texture |
| handles in the same way that they can be used with the texture/sampler |
| object pair associated with a texture image unit. |
| |
| It's possible that some future extension to OpenGL might allow shaders |
| to mix and match texture and sampler objects within a shader instead of |
| using pre-defined pairs. Such shaders would use two different shader |
| variable types -- one encapsulating texture object state and the other |
| encapsulating sampler state. To allow bindless texture support in this |
| mode, we would expect to add a new handle type (sampler handles) and to |
| provide new APIs to extract sampler handles from sampler objects and to |
| manage sampler handle residency. (It's not immediately clear whether it |
| would even be necessary to manage sampler handle residency, since |
| sampler objects only have a small number of state variables.) |
| |
| (4) Can texture or sampler objects be modified while they are used by a |
| texture or image handle? |
| |
| RESOLVED: No. If such changes were permitted, each modification to the |
| texture object would require potential synchronization with one or more |
| texture/image handles extracted from the texture. This seems like a lot |
| of bookkeeping with little benefit. One exception to this rule is that |
| individual texels of such texture objects may still be updated with APIs |
| such as TexSubImage* and by rendering to a framebuffer object to which |
| the texture is attached. |
| |
| (5) Is there a way to release a texture or image handle after it is |
| created? |
| |
| RESOLVED: No API is provided to release or delete handles once they are |
| created. Texture and image handles are automatically reclaimed when the |
| underlying texture or sampler objects are finally deleted. This |
| deletion will happen only when no handle using the texture or sampler |
| object is resident on any context. This decision is similar to that of |
| NV_shader_buffer_load, which didn't provide any mechanism to release the |
| address of a buffer object. |
| |
| One consequence of this decision is that structural changes (e.g., image |
| size and format and parameter changes) to textures from which handles |
| are extracted are not possible for the lifetime of the texture. |
| |
| (6) How do texture and image handles work with multiple contexts sharing a |
| set of texture and sampler objects? |
| |
| RESOLVED: Texture and image handles are shared by all contexts in a |
| share group, in the same way that GPU addresses are shared in |
| NV_shader_buffer_load. Once a handle has been extracted from a texture |
| or texture/sampler pair in any context, that handle may be used by all |
| other contexts in the share group. |
| |
| However, texture and image handle residency is managed per-context. If |
| a texture or image handle is used in multiple contexts in a share group, |
| the handle must be made resident in all such contexts. |
| |
| (7) What happens if you try to delete a texture or sampler object with a |
| handle that is resident in another context? |
| |
| RESOLVED: Deleting the texture will remove the texture from the name |
| space and make all handles using the texture non-resident in the current |
| context. However, texture or image handles for a deleted texture are |
| not deleted until the underlying texture or sampler object itself is |
| deleted. That deletion won't happen until the object is not bound |
| anywhere and there are no handles using the object that are resident in |
| any context. |
| |
| (8) Can you get a handle from a default texture object (numbered zero)? |
| |
| RESOLVED: No, for several reasons. First, the APIs to extract a |
| texture handle only take a texture object number, with no target. Since |
| there is a separate default texture object for each texture target, the |
| texture object number zero does not identify a unique texture. |
| Additionally, since the spec forbids modification of textures used with |
| handles, extracting a handle from a default texture would leave the |
| texture in a state where it could be neither modified nor deleted. |
| |
| (9) Can you have multiple handles for the same texture or texture/sampler |
| pair? |
| |
| RESOLVED: Any texture object can have at most one handle extracted from |
| the texture object via GetTextureHandleARB; calling that function |
| multiple times on a single texture will always return the same handle. |
| |
| A texture or sampler object may have multiple texture handles extracted |
| from it via GetTextureSamplerHandleARB, since such handles correspond to |
| a texture/sampler pair and a single texture or sampler object may be |
| paired with multiple objects of the other type. However, calling that |
| function multiple times on a single texture/sampler pair will always |
| return the same handle. |
| |
| A texture object may have multiple image handles extracted from it via |
| GetImageHandleARB; however, each such handle must represent a different |
| "view" of the texture. If that function is called multiple times with |
| the same <texture>, <level>, <layered>, <layer>, and <format> |
| parameters, the same handle will always be returned. |
| |
| (10) Should we provide <access> parameters for MakeTextureHandleResidentARB |
| and MakeImageHandleResidentARB? |
| |
| RESOLVED: For MakeImageHandleResidentARB, yes. It may be useful to be |
| able to make a given texture resident only for reading or writing. For |
| MakeTextureHandleResidentARB, no. Texture mapping is a read-only |
| operation; texture handles can really only be used for reading. So all |
| calls to MakeTextureHandleResidentARB are considered to use an access |
| mode of READ_ONLY. |
| |
| (11) Should implicit conversions be supported for converting uint64-typed |
| handles to sampler and image types? |
| |
| RESOLVED: No. An explicit constructor is provided to build a handle |
| from uvec2 or vice versa. |
| |
| (12) How do we handle backwards compatibility for sampler uniforms in the |
| default uniform block, which have historically been set to point at a |
| texture image unit? |
| |
| RESOLVED: We allow sampler uniforms to be set either using handles (via |
| the UniformHandle* APIs) or texture image units (via the previously used |
| Uniform1i* APIs). If the uniform was last set with a handle, the |
| specified handle will be used for texture access. Otherwise, the value |
| of the uniform is treated as a texture image unit when the texture is |
| accessed, and is resolved to refer to the appropriate texture bound to |
| that unit. |
| |
| We expect that implementations will distinguish between the two types of |
| uniform values either by a per-uniform flag or by reserving a subset of |
| the 2^64 possible handle values to be used to refer to texture image |
| units. |
| |
| We impose no limit on the mixing and matching of texture image unit and |
| handle-based uniform values; an application is permitted to set some |
| uniforms via UniformHandle*ARB and others via Uniform1i. We don't expect |
| such mixing and matching to be common. |
| |
| When a sampler or image uniform's value is queried via any of the |
| GetUniform* commands, the returned value will reflect the most recently |
| set value through either UniformHandle* or Uniform1i*, converted to the |
| requested type. |
| |
| (13) Should UniformHandleui64{v}ARB check the provided uniform value(s) to |
| determine if they are valid handles? |
| |
| RESOLVED: No; passing in proper texture or image handles is the |
| responsibility of the application. Note that even if we did verify that |
| handles were valid at the time sampler or image uniforms were specified, |
| there is no guarantee that they would still be valid for texture or |
| image accesses when they are used. In particular, the texture referred |
| to by the handle may have be deleted, or may exist without being made |
| resident for the context in question. |
| |
| (14) With this extension, GLSL sampler and image variables may be |
| specified using 64-bit handles and are permitted to count as two |
| components toward implementation-dependent limits on uniforms, shader |
| inputs, and shader outputs. Is there a backward compatibility |
| problem here? |
| |
| RESOLVED: If there is one, we don't expect it to be very serious. |
| |
| Prior to this extension, samplers or images could not be used as shader |
| inputs or outputs, so there is no compatibility problem there. Samplers |
| and images could be used as uniforms, however. While there is no |
| explicit spec language describing the amount of storage required for |
| samplers and images, one might construe this lack of language to mean |
| that only a single component was previously required. Allowing for |
| 64-bit handles in this extension could double the requirement and cause |
| shaders that previously just barely fit to exceed implementation |
| limits. |
| |
| Implementations that consider this issue serious could increase their |
| uniform limit slightly to compensate. Note that the number of sampler |
| variables used prior to this extension was quite limited, so the amount |
| of extra storage required for 64-bit handles should be small. |
| |
| (15) What happens if you try to access a texture or image handle that is |
| (a) invalid, (b) non-resident, or (c) corresponds to a texture of a |
| target different from the target used for the access (e.g., doing a |
| 3D lookup with a handle referring to a 2D texture)? |
| |
| RESOLVED: For (a), we specify undefined behavior including possible |
| program termination. Such accesses are effectively equivalent to |
| chasing an invalid pointer. |
| |
| For (b), we treat non-resident handles as invalid. Note that this |
| extension doesn't require that accesses to non-resident handles fail. |
| |
| For (c), we specify that loads/stores to textures of the "wrong" type |
| may have undefined results but should not result in program termination. |
| This same situation could arise in EXT_shader_image_load_store, where |
| each image unit has a single attachment point shared by all targets, and |
| the same behavior was specified there. Similar situations could also |
| arise for indexed texture accesses in OpenGL 4.0, where out-of-bounds |
| array indices could cause a shader to use a texture unit whose "active" |
| target was the wrong kind. |
| |
| (16) Prior to this extension, there were limits on the number of different |
| textures that could be accessed at once -- the number of texture |
| image units and image units were limited by implementation-dependent |
| constants. What limits apply with this extension? |
| |
| RESOLVED: Since texture image units and image units need not be used |
| with this extension, those limits no longer apply to shaders that use |
| bindless textures. With this extension, there is no longer any direct |
| limit on the number of textures/images that may be used in any shader |
| stage. |
| |
| There may still be indirect limits based on the total amount of storage |
| available: |
| |
| * Limits on the total amount of uniform memory imply a limit on the |
| total number of texture handles stored as uniforms. |
| |
| * Limits on the number of shader input/output components imply a limit |
| on the number of texture handles passed as shader inputs and |
| outputs. |
| |
| * Limits on the total amount of addressable texture memory imply a |
| limit on the total number of resident texture handles. |
| |
| * Implementations may have (high) limits on the total number of |
| texture handles available in the system. |
| |
| (17) Should we provide any queries to extract information from texture or |
| image handles? |
| |
| RESOLVED: No. |
| |
| (18) Texture and image handles may be made resident or non-resident. How |
| does handle residency interact with texture residency queries from |
| OpenGL 1.1 (AreTexturesResident or TEXTURE_RESIDENT)? |
| |
| RESOLVED: The residency state for texture and image handles in this |
| extension is completely independent from OpenGL 1.1's TEXTURE_RESIDENT |
| query. Residency for texture handles is a function of whether the |
| MakeTextureHandleResidentARB has been called for the handle. OpenGL 1.1 |
| residency is typically a function of whether the texture data are |
| resident in GPU-accessible memory. |
| |
| When a texture handle is not made resident, the texture that it refers |
| to may or may not be stored in GPU-accessible memory. The |
| TEXTURE_RESIDENT query may return TRUE in this case. However, it does |
| not guarantee that the texture handle may be used safely. |
| |
| When a texture handle is made resident, the texture that it refers to is |
| also considered resident for the purposes of the old TEXTURE_RESIDENT |
| query. When an image handle is resident, the texture that it refers to |
| may or may not be considered resident for the query -- the resident |
| image handle may refer only to a single layer of a single mipmap level |
| of the full texture. |
| |
| (19) How does ARB_bindless_texture differ from NV_bindless_texture? |
| |
| RESOLVED: |
| |
| - The constructors to convert between sampler and integer types use uvec2 |
| rather than uint64_t to avoid a dependency on the 64-bit integer types |
| in the shader from NV_gpu_shader5. |
| |
| - The interaction with NV_vertex_attrib_integer_64bit is modified to |
| incorporate the minimal amount of the extension required specify vertex |
| inputs of sampler/image types. |
| |
| - Sampler and image handles passed to texture built-in functions must be |
| dynamically uniform (NV_bindless_texture assumed NV_gpu_shader5 which |
| removed this restriction). In order to increase the utility of this |
| extension, the DrawIDARB shader input in a multi-draw |
| (ARB_shader_draw_parameters) should be defined to be dynamically |
| uniform. |
| |
| - New layout qualifiers are added to inform the compiler of whether |
| default-block sampler and image uniforms may be used with bindless |
| handles. In NV_bindless_texture any uniforms may be used with bindless |
| handles. So a shader can be ported from NV_bindless_texture to |
| ARB_bindless_texture by declaring: |
| |
| layout (bindless_sampler) uniform; |
| layout (bindless_image) uniform; |
| |
| NV_bindless_texture didn't require any shader changes to make uniforms |
| usable with UniformHandleui64{v}, but ARB_bindless_texture requires |
| these declarations. |
| |
| - Not all implementations support an unlimited number of border colors, |
| so ARB_bindless_texture only allows a limited set of border colors. |
| GetTextureHandleARB and GetTextureSamplerHandleARB generate an error |
| if the border color is not R=G=B=(0 or 1), A=(0 or 1), but the |
| corresponding *NV entry points will allow an arbitrary border color. |
| |
| Revision History |
| |
| Rev. Date Author Changes |
| ---- -------- -------- ----------------------------------------- |
| 1 jbolz Internal revisions. |
| pbrown |
| 2 05/01/13 jbolz Add border color limitation. |
| 3 07/24/13 Jon Leech Fix typos & 'program' -> 'texture' in |
| description of GetImageHandleARB (public |
| bugs 914,915). |
| 4 06/13/14 dkoch Fix a variety of typos and missing words. |
| Add missing error condition for BufferData and |
| buffer textures. |
| 5 02/13/17 pbrown Update issue (19) to correct discussion of the |
| DrawIDARB built-in and the name of the |
| extension that added it. |