Repository navigation
feat: Buffer views - #3271
feat: Buffer views#3271reczkok wants to merge 5 commits into
Conversation
|
pkg.pr.new packages benchmark commit |
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]
---
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]
---
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]
|
Bundle size comparison (
|
| 🟢 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 ( |
| d_struct.ts | 4.01 kB ( |
| STATIC_allImports.ts | 319.70 kB ( |
| STATIC_d.ts | 72.00 kB ( |
| tgpu_resolveWithContext.ts | 161.78 kB ( |
| tgpu_resolve.ts | 161.84 kB ( |
| d_arrayOf.ts | 33.72 kB ( |
| d_builtin.ts | 36.19 kB ( |
| tgpu_initFromDevice.ts | 256.84 kB ( |
| tgpu_init.ts | 257.38 kB ( |
| STATIC_tgpu.ts | 268.61 kB ( |
| common_fullScreenTriangle.ts | 48.82 kB ( |
| 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.
|
@pullfrog do a preliminary review |
There was a problem hiding this comment.
ℹ️ No critical issues — one minor validation gap worth a look.
Reviewed changes
d.bytes(n)schema (data/bytes.ts) — newWgslBufferschema resolving to WGSLbuffer<n>(or runtime-sizedbufferfor 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, plusstdexports.buffer_viewlanguage-feature plumbing (resolutionCtx.ts,wgslExtensions.ts,resolveData.ts,types.ts) —requireLanguageFeatureand arequires buffer_view;directive emitted ahead of the module.- For-of over pointer iterables (
tgsl/forOfUtils.ts) —getRangeSnippetsnow unwraps pointer data types (enables iterating abufferView-returned array). - Docs + example + tests — new
buffer-views.mdx, theshape-streamexample, andbytes/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.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
| export function bytes(byteSize = 0): WgslBuffer { | ||
| if (!Number.isInteger(byteSize) || byteSize < 0) { |
There was a problem hiding this comment.
| 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.`, | |
| ); | |
| }", |
There was a problem hiding this comment.
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).
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
79f03d5 to
45d9dd2
Compare

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