What Built-In Bitwise Functions Does GLSL Support?

Modern GLSL provides a dedicated set of hardware-accelerated integer functions designed for advanced bit-level manipulation, supplementing standard C-style bitwise operators. Introduced with GLSL 4.00 and OpenGL ES 3.10 (via GL_ARB_gpu_shader5), these built-in functions operate component-wise on signed and unsigned 32-bit scalars (int, uint) and integer vector types (ivec2–ivec4, uvec2–uvec4). Below is an overview of the core bitwise manipulation functions available in modern GLSL.

Core Bitfield Operations

  • bitfieldExtract(value, offset, bits): Extracts a consecutive range of bits starting at offset for a length of bits, shifting the extracted sequence down to the least significant bit (LSB) position. For unsigned integers, higher-order bits are zero-extended; for signed integers, they are sign-extended based on the most significant bit of the extracted field.
  • bitfieldInsert(base, insert, offset, bits): Inserts the lowest bits from insert into base starting at offset, preserving all other bits of base.
  • bitfieldReverse(value): Reverses the order of all bits across the 32-bit integer, swapping the positions of the most significant and least significant bits.

Bit Inspection and Counting

  • bitCount(value): Computes the population count (popcount), returning the total number of bits set to 1 across the integer.
  • findLSB(value): Scans for the least significant bit set to 1 and returns its zero-based index (from 0 to 31). Returns -1 if the input is 0.
  • findMSB(value): Scans for the most significant bit. For unsigned integers and positive signed integers, it returns the index of the highest 1 bit; for negative signed integers, it returns the index of the highest 0 bit. Returns -1 if no such bit exists (e.g., unsigned 0 or signed -1).

Extended Arithmetic and Carry Handling

Modern GLSL also incorporates extended arithmetic routines to assist with multi-precision integer operations:

  • uaddCarry(x, y, out carry): Adds two unsigned integers, returning the low 32 bits and outputting the carry-out value (0 or 1) through the carry parameter.
  • usubBorrow(x, y, out borrow): Subtracts y from x, returning the low 32 bits and writing the borrow flag (0 or 1) to borrow.
  • umulExtended(x, y, out msb, out lsb) / imulExtended(x, y, out msb, out lsb): Multiplies two 32-bit integers, outputting the full 64-bit result split across the upper msb and lower lsb output variables.