Task 4 of 5

Feedback Loops: immutable Textures

Simulations don't run once — they step: the output of step n is the input of step n+1. With pipelines that means feeding a kernel its own texture back. Try it naively and gpu.js stops you cold — the kernel would be reading the very storage it is writing to, and every backend refuses. WebGL puts it as "Source and destination … are the same. Use immutable = true"; WebGPU says the argument "is this kernel's own output buffer". Same crime, and the same fix.

immutable: true is the fix: each call renders to a fresh texture instead of recycling one, so last step's output is safe to read while this step writes. (In long-running sims you'd call texture.delete() on old steps to recycle their memory — at 128 cells here, we'll let them slide.)

Below is a 1D heat field: 128 cells, all cold except one hot spike. One diffusion step moves each cell toward its neighbours. Twelve steps stay entirely on the GPU — one upload at the start, one download at the end.

immutable: true — a fresh texture per step makes feedback legal
Goal: make the feedback loop legal — the step kernel needs immutable: true — and run 12 diffusion steps without the heat ever visiting JavaScript.

Requirements

Hint 1 — read the error message

Run the starter as-is. The error names the crime: this kernel's input is its own output storage. On WebGL it names the sentence too — immutable = true; on WebGPU it only tells you the buffer is the kernel's own, and immutable: true is still the fix. Either way, the second step of the loop is where it fires: the first step reads upload's texture, which is somebody else's.

Hint 2 — why upload() exists

The tiny upload kernel copies the seed array into a texture once, so step always sees texture inputs from its very first call. Keeping argument types stable means the kernel compiles exactly once.

Hint 3 — the one-word diff

In step's settings:

{ output: [128], pipeline: true, immutable: true }

The loop is already correct.

Same idea elsewhere

Every GPU API solves read-write hazards the same way gpu.js just made you do: ping-pong buffering. WebGPU compute passes swap two storage buffers each dispatch, CUDA stencil codes swap in/out device pointers, Metal simulations flip between two textures. immutable: true is ping-ponging with the bookkeeping done for you.

All tasks in Pipelines & Textures

  1. Flip On the Pipeline
  2. Chain Kernels, Skip the Round Trip
  3. toArray() Is a Tollbooth
  4. Feedback Loops: immutable Textures
  5. The Payoff: Photo to Screen, Zero Readbacks

This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.