github gpujs/gpu.js 2.19.9

5 hours ago

Eight bug fixes, several of them long-standing, found by finally running the full browser suite on real GPUs and real Windows machines.

Fixed

  • Kernels indexing one array by another returned garbage on Windows (#300, open since 2018). lookup[input[this.thread.x]] compiles to a texture read nested inside another's argument list, and FXC — the HLSL compiler every Windows browser hands ANGLE's output to — miscompiles that shape: the outer read samples the wrong texture. The compiler now hoists the inner read into a temporary, the shape FXC gets right. This also fixes "integer division as index" kernels (array[a[x]/b[x]]), which were the same bug through a different door. Diagnosed down to the DXBC bytecode; workaround also submitted upstream to ANGLE (issue).
  • Every video passed to a WebGL kernel sampled arbitrary texels. The texture was sized from video.width/height — the presentational attributes, 0 on a detached element — instead of videoWidth/videoHeight, so the shader divided by a 0×0 size. Constant indices often looked right by luck; computed ones returned different garbage per run.
  • kernel.toString() dropped every else branch while flattening helper functions — regenerated kernels parsed, ran, and silently computed wrong answers. Also fixed in the same area: a crash on bare let x; declarations, expression-bodied arrow functions being corrupted, and mapped kernel outputs reading back as all zeros (the generated toArray() reused the draw framebuffer, where subkernel textures are still bound to other attachments).
  • The CPU backend read images and video a shade off — its readback canvas lacked willReadFrequently, so the browser kept it GPU-backed and getImageData wasn't bit-exact with the decoded image (253 came back 252). CPU and WebGL backends now agree exactly.
  • Internally-defined matrices couldn't be indexed dynamically on WebGL1getMatrix()[y][x] failed shader compilation with "Index expression can only contain const or loop symbols" (GLSL ES 1.00 restriction). The matrix is now walked with loop counters, which are legal index expressions; constant indices keep the direct form.
  • GPU.destroy() leaked WebGL contexts and kernels (from earlier in this cycle).
  • Bitwise NOT ignored the sign of its operand; / truncated to an integer divide on most desktop GPUs (from earlier in this cycle).

Build

  • gulp is gone: npm run make now runs plain Node scripts, bundling with rolldown instead of browserify.

Testing

The browser suite (3,699 tests, previously skipped in CI's Node-only run) now runs in real Chromium via Playwright (npm run test:browser), survives crashing tests instead of hanging, and runs on demand across BrowserStack's desktop matrix (npm run test:browserstack:qunit). Suite status: 0 failures on macOS Node, 0 on real Apple GPU, 0 on Windows Chrome and Edge on BrowserStack.

Don't miss a new gpu.js release

NewReleases is sending notifications on new releases.