Difference between revisions of "Bindless Texture"

From OpenGL Wiki
Jump to navigation Jump to search
(Start of description of bindless textures, with overview.)
 
(Accidental duplicate data.)
Line 60: Line 60:
  
 
Bindless textures are not safe. The API is given fewer opportunities to ensure sane behavior; it is up to the programmer to maintain integrity. Furthermore, the consequences for mistakes are much more severe. Usually with OpenGL, if you do something wrong, you get either an [[OpenGL Error]] or undefined behavior. With bindless textures, if you do something wrong, the GPU can ''crash'' or your program can terminate. It might even bring down the whole OS.
 
Bindless textures are not safe. The API is given fewer opportunities to ensure sane behavior; it is up to the programmer to maintain integrity. Furthermore, the consequences for mistakes are much more severe. Usually with OpenGL, if you do something wrong, you get either an [[OpenGL Error]] or undefined behavior. With bindless textures, if you do something wrong, the GPU can ''crash'' or your program can terminate. It might even bring down the whole OS.
 
Things to keep in mind:
 
 
* When converting a handle into a sampler/image variable, the type of sampler/image must match with the handle.
 
* The integer values used with handles must be actual handles returned by the handle APIs, and those handles must be resident. So you can't perform "pointer arithmetic" or anything of the like on them; treat them as opaque values that happen to be 64-bit unsigned integers.
 
 
== Handle creation ==
 
{{todo}}
 
 
== Handle residency ==
 
{{todo}}
 
 
== GLSL handle usage ==
 
{{todo}}
 
 
== Extension implementation ==
 
 
This is not a core feature of any OpenGL version; at present, it only exists as an implementation. This is not for any of the reasons that an [[Ubiquitous Extension|extension might become ubiquitous]]. It is instead a matter of practicality.
 
 
If OpenGL 4.4 required bindless texture support, then only hardware that could support bindless textures could implement a conforming 4.4 implementation. But not all 4.3 hardware can handle bindless textures. The OpenGL ARB decided to make the functional optional by having it be an extension.
 
 
It is implemented across much of the OpenGL 4.x hardware spectrum. Intel is absent, but both AMD and NVIDIA have a lot of hardware that can handle it.
 
 
 
 
[[Category:Textures]]
 
{{infobox feature
 
| version =
 
| arb_extension = {{extref|bindless_texture}}
 
| vend_extension {{extref|bindless_texture|NV}}
 
}}
 
 
'''Bindless Textures''' are a method for passing [[Texture]]s (and [[Image Load Store|images]]) to [[Shader]] by name, rather than by binding them to the [[OpenGL Context]].
 
 
== Purpose ==
 
 
With [[Uniform Buffer Object]]s, [[Shader Storage Buffer Object]]s, and various other means, it is possible to communicate state information to a [[Shader]] without having to modify any OpenGL context state. You simply set data into the appropriate buffer objects. Then make sure that those buffers are bound when it comes time to render with the shader.
 
 
There are lines of communication for which this cannot work. Specifically, the [[Opaque Type]]s in GLSL: [[Sampler (GLSL)|samplers]], [[Image Load Store|images]], and [[Atomic Counter|atomic counters]]. These all derive their data based on objects bound to locations in the OpenGL context at the time of the rendering call.
 
 
This has two performance bearing consequences. The immediate performance cost is that you must bind textures and images to the context before rendering. This process has an intrinsic cost.
 
 
A second consequence is that you must issue more rendering calls. The reason being that you need to switch textures for different objects. If the objects could fetch which textures to use solely from memory (UBOs, SSBOs, etc), then one could render a number of objects with the same multi-draw [[Vertex Rendering|drawing command]]. Indeed, with [[Indirect Rendering]], it becomes possible to generate those rendering commands on the GPU. In a perfect world, this would reduce rendering to little more than a compute dispatch operation followed by a single multi-draw-indirect operation.
 
 
This can only work if the shader can get its textures from values in memory, rather than data bound to the context. This is the purpose of bindless texturing; to remove an obstacle that makes this possible.
 
 
== Overview ==
 
 
Bindless texturing is a bit complex. This represents a general overview of the process and the concepts that it uses.
 
 
=== Texture handles ===
 
 
The basic idea of bindless textures is to convert a [[Texture]] object into an integer (technically, [[OpenGL Object]]s are already integer numbers, but never mind that). This integer is called a ''handle'', and it is an unsigned, 64-bit integer.
 
 
{{note|The handle's value may or may not be an actual GPU address. You should not assume that it is, nor should you make any assumptions about its value relative to any other handle or anything else. Treat it as purely a reference.}}
 
 
Handles can be created from a [[Texture]] object alone. Such a handle refers to the texture using the sampler parameters within the texture object.
 
 
Handles can also be created from a [[Texture]] and [[Sampler Object]]. A handle created from a texture+sampler represents using that texture with that particular sampler object. Handles created by either one of these two processes are called ''texture handles''.
 
 
Lastly, handles can be created from a specific image within the texture. These are called ''image handles''. Image handles are intended to be used for [[Image Load Store]] operations, and cannot be used for regular sampler accesses. Similarly, texture handles or texture+sampler handles cannot be used for image load/store access.
 
 
Once an object has one (or more) handles associated with it (regardless of which kind of handle, texture or image), the object immediately becomes ''completely immutable''. No functions that modify anything about the texture will work. This includes the [[Sampler Object]] used in texture+sampler handles.
 
 
Furthermore, there is no way to undo this immutability. Once you get a handle that is associated with that object, it is permanently frozen.
 
 
Note that you can still create [[View Texture]]s from textures with handles. Similarly, views of a texture that uses a handle are still mutable (or at least, as mutable as an [[Immutable Storage Texture]] can be).
 
 
=== Residency ===
 
 
Once an appropriate handle is created, the handle cannot be used by any program until it is made resident. Texture and image handles use different residency functions, but the concept is the same.
 
 
Handles can remain resident for as long as you wish. Residency is removed with a separate function call.
 
 
=== Usage ===
 
 
The foundation of bindless texture usage is the ability of GLSL to convert a 64-bit unsigned integer texture handle value into a [[Sampler (GLSL)|sampler]] or [[Image (GLSL)|image]] variable. Thus, these types are no longer truly [[Opaque Type]]s, though the operations you can perform on them are still quite limited (no arithmetic for example).
 
 
Bindless texturing adds a number of features for communicating 64-bit integers to the API and to GLSL on the receiving end. It extends buffer-backed [[Interface Block]]s with the ability to store sampler/image types. From the OpenGL side, these are treated as 64-bit unsigned integers.
 
 
Bindless texturing also adds a few unique features for transmitting bindless handles to shaders. It adds a 64-bit unsigned integer [[Vertex Attribute]]. It also allows sampler and image types to be passed as inputs and outputs between [[Shader Stage]]s; they may only use {{code|flat}} interpolation qualifiers.
 
 
=== Safety ===
 
 
Bindless textures are not safe. The API is given fewer opportunities to ensure sane behavior; it is up to the programmer to maintain integrity. Furthermore, the consequences for mistakes are much more severe. Usually with OpenGL, if you do something wrong, you get either an [[OpenGL Error]] or undefined behavior. With bindless textures, if you do something wrong, the GPU can ''fail'' or your program can terminate. It might even bring down the whole OS.
 
  
 
Things to keep in mind:
 
Things to keep in mind:

Revision as of 21:46, 11 February 2015

Bindless Texture
ARB extension ARB_bindless_texture
Vendor extension NV_bindless_texture

Bindless Textures are a method for passing Textures to Shader by a name, rather than by binding them to the OpenGL Context. These texture can be used by samplers or images.

Purpose

With Uniform Buffer Objects, Shader Storage Buffer Objects, and various other means, it is possible to communicate state information to a Shader without having to modify any OpenGL context state. You simply set data into the appropriate buffer objects. Then make sure that those buffers are bound when it comes time to render with the shader.

There are lines of communication for which this cannot work. Specifically, the Opaque Types in GLSL: samplers, images, and atomic counters. These all derive their data based on objects bound to locations in the OpenGL context at the time of the rendering call.

This has two performance bearing consequences. The immediate performance cost is that you must bind textures and images to the context before rendering. This process has an intrinsic cost.

A second consequence is that you must issue more rendering calls. The reason being that you need to switch textures for different objects. If the objects could fetch which textures to use solely from memory (UBOs, SSBOs, etc), then one could render a number of objects with the same multi-draw drawing command. Indeed, with Indirect Rendering, it becomes possible to generate those rendering commands on the GPU. In a perfect world, this would reduce rendering to little more than a compute dispatch operation followed by a single multi-draw-indirect operation.

This can only work if the shader can get its textures from values in memory, rather than data bound to the context. This is the purpose of bindless texturing; to remove an obstacle that makes this possible.

Overview

Bindless texturing is a bit complex. This represents a general overview of the process and the concepts that it uses.

Texture handles

The basic idea of bindless textures is to convert a Texture object into an integer (technically, OpenGL Objects are already integer numbers, but never mind that). This integer is called a handle, and it is an unsigned, 64-bit integer.

Note: The handle's value may or may not be an actual GPU address. You should not assume that it is, nor should you make any assumptions about its value relative to any other handle or anything else. Treat it as purely a reference.

Handles can be created from a Texture object alone. Such a handle refers to the texture using the sampler parameters within the texture object.

Handles can also be created from a Texture and Sampler Object. A handle created from a texture+sampler represents using that texture with that particular sampler object. Handles created by either one of these two processes are called texture handles.

Lastly, handles can be created from a specific image within the texture. These are called image handles. Image handles are intended to be used for Image Load Store operations, and cannot be used for regular sampler accesses. Similarly, texture handles cannot be used for image load/store access.

Once an object has one (or more) handles associated with it (regardless of which kind of handle, texture or image), the object immediately becomes completely immutable. No functions that modify anything about the texture will work. This includes the Sampler Object used in texture+sampler handles.

Furthermore, there is no way to undo this immutability. Once you get a handle that is associated with that object, it is permanently frozen.

Note that you can still create View Textures from textures with handles. Similarly, views of a texture that uses a handle are still mutable (or at least, as mutable as an Immutable Storage Texture can be). Also, you can update the contents of the storage for such textures; just not their state.

Residency

Once an appropriate handle is created, the handle cannot be used by any program until it is made resident. Texture and image handles use different residency functions, but the concept is the same.

Handles can remain resident for as long as you wish. Residency is removed with a separate function call.

Note: Handle residency does not affect what operations can be performed on the texture/samplers involved. This however does not mean that residency is not cheap or unimportant. You should only maintain residency for handles that need it.

Usage

The foundation of bindless texture usage is the ability of GLSL to convert a 64-bit unsigned integer texture handle value into a sampler or image variable. Thus, these types are no longer truly Opaque Types, though the operations you can perform on them are still quite limited (no arithmetic for example).

Bindless texturing adds a number of features for communicating 64-bit integers to the API and to GLSL on the receiving end. It extends buffer-backed Interface Blocks with the ability to store sampler/image types. From the OpenGL side, these are treated as 64-bit unsigned integers.

Bindless texturing also adds a few unique features for transmitting bindless handles to shaders. It adds a 64-bit unsigned integer Vertex Attribute. It also allows sampler and image types to be passed as inputs and outputs between Shader Stages; they may only use flat interpolation qualifiers.

Safety

Bindless textures are not safe. The API is given fewer opportunities to ensure sane behavior; it is up to the programmer to maintain integrity. Furthermore, the consequences for mistakes are much more severe. Usually with OpenGL, if you do something wrong, you get either an OpenGL Error or undefined behavior. With bindless textures, if you do something wrong, the GPU can crash or your program can terminate. It might even bring down the whole OS.

Things to keep in mind:

  • When converting a handle into a sampler/image variable, the type of sampler/image must match with the handle.
  • The integer values used with handles must be actual handles returned by the handle APIs, and those handles must be resident. So you can't perform "pointer arithmetic" or anything of the like on them; treat them as opaque values that happen to be 64-bit unsigned integers.

Handle creation

Handle residency

GLSL handle usage

Extension implementation

This is not a core feature of any OpenGL version; at present, it only exists as an implementation. This is not for any of the reasons that an extension might become ubiquitous. It is instead a matter of practicality.

If OpenGL 4.4 required bindless texture support, then only hardware that could support bindless textures could implement a conforming 4.4 implementation. But not all 4.3 hardware can handle bindless textures. The OpenGL ARB decided to make the functional optional by having it be an extension.

It is implemented across much of the OpenGL 4.x hardware spectrum. Intel is absent, but both AMD and NVIDIA have a lot of hardware that can handle it.