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.WebGLKernelonly defaultedprecisionwhen float textures were available, so on such a device it stayednulland every kernel died withprecision missingorunhandled 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 === 0compiles again.getType()reported%as the left operand's type unlessfixIntegerDivisionAccuracywas set, but%never yields an integer: both GLSL helpers behind it returnfloat, and oncpuit stays a JS%. Typingi % 2asIntegeremitted 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.bitwiseSignedRightShiftdivided bypow(2.0, shifts), andpowis approximate on most GPUs — usuallyexp2(y * log2(x)). Landing ~1 ulp high made the quotient fall just short of a whole number, whichfloor()then discarded:2 >> 1returned0,8 >> 1returned3,8 >> 3returned0.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:browserstackruns it locally against your working copy over a tunnel, so the devices exercise the build you have rather than a published one. test/all.htmlnow 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.sqrtABno longer asserts exact equality onMath.sqrt. GLSL ES allowssqrtup 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