Image Load Store
|Core in version||4.5|
|Core since version||4.2|
|Core ARB extension||ARB_shader_image_load_store|
Image load/store is the ability of Shaders to more-or-less arbitrarily read from and write to images.
|This article is a stub. You can help the OpenGL Wiki by expanding it.|
The idea with image load/store is that the user can bind one of the images in a Texture to a number of image binding points (which are separate from texture image units). Shaders can read information from these images and write information to them, in ways that they cannot with textures.
This can allow for a number of powerful features, including relatively cheap order-independent transparency.
If you think that this is a great feature, remember that there is no such thing as a free lunch. The cost of using image load/store is that all of its write operations are not automatically coherent. By using image load/store, you take up the responsibility to manage what OpenGL would manage for you using regular texture reads/FBO writes.
Image variables are variables that have one of the following image types. The image types are based on the type of the source Texture for the image. Not all texture types have a separate image type. Image variables must be declared with the uniform storage qualifier (or as function parameter inputs).
Like samplers, image variables represent either floating-point, signed integer, or unsigned integer Image Formats. The prefix used for the image variable name denotes which, using standard GLSL conventions. No prefix means floating-point, a prefix of i means signed integer, and u means unsigned integer.
For the sake of clarity, when you see a g preceding "image" in an image name, it represents any of the 3 possible prefixes. The image variables are:
|Image Type||Corresponding Texture Type|
|gimageCubeArray||GL_TEXTURE_CUBE_MAP_ARRAY (requires GL 4.0 or ARB_texture_cube_map_array)|
There are no "shadow" variants.
Image variables can be declared with a number of qualifiers that have different meanings for how the variable is accessed.
- Normally, the compiler is free to assume that this shader invocation is the only invocation that modifies values read through this variable. It also can freely assume that other shader invocations may not see values written through this variable.
- Using this qualifier is required to allow dependent shader invocations to communicate with one another, as it enforces the coherency of memory accesses. Using this requires the appropriate memory barriers to be executed, so that visibility can be achieved.
- When communicating between shader invocations for different rendering commands, glMemoryBarrier should be used instead of this qualifier.
- The compiler normally is free to assume that values accessed through variables will only change after memory barriers or other synchronization. With this qualifier, the compiler assumes that the contents of the storage represented by the variable could be changed at any time.
- Normally, the compiler must assume that you could access the same image/buffer object through separate variables in the same shader. Therefore, if you write to one variable, and read from a second, the compiler assumes that it is possible that you could be reading the value you just wrote. With this qualifier, you are telling the compiler that this particular variable is the only variable that can modify the memory visible through that variable within this shader invocation (other shader stages don't count here). This allows the compiler to optimize reads/writes better.
- You should use this wherever possible.
- Normally, the compiler allows you to read and write from variables as you wish. If you use this, the variable can only be used for reading operations.
- Normally, the compiler allows you to read and write from variables as you wish. If you use this, the variable can only be used for writing operations (atomic writes are forbidden because they also count as reads).
Image variables can be declared with a format qualifier. Not all image variables must use a format qualifier, but they are required if you do not declare the variable with the writeonly memory qualifier. Write-only variables cannot be used as in any reading operations; this includes calling load and atomic (read/modify/write) functions. So if you want to read from an image, you must declare the format.
The format defines how the shader interprets the bits of data that it reads from the image. It also defines how it converts the data passed for write operations when it writes it into the image.
The format are divided into three categories, representing the three types of image variables:
- Floating-point layout image formats:
- Signed integer layout image formats:
- Unsigned integer layout image formats:
Image variables can have a format layout qualifier. It defines the image format used for reading from that variable. Image variables used only for reading do not need a format qualifier, but if they are used for writes or certain atomic operations, they must have a format qualifier. Also, if they are declared with readonly, then they must have the format qualifier.
The format qualifier specifies how data read from the image looks in OpenGL. It allows the image's actual Image Format to differ from the format qualifier in the shader. This allows the GLSL shader to reinterpret the meaning of the data in the image. Writes can also be re-interpreted in this manor, but only if a format is specified. If no format is specified, then the writes will be interpreted as if the format matched the image's actual image format.
The valid image formats
Images in the context
The way to associate an image variable in GLSL works very similar to the way of associating samplers with textures.
Basic load store
Writes and atomic operations via image variables are not automatically coherent. Therefore, you must do things to ensure that writes have occurred before you can read those values.