Skip to content

impr: Read v3 function metadata - #3245

Draft
iwoplaza wants to merge 1 commit into
impr/bare-numeric-literalsfrom
impr/metadata-v3-runtime
Draft

iwoplaza wants to merge 1 commit into
impr/bare-numeric-literalsfrom
impr/metadata-v3-runtime

Conversation

@iwoplaza

@iwoplaza iwoplaza commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Part of a stack that makes the metadata of 'use gpu' functions smaller and cheaper to load (#3246).

typegpu can now read metadata registered as [json, externals, name?] (v3), which the plugin starts emitting in #3246. v1 and v2 are still read, so code transformed by older plugin versions keeps working.

  • json holds [params, statements]. It's parsed on first use (getFunctionMetadata), not when the bundle loads.
  • Identifier params are plain strings ("a" instead of {"type":"i","name":"a"}). Destructured params are [name, alias][].
  • getName reads the name from either shape without parsing the AST.

Cost: the reader adds 549–578 B minified / 175–222 B gzip to an app. That's measured on four docs examples built with Vite 8, against main (setup in #3248). #3246 saves more than that in every one of them.

v3 metadata is registered as `[json, externals, name?]`. The AST stays a JSON
string until the function is first used. v1 and v2 metadata are still read.
@iwoplaza
iwoplaza added this pull request to stack #3249 October 21, 2026 10:12
@github-actions

Copy link
Copy Markdown

pkg.pr.new

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

https://pkg.pr.new/software-mansion/TypeGPU/tinyest@7be6355bed339b2b0b9027bcaf34879c45349038
https://pkg.pr.new/software-mansion/TypeGPU/typegpu@7be6355bed339b2b0b9027bcaf34879c45349038
https://pkg.pr.new/software-mansion/TypeGPU/unplugin-typegpu@7be6355bed339b2b0b9027bcaf34879c45349038

benchmark
view benchmark

commit
view commit

@github-actions

Copy link
Copy Markdown

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

🟢 Decreased ➖ Unchanged 🔴 Increased (max 79.48%) ❔ Unknown
0 36 316 0

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

Click to reveal the results table (149 entries).
Test tsdown
d_unstruct.ts 3.03 kB ($${\color{red}+79.5\%}$$)
tgpu_slot.ts 3.08 kB ($${\color{red}+77.3\%}$$)
tgpu_unroll.ts 3.76 kB ($${\color{red}+55.5\%}$$)
d_struct.ts 5.18 kB ($${\color{red}+35.0\%}$$)
tgpu_computeFn.ts 45.58 kB ($${\color{red}+0.9\%}$$)
tgpu_fn.ts 45.78 kB ($${\color{red}+0.9\%}$$)
tgpu_vertexFn.ts 46.13 kB ($${\color{red}+0.9\%}$$)
tgpu_fragmentFn.ts 46.32 kB ($${\color{red}+0.9\%}$$)
d_bool.ts 20.26 kB ($${\color{red}+0.9\%}$$)
d_f16.ts 20.26 kB ($${\color{red}+0.9\%}$$)
d_f32.ts 20.26 kB ($${\color{red}+0.9\%}$$)
d_i32.ts 20.26 kB ($${\color{red}+0.9\%}$$)
d_u32.ts 20.26 kB ($${\color{red}+0.9\%}$$)
d_ref.ts 20.27 kB ($${\color{red}+0.9\%}$$)
d_u16.ts 20.28 kB ($${\color{red}+0.9\%}$$)
d_abstractInt.ts 20.33 kB ($${\color{red}+0.9\%}$$)
d_abstractFloat.ts 20.34 kB ($${\color{red}+0.9\%}$$)
d_textureDepth2d.ts 20.70 kB ($${\color{red}+0.8\%}$$)
d_textureDepthCube.ts 20.71 kB ($${\color{red}+0.8\%}$$)
d_texture1d.ts 20.71 kB ($${\color{red}+0.8\%}$$)
d_texture2d.ts 20.71 kB ($${\color{red}+0.8\%}$$)
d_texture3d.ts 20.71 kB ($${\color{red}+0.8\%}$$)
d_textureCube.ts 20.72 kB ($${\color{red}+0.8\%}$$)
d_textureDepth2dArray.ts 20.72 kB ($${\color{red}+0.8\%}$$)
d_textureDepthCubeArray.ts 20.72 kB ($${\color{red}+0.8\%}$$)
d_textureDepthMultisampled2d.ts 20.73 kB ($${\color{red}+0.8\%}$$)
d_texture2dArray.ts 20.73 kB ($${\color{red}+0.8\%}$$)
d_textureCubeArray.ts 20.74 kB ($${\color{red}+0.8\%}$$)
d_textureMultisampled2d.ts 20.74 kB ($${\color{red}+0.8\%}$$)
common_fullScreenTriangle.ts 49.01 kB ($${\color{red}+0.8\%}$$)
std_discard.ts 21.51 kB ($${\color{red}+0.8\%}$$)
tgpu_comptime.ts 21.61 kB ($${\color{red}+0.8\%}$$)
std_arrayLength.ts 21.73 kB ($${\color{red}+0.8\%}$$)
std_copy.ts 21.75 kB ($${\color{red}+0.8\%}$$)
std_extensionEnabled.ts 21.83 kB ($${\color{red}+0.8\%}$$)
std_range.ts 22.10 kB ($${\color{red}+0.8\%}$$)
std_isBeingTranspiled.ts 22.14 kB ($${\color{red}+0.8\%}$$)
std_getShaderStage.ts 22.19 kB ($${\color{red}+0.8\%}$$)
std_getTargetShaderLanguage.ts 22.20 kB ($${\color{red}+0.8\%}$$)
std_typeOf.ts 22.25 kB ($${\color{red}+0.8\%}$$)
d_disarrayOf.ts 22.27 kB ($${\color{red}+0.8\%}$$)
STATIC_common.ts 56.56 kB ($${\color{red}+0.7\%}$$)
std_atomicLoad.ts 26.38 kB ($${\color{red}+0.7\%}$$)
std_atomicCompareExchangeWeak.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_atomicExchange.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_atomicStore.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_workgroupBarrier.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_workgroupUniformLoad.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_atomicAdd.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_atomicAnd.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_atomicMax.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_atomicMin.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_atomicOr.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_atomicSub.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_atomicXor.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_storageBarrier.ts 26.39 kB ($${\color{red}+0.7\%}$$)
std_textureBarrier.ts 26.39 kB ($${\color{red}+0.7\%}$$)
d_uint8.ts 28.21 kB ($${\color{red}+0.6\%}$$)
d_float16.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_float16x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_float16x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_float32.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_float32x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_float32x3.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_float32x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_sint16.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_sint16x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_sint16x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_sint32.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_sint32x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_sint32x3.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_sint32x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_sint8.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_sint8x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_sint8x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_snorm16.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_snorm16x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_snorm16x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_snorm8.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_snorm8x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_snorm8x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_uint16.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_uint16x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_uint16x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_uint32.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_uint32x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_uint32x3.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_uint32x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_uint8x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_uint8x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_unorm10_10_10_2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_unorm16.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_unorm16x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_unorm16x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_unorm8.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_unorm8x2.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_unorm8x4.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_unorm8x4_bgra.ts 28.22 kB ($${\color{red}+0.6\%}$$)
d_formatToWGSLType.ts 28.21 kB ($${\color{red}+0.6\%}$$)
d_packedFormats.ts 28.24 kB ($${\color{red}+0.6\%}$$)
d_isPackedData.ts 28.28 kB ($${\color{red}+0.6\%}$$)
d_alignmentOf.ts 29.17 kB ($${\color{red}+0.6\%}$$)
tgpu_accessor.ts 68.34 kB ($${\color{red}+0.6\%}$$)
tgpu_mutableAccessor.ts 68.35 kB ($${\color{red}+0.6\%}$$)
d_isBuiltin.ts 31.89 kB ($${\color{red}+0.5\%}$$)
d_sizeOf.ts 31.94 kB ($${\color{red}+0.5\%}$$)
d_isContiguous.ts 31.95 kB ($${\color{red}+0.5\%}$$)
d_getLongestContiguousPrefix.ts 31.96 kB ($${\color{red}+0.5\%}$$)
std_subgroupAdd.ts 32.32 kB ($${\color{red}+0.5\%}$$)
std_quadBroadcast.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_quadSwapDiagonal.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_quadSwapX.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_quadSwapY.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupAll.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupAnd.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupAny.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupBallot.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupBroadcast.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupBroadcastFirst.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupElect.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupExclusiveAdd.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupExclusiveMul.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupInclusiveAdd.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupInclusiveMul.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupMax.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupMin.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupMul.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupOr.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupShuffle.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupShuffleDown.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupShuffleUp.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupShuffleXor.ts 32.33 kB ($${\color{red}+0.5\%}$$)
std_subgroupXor.ts 32.33 kB ($${\color{red}+0.5\%}$$)
d_size.ts 33.63 kB ($${\color{red}+0.5\%}$$)
d_align.ts 33.63 kB ($${\color{red}+0.5\%}$$)
d_location.ts 33.63 kB ($${\color{red}+0.5\%}$$)
d_interpolate.ts 33.64 kB ($${\color{red}+0.5\%}$$)
d_arrayOf.ts 33.69 kB ($${\color{red}+0.5\%}$$)
tgpu_vertexLayout.ts 33.95 kB ($${\color{red}+0.5\%}$$)
d_invariant.ts 34.01 kB ($${\color{red}+0.5\%}$$)
std_identity2.ts 34.42 kB ($${\color{red}+0.5\%}$$)
std_identity3.ts 34.42 kB ($${\color{red}+0.5\%}$$)
std_identity4.ts 34.42 kB ($${\color{red}+0.5\%}$$)
std_rotationX4.ts 34.42 kB ($${\color{red}+0.5\%}$$)
std_rotationY4.ts 34.42 kB ($${\color{red}+0.5\%}$$)
std_rotationZ4.ts 34.42 kB ($${\color{red}+0.5\%}$$)
std_scaling4.ts 34.42 kB ($${\color{red}+0.5\%}$$)
std_translation4.ts 34.42 kB ($${\color{red}+0.5\%}$$)
common_writeSoA.ts 34.55 kB ($${\color{red}+0.5\%}$$)

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

@github-actions

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 [1.09, 2.21, 4.56, 7.42, 8.91, 13.62, 27.60, 27.69]
  line [1.14, 2.24, 4.96, 6.94, 9.29, 15.65, 27.57, 28.01]
  line [1.07, 2.25, 4.47, 7.52, 9.20, 12.87, 28.15, 27.23]
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.31, 0.54, 0.75, 0.92, 1.24, 1.29, 1.53, 1.66]
  line [0.32, 0.54, 0.79, 0.98, 1.32, 1.38, 1.56, 1.76]
  line [0.34, 0.56, 0.77, 0.91, 1.23, 1.30, 1.57, 1.69]
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 [1.00, 2.96, 4.76, 8.55, 15.08, 28.88, 61.79, 125.31]
  line [0.93, 2.29, 4.38, 7.88, 14.49, 30.22, 63.34, 127.36]
  line [0.95, 2.35, 3.91, 7.91, 14.47, 28.57, 60.51, 126.17]
Loading

@vende11s

vende11s commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

@iwoplaza

Identifier params are plain strings ("a" instead of {"type":"i","name":"a"}). Destructured params are [name, alias][].

I'm introducing that in #2913

nodes/types look like that:

export type ObjectPattern = readonly [
  type: NodeTypeCatalog['objectPattern'],
  props: readonly [name: string, binding: BindingElement][],
];

export type BindingPattern = ObjectPattern;
export type BindingName = Identifier | BindingPattern;
export type BindingElement = BindingName;

export type FuncParameter = LegacyFuncParameter | BindingElement;

Destructured params are [name, binding] (and not [string, string]) because it leaves room for nested destructuring (not implemented yet)

It lets us add new kinds of destructuring, default parameters, and rest element without breaking changes in AST, finally it could look like that:

export type ObjectPatternEntry =
  | readonly [name: string, binding: BindingElement]
  | RestElement<Identifier>;

export type ObjectPattern = readonly [
  type: NodeTypeCatalog['objectPattern'],
  props: readonly ObjectPatternEntry[],
];

export type BindingPattern = ObjectPattern | ArrayPattern;
export type BindingName = Identifier | BindingPattern;
export type BindingElement = BindingName | AssignmentPattern;

export type FuncParameter = BindingElement | RestElement;

tldr

Should I include this change in #2913, or leave it for this PR?

@iwoplaza

iwoplaza commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator Author

@vende11s Thanks! I think #2913 should focus on the destructuring params, and this PR will just extend it with the rest.

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.

2 participants