github gpujs/gpu.js 2.19.8

4 hours ago

Real device testing, and the bugs it found.

This release is the result of putting GPU.js on real phones and desktop browsers for the first time, via BrowserStack. Every fix below is for a bug no CI runner could have caught, because each one only reproduces on hardware.

Fixed

  • GPU.js no longer throws on every kernel on WebGL1 devices without OES_texture_float. WebGLKernel only defaulted precision when float textures were available, so on such a device it stayed null and every kernel died with precision missing or unhandled precision of "null". The backend was unusable rather than degraded, with no fallback.

    Those devices cannot do single precision, but unsigned needs no float extension at all, so it now falls back to it — matching WebGL2Kernel, which already defaulted unconditionally. Found on a Google Pixel 7 (Chrome, Android 13), where all 12 WebGL1 smoke tests failed and now pass.

  • i % 2 === 0 compiles again. getType() reported % as the left operand's type unless fixIntegerDivisionAccuracy was set, but % never yields an integer: both GLSL helpers behind it return float, and on cpu it stays a JS %. Typing i % 2 as Integer emitted a float/int comparison that GLSL rejects outright:

    '==' : no operation '==' exists that takes a left-hand operand of
    type 'lowp float' and a right operand of type 'const int'
    

    The flag is derived from GPU features, so this broke on desktop Chrome, Firefox and Edge on Windows — but never on headless-gl or Apple GPUs, which is why the suite never saw it. / is unchanged: with the flag off it really is an integer division in GLSL.

  • >> no longer loses a bit on even operands. bitwiseSignedRightShift divided by pow(2.0, shifts), and pow is approximate on most GPUs — usually exp2(y * log2(x)). Landing ~1 ulp high made the quotient fall just short of a whole number, which floor() then discarded: 2 >> 1 returned 0, 8 >> 1 returned 3, 8 >> 3 returned 0.

    Only even left operands were affected; odd ones carry enough of a fraction to absorb the error, which made the breakage look arbitrary. It now uses _pow2, the exact constant-multiply helper already added for the same class of bug in the float packing (#659), in both the WebGL1 and WebGL2 shaders.

Testing

  • GPU.js is now tested on real iOS and Android devices and desktop browsers on BrowserStack, on every push. npm run test:browserstack runs it locally against your working copy over a tunnel, so the devices exercise the build you have rather than a published one.
  • test/all.html now reports results machine-readably. QUnit's HTML output misses failures raised before its reporter initialises, so errors thrown while test files load went unreported entirely.
  • sqrtAB no longer asserts exact equality on Math.sqrt. GLSL ES allows sqrt up to 2 ULP of error — unlike + - * / it is not required to be correctly rounded — so exact equality was never a property GPU.js could offer. It now compares within 2 ULP.

The macOS suite goes from 12 failures to 3; the remainder are the Infinity encoding family.

Installing

npm install gpu.js@2.19.8

Don't miss a new gpu.js release

NewReleases is sending notifications on new releases.