home/ atoms/ ping-pong-buffer-pattern

The ping-pong pattern uses two alternating state buffers — one read-input, one write-output — to prevent in-place mutation corruption in GPU simulations

In GPU simulations, a compute shader cannot safely read from and write to the same buffer in the same dispatch because parallel invocations may overwrite data others have not yet read. The ping-pong pattern maintains two identically-sized state buffers (A and B): on odd steps read A, write B; on even steps read B, write A. Each step reads the fully-committed previous state. In WebGPU, implemented with two storage buffers and two bind groups that swap buffer roles, toggled by a step counter modulo 2.

Examples

const bindGroups = [
  device.createBindGroup({ entries: [{ binding: 1, resource: { buffer: cellStateStorage[0] } }, { binding: 2, resource: { buffer: cellStateStorage[1] } }] }),
  device.createBindGroup({ entries: [{ binding: 1, resource: { buffer: cellStateStorage[1] } }, { binding: 2, resource: { buffer: cellStateStorage[0] } }] }),
];
computePass.setBindGroup(0, bindGroups[step % 2]);

Assessment

Without ping-pong, why does a Game of Life compute shader that reads and writes the same buffer in one dispatch produce wrong results? Sketch the two-buffer solution at the bind-group level.

“Most simulations like the one you're building typically use at least _two_ copie”
corpus · your-first-webgpu-app-google-codelab · chunk 17