GL_ARB_gpu_shader_fp64: 64-Bit Floats in GLSL

The GL_ARB_gpu_shader_fp64 extension introduces native 64-bit double-precision floating-point arithmetic to the OpenGL Shading Language (GLSL). By adding dedicated scalar, vector, and matrix types alongside matching mathematical built-ins, this extension allows graphics and compute pipelines to process high-precision data directly on the GPU without custom multi-pass emulations. This article details the syntax, memory mechanics, vector configurations, and operational trade-offs of using 64-bit floating-point vectors in GLSL.

Enabling the Extension

To use 64-bit floating-point constructs in GLSL, the shader stage must explicitly declare support for the extension at the top of the source file:

#version 400 core
#extension GL_ARB_gpu_shader_fp64 : require

While core OpenGL 4.0 and later versions integrated this feature natively, enabling it via the extension directive ensures backward compatibility and explicit compiler enforcement on hardware supporting the extension.

64-Bit Types and Vector Definitions

Prior to this extension, GLSL handled floating-point operations using 32-bit single precision (float, vec2, vec3, vec4). GL_ARB_gpu_shader_fp64 introduces the 64-bit scalar type double and corresponding vector types:

  • dvec2: A two-component vector of 64-bit floats (128 bits total).
  • dvec3: A three-component vector of 64-bit floats (192 bits total).
  • dvec4: A four-component vector of 64-bit floats (256 bits total).

Double-precision floating-point literals are identified with the lf or LF suffix:

double scalarVal = 1.0lf;
dvec3 precisePosition = dvec3(100000.123456789lf, 200000.987654321lf, 0.0lf);

The extension also introduces double-precision matrices, such as dmat2, dmat3, dmat4, and non-square variants like dmat3x2.

Register Allocation and Varying Locations

Under standard 32-bit floating-point processing, a vector register typically contains four 32-bit channels (128 bits per slot). Because double values require 64 bits per component, hardware packing rules change significantly:

  1. Component Consumption: A dvec2 consumes the space of a single 32-bit four-component slot (vec4). A dvec3 or dvec4 spans across two separate 32-bit four-component input/output locations.
  2. Varyings and Interpolation: When passing dvec variables between pipeline stages (e.g., from vertex to fragment shader), they consume twice as many varying locations. Flat interpolation is commonly enforced, as perspective-correct interpolation of 64-bit attributes requires dedicated hardware support and may incur performance penalties.

Built-In Functions and Overloads

GL_ARB_gpu_shader_fp64 overloads most core GLSL mathematical functions to accept double and dvec parameters, including:

  • Geometric Functions: length(), distance(), dot(), cross(), and normalize().
  • Common Functions: abs(), sign(), floor(), ceil(), fract(), min(), max(), clamp(), and mix().
  • Exponential and Trigonometric: sqrt(), inversesqrt(), and trigonometric operations where supported by hardware.

Explicit conversions between 32-bit and 64-bit types are fully defined. Converting a vec4 to a dvec4 promotes each component to double precision, while casting a dvec4 to a vec4 truncates the mantissa:

dvec4 highPrec = dvec4(1.0lf);
vec4 lowPrec = vec4(highPrec); // Explicit downcast

Performance and Hardware Considerations

While GL_ARB_gpu_shader_fp64 provides precision essential for planetary-scale rendering (GIS), scientific simulations, and ray tracing, it alters pipeline throughput:

  • Compute Rate: Consumer GPUs often have a restricted ratio of FP64 to FP32 execution units (often 1:32 or 1:16), making double-precision calculations considerably slower than single-precision equivalents.
  • Register Pressure: Double-precision vectors double register usage, reducing the total active warps/wavefronts (occupancy) on the GPU multiprocessors.

Best practices recommend isolating dvec calculations to operations where numerical instability is critical—such as camera translation matrices relative to distant origins—and downcasting to standard single-precision vectors (vec3, vec4) for shading and rasterization.