Skip to content

feat: Buffer views - #3271

Draft
reczkok wants to merge 5 commits into
mainfrom
feat/wgsl-buffer-view
Draft

reczkok wants to merge 5 commits into
mainfrom
feat/wgsl-buffer-view

Conversation

@reczkok

@reczkok reczkok commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

(FYI this is not the feature discussed in #2816 proposal, this is the actual WebGPU feature)
d.bytes(n) resolves to the WGSL buffer<n> type, and std.bufferView, std.bufferArrayView and std.bufferLength read and write its bytes as any host-shareable type at runtime offsets

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

pkg.pr.new

packages
Ready to be installed by your favorite package manager ⬇️

https://pkg.pr.new/software-mansion/TypeGPU/typegpu@45d9dd2e0ad25b3e4227b15809c11a13281a7ccf
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/gl@45d9dd2e0ad25b3e4227b15809c11a13281a7ccf

benchmark
view benchmark

commit
view commit

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Resolution Time Benchmark

---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.76, 1.46, 3.14, 4.74, 5.58, 9.73, 19.60, 17.48]
  line [0.77, 1.44, 2.92, 5.28, 5.97, 8.80, 19.46, 19.88]
  line [0.77, 1.50, 3.17, 4.98, 6.06, 9.61, 18.64, 16.43]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.21, 0.38, 0.55, 0.65, 0.91, 1.01, 1.20, 1.37]
  line [0.24, 0.42, 0.59, 0.70, 0.88, 0.90, 1.07, 1.25]
  line [0.26, 0.42, 0.61, 0.69, 0.92, 0.98, 1.16, 1.26]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.79, 1.72, 2.75, 5.36, 10.26, 20.65, 42.67, 89.29]
  line [0.74, 1.67, 2.67, 5.22, 9.41, 19.85, 43.31, 87.44]
  line [0.61, 1.69, 3.09, 6.00, 9.73, 20.29, 42.88, 89.77]
Loading

@github-actions

Copy link
Copy Markdown

Bundle size comparison (import * as ... in PR vs import * as ... in target):

🟢 Decreased ➖ Unchanged 🔴 Increased (max 12.84%) ❔ Unknown
0 312 43 4

import * as ... in PR vs import * as ... in target (did bundle size increase?):

Test tsdown
STATIC_std.ts 114.58 kB ($${\color{red}+12.8\%}$$)
d_struct.ts 4.01 kB ($${\color{red}+4.7\%}$$)
STATIC_allImports.ts 319.70 kB ($${\color{red}+1.4\%}$$)
STATIC_d.ts 72.00 kB ($${\color{red}+1.0\%}$$)
tgpu_resolveWithContext.ts 161.78 kB ($${\color{red}+0.9\%}$$)
tgpu_resolve.ts 161.84 kB ($${\color{red}+0.9\%}$$)
d_arrayOf.ts 33.72 kB ($${\color{red}+0.7\%}$$)
d_builtin.ts 36.19 kB ($${\color{red}+0.7\%}$$)
tgpu_initFromDevice.ts 256.84 kB ($${\color{red}+0.7\%}$$)
tgpu_init.ts 257.38 kB ($${\color{red}+0.7\%}$$)
STATIC_tgpu.ts 268.61 kB ($${\color{red}+0.7\%}$$)
common_fullScreenTriangle.ts 48.82 kB ($${\color{red}+0.5\%}$$)
d_bytes.ts 1011 B
std_bufferArrayView.ts 40.15 kB
std_bufferLength.ts 41.29 kB
std_bufferView.ts 40.15 kB

If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.

@reczkok

reczkok commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

@pullfrog do a preliminary review

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one minor validation gap worth a look.

Reviewed changes

  • d.bytes(n) schema (data/bytes.ts) — new WgslBuffer schema resolving to WGSL buffer<n> (or runtime-sized buffer for 0), with size/alignment/equality/layout/serialization wiring and struct/array/address-space guards.
  • std.bufferView / std.bufferArrayView / std.bufferLength (std/bufferView.ts) — codegen-only builtins that reinterpret buffer bytes as host-shareable types, with alignment, fit, atomic, host-shareable and scope validation, plus std exports.
  • buffer_view language-feature plumbing (resolutionCtx.ts, wgslExtensions.ts, resolveData.ts, types.ts) — requireLanguageFeature and a requires buffer_view; directive emitted ahead of the module.
  • For-of over pointer iterables (tgsl/forOfUtils.ts) — getRangeSnippets now unwraps pointer data types (enables iterating a bufferView-returned array).
  • Docs + example + tests — new buffer-views.mdx, the shape-stream example, and bytes/bufferView/serialization/generator tests.

I read the full diff, verified the relevant source paths (dualImpl, pinEref, ptr, array, resolveData, forOfUtils, dataIO, compiledIO, schemaMemoryLayout, schemasEqual), ran the new tests (bytes, std/bufferView, serializeDataSchema), the tgsl suite, and tsc --noEmit — all pass. I also checked the claims against the WGSL spec: the requires buffer_view; directive/feature name is correct, directive ordering relative to enable is unconstrained, and the alignment/MinTypeSize/invalid-pointer semantics line up with assertViewFits/minSizeOf.

The buffer<N> size rule is the one gap I found; detail inline.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment on lines +67 to +68
export function bytes(byteSize = 0): WgslBuffer {
if (!Number.isInteger(byteSize) || byteSize < 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export function bytes(byteSize = 0): WgslBuffer {
if (!Number.isInteger(byteSize) || byteSize < 0) {
export function bytes(byteSize = 0): WgslBuffer {
if (!Number.isInteger(byteSize) || byteSize < 0) {
throw new Error(`Cannot create a buffer schema of ${byteSize} bytes.`);
}
if (byteSize !== 0 && byteSize % 2 !== 0) {
throw new Error(
`Cannot create a buffer schema of ${byteSize} bytes, WGSL requires a buffer size to be a multiple of 2.`,
);
}",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disregard the auto-suggestion above — its 2-line range was wrong and would leave a duplicate throw behind. The intended change is simply to reject sizes WGSL can't represent: after the existing integer/negative check in bytes(), add if (byteSize !== 0 && byteSize % 2 !== 0) throw new Error(...), and ideally a resolution-time % 4 check when f16 is disabled (WGSL allows buffer<N> only for N a multiple of 4, or of 2 when f16 is enabled; d.bytes(6) currently emits buffer<6>, a shader-creation error).

Pullfrog  | View workflow run | via Pullfrog | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@reczkok
reczkok force-pushed the feat/wgsl-buffer-view branch from 79f03d5 to 45d9dd2 Compare October 24, 2026 18:45
@reczkok
reczkok added this pull request to stack #3273 October 24, 2026 18:46

This branch has not been deployed

No deployments
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.

1 participant