Understanding GL_ARB_gpu_shader_int64 in GLSL

The GL_ARB_gpu_shader_int64 extension introduces native 64-bit signed and unsigned integer arithmetic and data types to the OpenGL Shading Language (GLSL). This article explains the primary functions of this extension, the specific data types and operators it provides, how it interfaces with the host OpenGL API, and its practical use cases in high-precision GPU computing.

Core Function and Data Types

Prior to the introduction of GL_ARB_gpu_shader_int64, GLSL natively supported only 32-bit integers (int and uint). Performing 64-bit arithmetic required complex software-based emulation using pairs of 32-bit integers, which added significant instruction overhead and reduced performance.

The primary function of GL_ARB_gpu_shader_int64 is to eliminate the need for emulation by exposing true 64-bit integer processing directly on compatible GPU hardware. To use this functionality, the extension is declared in the shader:

#extension GL_ARB_gpu_shader_int64 : require

Once enabled, the extension defines several new scalar and vector types:

  • Scalars: int64_t (signed 64-bit integer) and uint64_t (unsigned 64-bit integer).
  • Vectors: i64vec2, i64vec3, i64vec4 for signed vectors, and u64vec2, u64vec3, u64vec4 for unsigned vectors.

The extension also introduces standard 64-bit integer literal suffixes, allowing developers to define constants explicitly using l or L for signed values (e.g., 42L), and ul, uL, Ul, or UL for unsigned values (e.g., 1000UL).

Operations and Built-in Functions

The extension extends the standard GLSL operators to support 64-bit types seamlessly:

  • Arithmetic Operations: Addition, subtraction, multiplication, division, and modulo (+, -, *, /, %).
  • Bitwise Operations: Shifts, bitwise AND, OR, XOR, and NOT (<<, >>, &, |, ^, ~).
  • Relational and Equality Comparisons: Standard relational evaluations (<, >, <=, >=, ==, !=).

In addition to operators, common built-in math functions are overloaded to accept 64-bit integers. These include functions such as abs(), sign(), min(), max(), and clamp(). Specialized bit-manipulation built-ins—such as bitfieldExtract(), bitfieldInsert(), bitfieldReverse(), and bitCount()—are also updated to process 64-bit scalar and vector inputs.

CPU-to-GPU API Integration

GL_ARB_gpu_shader_int64 is not strictly confined to shader code; it extends the OpenGL API to allow host applications to transfer 64-bit integer data directly to uniform locations and vertex attributes.

Key API additions include:

  • Uniform Commands: Functions like glUniform1i64ARB, glUniform4ui64ARB, and their vector/array variants allow direct upload of 64-bit integer values into shader uniform variables.
  • Vertex Attributes: Vertex buffers can specify 64-bit integer vertex data using glVertexAttribLFormat or glVertexAttribLPointer (introduced via the ARB_vertex_attrib_64bit family of features), ensuring that data is passed to the vertex shader without precision loss or cast conversion to floating-point values.

Primary Use Cases

  1. 64-Bit Memory Addressing and Bindless Resources: Modern GPU techniques often rely on direct GPU memory pointers (such as bindless textures or GPU virtual addresses). These 64-bit pointers can be stored, shifted, masked, and dereferenced inside shaders using uint64_t.
  2. High-Precision Counters and Timers: Applications tracking nanosecond-precision timestamps, large iteration loops, or persistent global counters in compute shaders require 64-bit ranges to prevent integer overflow.
  3. Cryptography and Hashing: Cryptographic algorithms (such as SHA-512) and non-cryptographic hashing algorithms (such as MurmurHash64 or xxHash) rely heavily on 64-bit bitwise manipulation and modular arithmetic.
  4. Scientific and Geographic Computing: Coordinate systems requiring planetary scale with millimeter accuracy often exceed the 24-bit precision limit of single-precision floats and the range of 32-bit integers. Combining 64-bit integers with fixed-point arithmetic enables massive coordinate spaces inside the shader pipeline.