Skip to content

CPU fallback for compute shaders when WebGPU is unavailable #9223

Description

@skyyash

Context:
#9175 for WebGPU to WebGL fallback so sketches reach more browsers. #9191 covered the first part: createCanvas(..., WEBGPU) falls back to WebGL, adds rendererType, and fails early on createStorage, buildComputeShader, compute when not in WebGPU.

the followup from #9175 is: can we run compute shaders on CPU as a fallback, possibly with a smaller particle count.

Goals:

particles = createStorage(data)
computeShader = buildComputeShader(simulate)
compute(computeShader, N)
  • User code should stay the same.
  • When running in WebGL (or 2d?) mode, compute should fall back to the CPU instead of failing.
  • Performance will be much lower, so the system should automatically use fewer items (particles, cells, etc.).

Approaches considered

  1. Runtime dual-mode objects
    createStorage, buildComputeShader and compute() detect the current renderer. on WebGPU they use the real GPU path. on other renderers they use a CPU path.

  2. Dual compilation / JS backend
    p5.strands already has separate backends (strands_glslBackend.js, strands_wgslBackend.js). adding a strands_jsBackend.js that evaluates the IR (or lowers it to plain JavaScript) instead of emitting shader source?

  3. Full source-to-source rewriting of the sketch (its where i begin thinking, lets just ignore this approach. unnecessary)

I guess we might need some combination of 1 and 2.


Note:
the function passed to buildComputeShader is not normal runnable js. when strands executes it, it builds IR. simply calling that function in a for loop does nothing useful. therefore we might need:

  • an interpreter that walks the IR, or
  • a js backend that turns the IR into executable js.

  • is it viable and also aligned with the project goals?
  • how aggressively should we reduce the number of particles/cells on the cpu path? fixed limit?based on device?
  • should the js backend interpret the ir directly, or lower it once to a normal js function?
  • how much of the strands feature set do we need to support on cpu?
  • where should the dual-mode logic live so it stays maintainable across RendererGL and RendererWebGPU?
  • how should uniformStorage used inside material and filter shaders behave in WebGL when data lives on CPU.

thoughts welcome.

EDIT: this is roughly the behavior we want the fallback to produce internally: https://editor.p5js.org/skyash/sketches/8McCWmdSl

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions