Name NV_bindless_texture Name Strings GL_NV_bindless_texture Contact Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com) Pat Brown, NVIDIA Coproration (pbrown 'at' nvidia.com) Contributors Daniel Koch, NVIDIA Status Shipping Version Last Modified Date: June 13, 2014 Author Revision: 3 Number OpenGL Extension #418 OpenGL ES Extension #197 Dependencies This extension is written against the OpenGL 4.0 (Compatibility Profile) and OpenGL Shading Language 4.00 Specifications. OpenGL 4.0 or later is required for an OpenGL implementation. The GLSL portion of this extension requires NV_gpu_shader5, or a similar extension providing 64-bit integer support in the shading language. 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. OpenGL ES 3.0 or later is required for an OpenGL ES implementation. This extension interacts with OpenGL ES 3.1. This extension interacts with OES_shader_image_atomic. This extension interacts with EXT_texture_cube_map_array. This extension interacts with EXT_texture_buffer. This extension interacts with EXT_shader_io_blocks. 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, OpenGL ES 3.1 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 64-bit 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 GetTextureHandleNV(uint texture); uint64 GetTextureSamplerHandleNV(uint texture, uint sampler); void MakeTextureHandleResidentNV(uint64 handle); void MakeTextureHandleNonResidentNV(uint64 handle); uint64 GetImageHandleNV(uint texture, int level, boolean layered, int layer, enum format); void MakeImageHandleResidentNV(uint64 handle, enum access); void MakeImageHandleNonResidentNV(uint64 handle); void UniformHandleui64NV(int location, uint64 value); void UniformHandleui64vNV(int location, sizei count, const uint64 *value); void ProgramUniformHandleui64NV(uint program, int location, uint64 value); void ProgramUniformHandleui64vNV(uint program, int location, sizei count, const uint64 *values); boolean IsTextureHandleResidentNV(uint64 handle); boolean IsImageHandleResidentNV(uint64 handle); New Tokens None. 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 UniformHandleui64NV(int location, uint64 value); void UniformHandleui64vNV(int location, sizei count, const uint64 *value); void ProgramUniformHandleui64NV(uint program, int location, uint64 value); void ProgramUniformHandleui64vNV(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}NV commands will load 64-bit unsigned integer handles into a uniform location corresponding to sampler or image variable types. Only the UniformHandleui64{v}NV and Uniform1i{v} commands can be used to load sampler and image values as described in Section 2.14.6 (Samplers). 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 uint64-typed value at the specified offset. * Members of image types are extracted from a buffer object by reading a single uint64-typed 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}NV 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}NV. 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}NV, the value passed to UniformHandleui64NV{v} 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}NV 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}NV. 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}NV, 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 GetTextureHandleNV(uint texture); uint64 GetTextureSamplerHandleNV(uint texture, uint sampler); GetTextureHandleNV will create a texture handle using the current state of the texture named , including any embedded sampler state. GetTextureSamplerHandleNV will create a texture handle using the current non-sampler state from the texture named and the sampler state from the sampler object . In both cases, a 64-bit unsigned integer handle is returned. The error INVALID_VALUE is generated if is zero or is not the name of an existing texture object or if is zero or is not the name of an existing sampler object. The error INVALID_OPERATION is generated if the texture object is not complete (section 3.9.14). 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 GetTextureHandleNV is called multiple times for the same texture or if GetTextureSamplerHandleNV is called multple 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 MakeTextureHandleResidentNV(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 is not a valid texture handle, or if is already resident in the current GL context. A texture handle may be made inaccessible to shaders by calling: void MakeTextureHandleNonResidentNV(uint64 handle); The error INVALID_OPERATION is generated if is not a valid texture handle, or if 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) ... 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 GetImageHandleNV(uint texture, int level, boolean layered, int layer, enum format); creates and returns an image handle for level of the texture named . If is TRUE, a handle is created for the entire texture level. If is FALSE, a handle is created for only the layer of the texture level. 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 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 GetImageHandleNV if: * is zero or not the name of an existing texture object; * the image for the texture level doesn't exist (i.e., has a size of zero in ); or * is FALSE and is greater than or equal to the number of layers in the image at level . The error INVALID_OPERATION is generated by GetImageHandleNV if: * the texture object is not complete (section 3.9.14); * 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 , , , , and is unique; the same handle will be returned if GetImageHandleNV 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 MakeImageHandleResidentNV(uint64 handle, enum 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 is not a valid image handle, or if 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 MakeImageHandleNonResidentNV(uint64 handle); The error INVALID_OPERATION is generated if is not a valid image handle, or if 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: MakeTextureHandleResidentNV, MakeTextureHandleNonResidentNV, MakeImageHandleResidentNV, MakeImageHandleNonResidentNV. (note: GetTextureHandleNV, GetTextureSamplerHandleNV, GetImageHandleNV, IsTextureHandleResidentNV, and IsImageHandleResidentNV 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 IsTextureHandleResidentNV(uint64 handle); boolean IsImageHandleResidentNV(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 IsTextureHandleResidentNV or IsImageHandleResidentNV if 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_NV_bindless_texture : where is as specified in section 3.3. New preprocessor #defines are added to the OpenGL Shading Language: #define GL_NV_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 5.4.1, Conversion and Scalar Constructors, p. 60 (add the following constructors:) uint64_t(any sampler type) // Converts a sampler type to a // 64-bit unsigned integer any sampler type(uint64_t) // Converts a 64-bit unsigned integer to // a sampler type uint64_t(any image type) // Converts an image type to a // 64-bit unsigned integer any image type(uint64_t) // Converts a 64-bit unsigned integer 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 GetTextureSamplerHandleNV API will not be supported. Interactions with OpenGL 4.2, OpenGL ES 3.1, ARB_shader_image_load_store, and EXT_shader_image_load_store If OpenGL 4.2, OpenGL ES 3.1, 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 GetImageHandleNV, MakeImageHandleResidentNV, MakeImageHandleNonResidentNV 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, sampler and image variables (which take 64-bit integer handles) are not allowed to be used as vertex shader inputs. Additionally, portions of this extension modifying NV_vertex_attrib_integer_64bit should be ignored. Interactions with NV_gpu_shader5 If NV_gpu_shader5 or similar functionality providing 64-bit integer types in the shading language is not supported, the GLSL portion of this extension should be modified. In particular, references to 64-bit integer scalars, vectors or other 64-bit types should be deleted, and the constructors to convert 64-bit unsigned integer handles to and from sampler and image data types (as added in Section 5.4.1), should be removed. Default block sampler and image uniforms can still be assigned handles via the UniformHandleui64*NV and ProgramUniformHandleui64*NV functions, and sampler and image types can continue to be used as shader inputs and outputs, uniforms in user-defined blocks, and temporaries. Such uses of these types may consume two components against any relevant limits. Extracting these types from memory locations will be done as if reading a uvec2-typed value at the specified location. Additionally, edits to Section 4.1.7 of the GLSL Specification describing sampler indexing should be changed to read "Samplers aggregated into arrays within a shader (using square brackets [ ]) can only be indexed with a dynamically uniform integral expression, otherwise results are undefined." This is the language found in unextended OpenGL 4.0; NV_gpu_shader5 extends it to allow indexing with arbitrary integer expressions. 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") ::= "handle" "(" ")" ::= "handle" "(" ")" 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 grammar rule. If 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 is used. The texture target... If the instruction uses a named texture variable, the 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 grammar rule, and the texture target accessed is specified according to the 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 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 "NV_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 . If 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 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 using the data specified in the first vector operand. If 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 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 , performs ... returns the loaded value in the vector result. If 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 is used. The atomic operation is performed in the manner described in Section 3.9.X. Interactions with GLSL 4.20 and GLSL ES 3.10 Without GLSL 4.20 or GLSL ES 3.10 support, sampler and image uniforms may only be initialized through the OpenGL API. With GLSL 4.20 and GLSL ES 3.1, 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 NV_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 OpenGL ES If implemented in an OpenGL ES context, references to the following should be removed: - assembly-based shaders, - display lists, - fixed-function fragment processing, - double-precision floating-point values, - 1D and 1D-array textures and images, - TEXTURE_LOD_BIAS for the current texture unit, - the AreTexturesResident command, unless subsequently added by a later extension or version. Modify the edits to Section to 3.9.10 to state that when accessing cube map textures using texture handles in an OpenGL ES context, the cube maps are always treated as seamless. Interactions with OpenGL ES 3.1 If OpenGL ES 3.1 is supported, replace references to EXT_image_load_store and BindImageTextureEXT with appropriate references to OpenGL ES 3.1 functionality and BindImageTexture. References to assigning a default block image uniform an image unit number from the OpenGL API with the Uniform* commands (but not the UniformHandle* commands) should be removed since OpenGL ES only supports assigning image unit numbers with the 'binding' layout qualifier in the shading language. Ignore references to 2DMSArray and 2DMS images as they are not supported in OpenGL ES. Interactions with OES_shader_image_atomic If OES_shader_image_atomic or equivalent functionality is not supported, ignore all references to atomic image operations. Interactions with EXT_texture_cube_map_array If EXT_texture_cube_map_array or equivalent functionality is not supported, ignore all references to cube map array textures. Interactions with EXT_texture_buffer If EXT_texture_buffer or equivalent functionality is not supported, ignore all references to buffer textures and related buffer functionality. Interactions with EXT_shader_io_blocks If EXT_shader_io_blocks or equivalent functionality is supported, sampler and image types are allowed in interface blocks. Otherwise ignore all references to interface blocks. Errors The error INVALID_VALUE is generated by GetTextureHandleNV or GetTextureSamplerHandleNV if is zero or not the name of an existing texture object. The error INVALID_VALUE is generated by GetTextureSamplerHandleNV if is zero or is not the name of an existing sampler object. The error INVALID_OPERATION is generated by GetTextureHandleNV or GetTextureSamplerHandleNV if thetexture object specified by 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 identifies a sampler object referenced by one or more texture handles. The error INVALID_OPERATION is generated by MakeTextureHandleResidentNV if is not a valid texture handle, or if is already resident in the current GL context. The error INVALID_OPERATION is generated by MakeTextureHandleNonResidentNV if is not a valid texture handle, or if is not resident in the current GL context. The error INVALID_VALUE is generated by GetImageHandleNV if is zero or not the name of an existing texture object, if the image for does not existing in , or if is FALSE and is greater than or equal to the number of layers in the image at . The error INVALID_OPERATION is generated by GetImageHandleNV if the texture object is not complete or if is TRUE and 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 MakeImageHandleResidentNV if is not a valid image handle, or if is already resident in the current GL context. The error INVALID_OPERATION is generated by MakeImageHandleNonResidentNV if is not a valid image handle, or if is not resident in the current GL context. The error INVALID_OPERATION will be generated by IsTextureHandleResidentNV and IsImageHandleResidentNV if is not a valid texture or image handle, respectively. 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] = glGetTextureHandleNV(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. glMakeTextureHandleResidentNV(texHandles[i]); } // Compile GLSL shader using sampler uniform . The shader itself // needs no special #extension directive as long as is a uniform in // the default partition. Link the program, and query the location of // , which we will store in . // 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 to point at "texHandles[i]". glUniformHandleui64NV(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. glMakeTextureHandleNonResidentNV(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 glMakeTextureHandleResidentNV() 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_NV_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_NV_gpu_shader5 : require // for 64-bit integer types #extension GL_NV_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 GetTextureHandleNV n/a texture handle 3.9.X - or GetTextureSampler- HandleNV - 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 - ResidentNV 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 GetImageHandleNV 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/a image internal format enum 3.9.X - - nxB IsImageHandle- FALSE is bindless image handle 3.9.X - ResidentNV 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 GetTextureSamplerHandleNV 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 GetTextureHandleNV; 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 GetTextureSamplerHandleNV, 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 GetImageHandleNV; however, each such handle must represent a different "view" of the texture. If that function is called multiple times with the same , , , , and parameters, the same handle will always be returned. (10) Should we provide parameters for MakeTextureHandleResidentNV and MakeImageHandleResidentNV? RESOLVED: For MakeImageHandleResidentNV, yes. It may be useful to be able to make a given texture resident only for reading or writing. For MakeTextureHandleResidentNV, no. Texture mapping is a read-only operation; texture handles can really only be used for reading. So all calls to MakeTextureHandleResidentNV 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 64-bit unsigned integer 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*NV 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}NV 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 MakeTextureHandleResidentNV 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. Revision History Rev. Date Author Changes ---- -------- -------- ----------------------------------------- 3 06/12/14 dkoch Add interactions with OpenGL ES. Define better functionality when NV_gpu_shader5 is not supported. Fix a variety of typos and missing words. Merge in typo fixes from v3 of the ARB extn. Add missing error condition for BufferData and buffer textures. 2 05/16/13 pbrown Fix typo in spec language. 1 jbolz Internal revisions. pbrown