Skip to content

Webgpu variable length buffer - #9086

Open
davepagurek wants to merge 15 commits into
mainfrom
webgpu-variable-length-buffer
Open

Webgpu variable length buffer#9086
davepagurek wants to merge 15 commits into
mainfrom
webgpu-variable-length-buffer

Conversation

@davepagurek

Copy link
Copy Markdown
Contributor

Resolves #9081

Changes:

  • Introduces createStorageList, which is like createStorageBuffer but is variable-length, where you call .push() on it rather than just writing to indices
  • Lets you pass a storage list to instances() to draw that many items

PR Checklist

@davepagurek
davepagurek marked this pull request as draft August 16, 2026 14:02
@davepagurek
davepagurek marked this pull request as ready for review August 16, 2026 21:06
@davepagurek

Copy link
Copy Markdown
Contributor Author

@aashu2006 lmk what you think of the design decisions here!

@aashu2006

aashu2006 commented Aug 18, 2026

Copy link
Copy Markdown
Member

@davepagurek I had a read, the indirect draw path is really nice copying the atomic length straight into instanceCount and never round tripping to the cpu is exactly the right call

two things that look like bugs

instances(storageBuffer) uses .size not .length

3d_primitives.js:2704 does count = count.size, which is the 16 byte aligned byte length, not the element count. .length is right there on the constructor so looks like a slip. The visual test uses a struct buffer so it might still land onscreen, a flat Float32Array one would show it right away

overflow counter reaches the indirect draw unclamped

_p5_push_* does atomicAdd unconditionally and only guards the store, so the counter climbs past maxCapacity even though nothing gets written. read() clamps with Math.min(..., maxCapacity), but the copyBufferToBuffer into instanceCount copies the raw counter. So an overflowing list draws more instances than exist and reads uninit data. read and draw should probably agree here

heads up on #9083

this adds length as the 5th constructor param on StorageBuffer, mine adds arrayType in the same slot. whichever lands second clobbers the other

the spreading fix

that one's on me. the stride used px but the real dispatch width is ceil(px/8)*8, so rows overlapped whenever ceil(sqrt(N)) wasn't a multiple of 8. fix looks right and N=2500 hits it squarely

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Variable-length storage buffers for WebGPU

2 participants