GLSL ES lowp Precision for Float and Integer Qualifiers

In the OpenGL ES Shading Language (GLSL ES), precision qualifiers allow developers to balance mathematical accuracy and performance on mobile hardware. This article examines the minimum precision and range guarantees provided by the lowp qualifier for both floating-point and integer types under the official GLSL ES specifications, alongside practical hardware implementation details across mobile GPUs.

Guaranteed Precision for lowp Float

According to the GLSL ES specifications (versions 1.00 through 3.20), the lowp floating-point type provides the following minimum guarantees:

  • Value Range: At least \([-2.0, 2.0]\)
  • Relative Precision: At least \(2^{-8}\) (approximately \(0.00390625\), or roughly 8 bits of fractional precision)

Because the standard only mandates a minimum range of \([-2.0, 2.0]\), lowp float is fundamentally designed for storing and operating on normalized color data (such as standard RGBA values between \(0.0\) and \(1.0\)). Attempting to use lowp float for coordinate calculations, UV mapping, or world positions will frequently result in severe visual artifacts or clamping due to range exhaustion.

Guaranteed Precision for lowp Integer

For integer types, GLSL ES defines lowp as a signed representation with the following minimum guarantees:

  • Value Range: At least \([-2^8, 2^8 - 1]\), which evaluates to \([-256, 255]\)
  • Precision: Exact integer steps of \(1.0\) across the supported range (requiring at least a 9-bit signed integer representation)

The lowp int qualifier is intended for small loops, array indexing within small buffers, and basic state flags. Exceeding values above \(255\) or below \(-256\) results in undefined behavior or integer overflow on conforming hardware.

Mobile Hardware Implementations

While the GLSL ES specification outlines the minimum acceptable baseline, actual mobile silicon often promotes lowp to higher precisions to simplify hardware arithmetic units:

  • Qualcomm Adreno: Modern Adreno architectures generally process lowp arithmetic using standard 16-bit floating-point (mediump) or 32-bit floating-point (highp) pipelines.
  • ARM Mali: Mali Bifrost and Valhall architectures primarily operate on 16-bit (mediump) and 32-bit (highp) registers, promoting lowp operations to 16-bit execution.
  • Apple GPUs: Apple silicon natively executes half-precision 16-bit floats for any precision qualifier below 32-bit, meaning lowp operations are transparently promoted to 16-bit float.
  • Imagination PowerVR: Historically, certain PowerVR architectures featured dedicated low-precision arithmetic hardware (such as 10-bit formats), directly reflecting the minimum specification constraints.

Relying on hardware promotion is dangerous for cross-platform shaders. If a shader relies on values outside the \([-2.0, 2.0]\) range for floats or \([-256, 255]\) for integers, it may function properly on devices that promote lowp to 16-bit while failing or clamping on devices that adhere strictly to the minimum GLSL ES specification.