typegpu 0.11.5 → 0.11.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/bin.mjs +57 -0
  2. package/builtin.d.ts +5 -1
  3. package/builtin.js +2 -0
  4. package/core/buffer/buffer.js +1 -1
  5. package/core/buffer/bufferUsage.js +18 -14
  6. package/core/constant/tgpuConstant.js +6 -6
  7. package/core/function/comptime.js +8 -3
  8. package/core/function/createCallableSchema.js +7 -5
  9. package/core/function/dualImpl.js +2 -2
  10. package/core/function/fnCore.js +7 -8
  11. package/core/function/tgpuComputeFn.js +1 -1
  12. package/core/function/tgpuFn.js +3 -2
  13. package/core/pipeline/computePipeline.js +3 -3
  14. package/core/pipeline/renderPipeline.js +3 -3
  15. package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +1 -1
  16. package/core/resolve/externals.js +1 -1
  17. package/core/resolve/tgpuResolve.d.ts +2 -2
  18. package/core/root/init.js +1 -1
  19. package/core/slot/accessor.js +1 -1
  20. package/core/texture/texture.js +8 -2
  21. package/core/variable/tgpuVariable.js +8 -6
  22. package/core/vertexLayout/vertexLayout.js +1 -1
  23. package/data/alignmentOf.js +1 -1
  24. package/data/attributes.d.ts +1 -1
  25. package/data/dataIO.js +1 -1
  26. package/data/dataTypes.d.ts +0 -1
  27. package/data/dataTypes.js +2 -12
  28. package/data/index.js +6 -23
  29. package/data/ref.js +20 -7
  30. package/data/snippet.d.ts +2 -1
  31. package/data/snippet.js +37 -10
  32. package/errors.d.ts +1 -4
  33. package/errors.js +1 -7
  34. package/index.d.ts +3 -3
  35. package/index.js +2 -2
  36. package/indexNamedExports.d.ts +2 -2
  37. package/package.js +1 -1
  38. package/package.json +5 -4
  39. package/resolutionCtx.js +10 -17
  40. package/shared/meta.d.ts +6 -15
  41. package/shared/meta.js +45 -38
  42. package/shared/normalizeMetadata.d.ts +32 -0
  43. package/shared/normalizeMetadata.js +40 -0
  44. package/std/atomic.js +1 -1
  45. package/std/boolean.js +36 -5
  46. package/std/environment.d.ts +48 -0
  47. package/std/environment.js +57 -0
  48. package/std/extensions.d.ts +2 -2
  49. package/std/extensions.js +2 -2
  50. package/std/index.d.ts +3 -2
  51. package/std/index.js +5 -2
  52. package/tgpuBindGroupLayout.js +1 -1
  53. package/tgsl/accessIndex.js +8 -14
  54. package/tgsl/accessProp.js +16 -29
  55. package/tgsl/consoleLog/serializers.js +1 -1
  56. package/tgsl/conversion.js +3 -3
  57. package/tgsl/forOfUtils.js +8 -5
  58. package/tgsl/generationHelpers.js +10 -11
  59. package/tgsl/infixDispatch.js +53 -0
  60. package/tgsl/shaderGenerator.d.ts +4 -1
  61. package/tgsl/shaderGenerator_members.d.ts +20 -2
  62. package/tgsl/shaderGenerator_members.js +5 -1
  63. package/tgsl/shellless.js +4 -4
  64. package/tgsl/wgslGenerator.d.ts +15 -11
  65. package/tgsl/wgslGenerator.js +174 -97
  66. package/types.d.ts +6 -4
  67. package/wgslExtensions.d.ts +3 -3
  68. package/wgslExtensions.js +3 -3
package/data/index.js CHANGED
@@ -12,7 +12,7 @@ import { PUBLIC_sizeOf } from "./sizeOf.js";
12
12
  import { align, interpolate, invariant, isBuiltin, location, size } from "./attributes.js";
13
13
  import { struct } from "./struct.js";
14
14
  import { MatBase, mat2x2f, mat3x3f, mat4x4f, matToArray } from "./matrix.js";
15
- import { infixOperators } from "../tgsl/accessProp.js";
15
+ import { assignInfixOperator } from "../tgsl/infixDispatch.js";
16
16
  import { comparisonSampler, sampler } from "./sampler.js";
17
17
  import { texture1d, texture2d, texture2dArray, texture3d, textureCube, textureCubeArray, textureDepth2d, textureDepth2dArray, textureDepthCube, textureDepthCubeArray, textureDepthMultisampled2d, textureExternal, textureMultisampled2d, textureStorage1d, textureStorage2d, textureStorage2dArray, textureStorage3d } from "./texture.js";
18
18
  import { arrayOf } from "./array.js";
@@ -159,33 +159,16 @@ var data_exports = /* @__PURE__ */ __export({
159
159
  vec4i: () => vec4i,
160
160
  vec4u: () => vec4u
161
161
  });
162
- function assignInfixOperator(object, operator, operatorSymbol) {
163
- const proto = object.prototype;
164
- const opImpl = infixOperators[operator];
165
- proto[operator] = function(other) {
166
- return opImpl(this, other);
167
- };
168
- proto[operatorSymbol] = (lhs, rhs) => {
169
- return opImpl(lhs, rhs);
170
- };
171
- }
172
162
  assignInfixOperator(VecBase, "add", Operator.plus);
163
+ assignInfixOperator(MatBase, "add", Operator.plus);
173
164
  assignInfixOperator(VecBase, "sub", Operator.minus);
165
+ assignInfixOperator(MatBase, "sub", Operator.minus);
174
166
  assignInfixOperator(VecBase, "mul", Operator.star);
167
+ assignInfixOperator(MatBase, "mul", Operator.star);
175
168
  assignInfixOperator(VecBase, "div", Operator.slash);
176
169
  assignInfixOperator(VecBase, "mod", Operator.percent);
177
- assignInfixOperator(MatBase, "add", Operator.plus);
178
- assignInfixOperator(MatBase, "sub", Operator.minus);
179
- assignInfixOperator(MatBase, "mul", Operator.star);
180
- {
181
- const proto = VecBase.prototype;
182
- proto.bitShiftLeft = function(other) {
183
- return infixOperators.bitShiftLeft(this, other);
184
- };
185
- proto.bitShiftRight = function(other) {
186
- return infixOperators.bitShiftRight(this, other);
187
- };
188
- }
170
+ assignInfixOperator(VecBase, "bitShiftLeft", Symbol());
171
+ assignInfixOperator(VecBase, "bitShiftRight", Symbol());
189
172
 
190
173
  //#endregion
191
174
  export { Void, align, PUBLIC_alignmentOf as alignmentOf, arrayOf, atomic, bool, builtin, comparisonSampler, data_exports, deepEqual, disarrayOf, f16, f32, float16, float16x2, float16x4, float32, float32x2, float32x3, float32x4, formatToWGSLType, PUBLIC_getLongestContiguousPrefix as getLongestContiguousPrefix, i32, interpolate, invariant, isAlignAttrib, isAtomic, isBuiltin, isBuiltinAttrib, PUBLIC_isContiguous as isContiguous, isData, isDecorated, isDisarray, isInterpolateAttrib, isLocationAttrib, isLooseData, isLooseDecorated, isPackedData, isPtr, isSizeAttrib, isUnstruct, isWgslArray, isWgslData, isWgslStruct, location, mat2x2f, mat3x3f, mat4x4f, matToArray, memoryLayoutOf, packedFormats, ptrFn, ptrHandle, ptrPrivate, ptrStorage, ptrUniform, ptrWorkgroup, _ref as ref, sampler, sint16, sint16x2, sint16x4, sint32, sint32x2, sint32x3, sint32x4, sint8, sint8x2, sint8x4, size, PUBLIC_sizeOf as sizeOf, snorm16, snorm16x2, snorm16x4, snorm8, snorm8x2, snorm8x4, struct, texture1d, texture2d, texture2dArray, texture3d, textureCube, textureCubeArray, textureDepth2d, textureDepth2dArray, textureDepthCube, textureDepthCubeArray, textureDepthMultisampled2d, textureExternal, textureMultisampled2d, textureStorage1d, textureStorage2d, textureStorage2dArray, textureStorage3d, u16, u32, uint16, uint16x2, uint16x4, uint32, uint32x2, uint32x3, uint32x4, uint8, uint8x2, uint8x4, unorm10_10_10_2, unorm16, unorm16x2, unorm16x4, unorm8, unorm8x2, unorm8x4, unorm8x4_bgra, unstruct, vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u };
package/data/ref.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { $gpuCallable, $internal, $ownSnippet, $resolve } from "../shared/symbols.js";
2
- import { setName } from "../shared/meta.js";
3
2
  import { isNaturallyEphemeral, isPtr } from "./wgslTypes.js";
3
+ import { setName } from "../shared/meta.js";
4
4
  import { UnknownData } from "./dataTypes.js";
5
- import { snip } from "./snippet.js";
5
+ import { isAlias, snip } from "./snippet.js";
6
6
  import { WgslTypeError } from "../errors.js";
7
7
  import { stitch } from "../core/resolve/stitch.js";
8
8
  import { createPtrFromOrigin, explicitFrom } from "./ptr.js";
@@ -13,8 +13,22 @@ const _ref = (() => {
13
13
  setName(impl, "ref");
14
14
  impl.toString = () => "ref";
15
15
  impl[$internal] = true;
16
- impl[$gpuCallable] = { call(_ctx, [value]) {
17
- if (value.origin === "argument") throw new WgslTypeError(stitch`d.ref(${value}) is illegal, cannot take a reference of an argument. Copy the value locally first, and take a reference of the copy.`);
16
+ impl[$gpuCallable] = { call(ctx, [value]) {
17
+ if (value.origin === "argument") throw new WgslTypeError(stitch`d.ref(${value}) is illegal, cannot take a reference of an argument. Copy the value first, and take a reference of the copy.`);
18
+ if (value.origin === "constant-immutable-def" || value.origin === "runtime-immutable-def") {
19
+ const typeStr = ctx.resolve(value.dataType).value;
20
+ throw new WgslTypeError(stitch`d.ref(${value}) is illegal, cannot take a reference to a constant.
21
+ -----
22
+ - Try 'd.ref(${typeStr}(${value}));' instead to create a new referencable value.
23
+ -----`);
24
+ }
25
+ if (isAlias(value) && isNaturallyEphemeral(value.dataType)) {
26
+ const typeStr = ctx.resolve(value.dataType).value;
27
+ throw new WgslTypeError(stitch`d.ref(${value}) is illegal, cannot take a reference to a scalar value.
28
+ -----
29
+ - Try 'd.ref(${typeStr}(${value}));' instead to create a new referencable scalar.
30
+ -----`);
31
+ }
18
32
  if (isPtr(value.dataType)) return snip(value.value, explicitFrom(value.dataType), value.origin);
19
33
  /**
20
34
  * Pointer type only exists if the ref was created from a reference (buttery-butter).
@@ -87,9 +101,8 @@ var RefOperator = class {
87
101
  function derefSnippet(snippet) {
88
102
  if (!isPtr(snippet.dataType)) return snippet;
89
103
  const innerType = snippet.dataType.inner;
90
- const origin = isNaturallyEphemeral(innerType) ? "runtime" : snippet.origin;
91
- if (snippet.value instanceof RefOperator) return snip(stitch`${snippet.value.snippet}`, innerType, origin);
92
- return snip(stitch`(*${snippet})`, innerType, origin);
104
+ if (snippet.value instanceof RefOperator) return snip(stitch`${snippet.value.snippet}`, innerType, snippet.origin);
105
+ return snip(stitch`(*${snippet})`, innerType, snippet.origin);
93
106
  }
94
107
 
95
108
  //#endregion
package/data/snippet.d.ts CHANGED
@@ -2,7 +2,7 @@ import { BaseData } from "./wgslTypes.js";
2
2
  import { UnknownData } from "./dataTypes.js";
3
3
 
4
4
  //#region src/data/snippet.d.ts
5
- type Origin = 'uniform' | 'readonly' | 'mutable' | 'workgroup' | 'private' | 'function' | 'this-function' | 'handle' | 'argument' | 'runtime' | 'constant' | 'constant-tgpu-const-ref' | 'runtime-tgpu-const-ref';
5
+ type Origin = 'uniform' | 'readonly' | 'mutable' | 'workgroup' | 'private' | 'handle' | 'function' | 'local-def' | 'constant-immutable-def' | 'runtime-immutable-def' | 'argument' | 'runtime' | 'constant';
6
6
  interface Snippet {
7
7
  readonly value: unknown;
8
8
  /**
@@ -11,6 +11,7 @@ interface Snippet {
11
11
  */
12
12
  readonly dataType: BaseData | UnknownData;
13
13
  readonly origin: Origin;
14
+ readonly possibleSideEffects: boolean;
14
15
  }
15
16
  interface ResolvedSnippet extends Snippet {
16
17
  readonly value: string;
package/data/snippet.js CHANGED
@@ -3,9 +3,6 @@ import { isNumericSchema } from "./wgslTypes.js";
3
3
  import { undecorate } from "./dataTypes.js";
4
4
 
5
5
  //#region src/data/snippet.ts
6
- function isEphemeralOrigin(space) {
7
- return space === "runtime" || space === "constant" || space === "argument";
8
- }
9
6
  /**
10
7
  * What happens to a snippet's origin when it's deep copied in JS, and left as is in WGSL?
11
8
  * e.g. `vec3f(vec3f(0, 1, 2))`
@@ -14,8 +11,27 @@ function fallthroughCopyOrigin(origin) {
14
11
  if (origin === "runtime" || origin === "constant") return origin;
15
12
  return "runtime";
16
13
  }
17
- function isEphemeralSnippet(snippet) {
18
- return isEphemeralOrigin(snippet.origin);
14
+ /**
15
+ * Whether a snippet aliases a value that lives outside the current expression.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * function foo(a: number) {
20
+ * const color = d.vec3f(1, 2, 3);
21
+ * return color * a;
22
+ * }
23
+ *
24
+ * // References:
25
+ * // - color
26
+ * // - a
27
+ * //
28
+ * // Not references:
29
+ * // - d.vec3f(1, 2, 3)
30
+ * // - color * a
31
+ * ```
32
+ */
33
+ function isAlias(snippet) {
34
+ return !(snippet.origin === "runtime" || snippet.origin === "constant");
19
35
  }
20
36
  const originToPtrParams = {
21
37
  uniform: {
@@ -42,7 +58,7 @@ const originToPtrParams = {
42
58
  space: "function",
43
59
  access: "read-write"
44
60
  },
45
- "this-function": {
61
+ "local-def": {
46
62
  space: "function",
47
63
  access: "read-write"
48
64
  }
@@ -51,10 +67,12 @@ var SnippetImpl = class {
51
67
  value;
52
68
  dataType;
53
69
  origin;
54
- constructor(value, dataType, origin) {
70
+ possibleSideEffects;
71
+ constructor(value, dataType, origin, possibleSideEffects) {
55
72
  this.value = value;
56
73
  this.dataType = dataType;
57
74
  this.origin = origin;
75
+ this.possibleSideEffects = possibleSideEffects;
58
76
  }
59
77
  };
60
78
  function isSnippet(value) {
@@ -63,10 +81,19 @@ function isSnippet(value) {
63
81
  function isSnippetNumeric(snippet) {
64
82
  return isNumericSchema(snippet.dataType);
65
83
  }
66
- function snip(value, dataType, origin) {
84
+ function snip(value, dataType, origin, possibleSideEffects = true) {
67
85
  if (DEV && isSnippet(value)) throw new Error("Cannot nest snippets");
68
- return new SnippetImpl(value, undecorate(dataType), origin);
86
+ return new SnippetImpl(value, undecorate(dataType), origin, possibleSideEffects);
87
+ }
88
+ function withDataType(dataType, snippet) {
89
+ return new SnippetImpl(snippet.value, dataType, snippet.origin, snippet.possibleSideEffects);
90
+ }
91
+ function withSideEffects(possibleSideEffects, snippet) {
92
+ return new SnippetImpl(snippet.value, snippet.dataType, snippet.origin, possibleSideEffects);
93
+ }
94
+ function noSideEffects(snippet) {
95
+ return withSideEffects(false, snippet);
69
96
  }
70
97
 
71
98
  //#endregion
72
- export { fallthroughCopyOrigin, isEphemeralOrigin, isEphemeralSnippet, isSnippet, isSnippetNumeric, originToPtrParams, snip };
99
+ export { fallthroughCopyOrigin, isAlias, isSnippet, isSnippetNumeric, noSideEffects, originToPtrParams, snip, withDataType };
package/errors.d.ts CHANGED
@@ -32,9 +32,6 @@ declare class MissingSlotValueError extends Error {
32
32
  declare class NotUniformError extends Error {
33
33
  constructor(value: TgpuBuffer<BaseData>);
34
34
  }
35
- declare class MissingLinksError extends Error {
36
- constructor(fnLabel: string | undefined, externalNames: string[]);
37
- }
38
35
  declare class MissingBindGroupsError extends Error {
39
36
  constructor(layouts: Iterable<TgpuBindGroupLayout>);
40
37
  }
@@ -42,4 +39,4 @@ declare class MissingVertexBuffersError extends Error {
42
39
  constructor(layouts: Iterable<TgpuVertexLayout>);
43
40
  }
44
41
  //#endregion
45
- export { MissingBindGroupsError, MissingLinksError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError };
42
+ export { MissingBindGroupsError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError };
package/errors.js CHANGED
@@ -86,12 +86,6 @@ var NotUniformError = class NotUniformError extends Error {
86
86
  Object.setPrototypeOf(this, NotUniformError.prototype);
87
87
  }
88
88
  };
89
- var MissingLinksError = class MissingLinksError extends Error {
90
- constructor(fnLabel, externalNames) {
91
- super(`The function '${fnLabel ?? "<unnamed>"}' is missing links to the following external values: ${externalNames}.`);
92
- Object.setPrototypeOf(this, MissingLinksError.prototype);
93
- }
94
- };
95
89
  var MissingBindGroupsError = class MissingBindGroupsError extends Error {
96
90
  constructor(layouts) {
97
91
  super(`Missing bind groups for layouts: '${[...layouts].map((layout) => getName(layout) ?? "<unnamed>").join(", ")}'. Please provide it using pipeline.with(bindGroup).(...)`);
@@ -130,4 +124,4 @@ var SignatureNotSupportedError = class SignatureNotSupportedError extends Error
130
124
  };
131
125
 
132
126
  //#endregion
133
- export { ExecutionError, IllegalBufferAccessError, IllegalVarAccessError, MissingBindGroupsError, MissingLinksError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError, SignatureNotSupportedError, WgslTypeError, invariant };
127
+ export { ExecutionError, IllegalBufferAccessError, IllegalVarAccessError, MissingBindGroupsError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError, SignatureNotSupportedError, WgslTypeError, invariant };
package/index.d.ts CHANGED
@@ -7,7 +7,7 @@ import { TgpuComputeFn, TgpuComputeFnShell, computeFn, isTgpuComputeFn } from ".
7
7
  import { TgpuVar, VariableScope, isVariable, privateVar, workgroupVar } from "./core/variable/tgpuVariable.js";
8
8
  import { Eventual, TgpuAccessor, TgpuLazy, TgpuMutableAccessor, TgpuSlot, isAccessor, isLazy, isMutableAccessor, isSlot } from "./core/slot/slotTypes.js";
9
9
  import { TgpuComputePipeline } from "./core/pipeline/computePipeline.js";
10
- import { AutoFragmentIn, AutoFragmentOut, AutoVertexOut, _AutoVertexIn } from "./core/function/autoIO.js";
10
+ import { AnyAutoCustoms, AutoFragmentIn, AutoFragmentOut, AutoVertexOut, _AutoVertexIn } from "./core/function/autoIO.js";
11
11
  import { TgpuFragmentFn, TgpuFragmentFnShell, fragmentFn, isTgpuFragmentFn } from "./core/function/tgpuFragmentFn.js";
12
12
  import { TgpuVertexFn, TgpuVertexFnShell, isTgpuVertexFn, vertexFn } from "./core/function/tgpuVertexFn.js";
13
13
  import { TextureProps } from "./core/texture/textureProps.js";
@@ -36,7 +36,7 @@ import { tgpuUnstable_d_exports } from "./tgpuUnstable.js";
36
36
  import { index_d_exports as index_d_exports$1 } from "./data/index.js";
37
37
  import { index_d_exports as index_d_exports$2 } from "./std/index.js";
38
38
  import { index_d_exports } from "./common/index.js";
39
- import { MissingBindGroupsError, MissingLinksError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError } from "./errors.js";
39
+ import { MissingBindGroupsError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError } from "./errors.js";
40
40
  import { WgslGenerator } from "./tgsl/wgslGenerator.js";
41
41
  import { readFromArrayBuffer, writeToArrayBuffer } from "./data/dataIO.js";
42
42
  import { patchArrayBuffer } from "./data/partialIO.js";
@@ -70,4 +70,4 @@ declare const tgpu: {
70
70
  '~unstable': typeof tgpuUnstable_d_exports;
71
71
  };
72
72
  //#endregion
73
- export { AutoFragmentIn, AutoFragmentOut, _AutoVertexIn as AutoVertexIn, AutoVertexOut, BindLayoutEntry, ColorAttachment, Configurable, Eventual, ExtractBindGroupInputFromLayout, INTERNAL_GlobalExt, IndexFlag, InitFromDeviceOptions, InitOptions, LayoutEntryToInput, MissingBindGroupsError, MissingLinksError, MissingSlotValueError, MissingVertexBuffersError, Namespace, NotUniformError, RawCodeSnippetOrigin, RenderFlag, ResolutionError, SampledFlag, ShaderGenerator, Storage, StorageFlag, TextureProps, TgpuAccessor, TgpuBindGroup, TgpuBindGroupLayout, TgpuBuffer, TgpuBufferMutable, TgpuBufferReadonly, TgpuBufferUniform, TgpuComparisonSampler, TgpuComptime, TgpuComputeFn, TgpuComputeFnShell, TgpuComputePipeline, TgpuConst, TgpuDeclare, TgpuFixedComparisonSampler, TgpuFixedSampler, TgpuFn, TgpuFnShell, TgpuFragmentFn, TgpuFragmentFnShell, TgpuGenericFn, TgpuGuardedComputePipeline, TgpuLayoutComparisonSampler, TgpuLayoutEntry, TgpuLayoutExternalTexture, TgpuLayoutSampler, TgpuLayoutStorage, TgpuLayoutTexture, TgpuLayoutUniform, TgpuLazy, TgpuMutable, TgpuMutableAccessor, TgpuPrimitiveState, TgpuQuerySet, TgpuRawCodeSnippet, TgpuReadonly, TgpuRenderPipeline, TgpuRenderPipelineDescriptor, TgpuRoot, TgpuSampler, TgpuSlot, TgpuTexture, TgpuTextureView, TgpuUniform, TgpuVar, TgpuVertexFn, TgpuVertexFnShell, TgpuVertexLayout, Uniform, UniformFlag, ValidUsagesFor, ValidateBufferSchema, ValidateStorageSchema, ValidateUniformSchema, VariableScope, Vertex, VertexFlag, WgslGenerator, WithBinding, WithCompute, WithFragment, WithVertex, Withable, index_d_exports as common, index_d_exports$1 as d, tgpu as default, tgpu, isAccessor, isBuffer, isBufferShorthand, isComparisonSampler, isLazy, isMutableAccessor, isSampler, isSlot, isTexture, isTgpuComputeFn, isTgpuFn, isTgpuFragmentFn, isTgpuVertexFn, isUsableAsRender, isUsableAsSampled, isUsableAsStorage, isUsableAsUniform, isUsableAsVertex, isVariable, patchArrayBuffer, readFromArrayBuffer, index_d_exports$2 as std, writeToArrayBuffer };
73
+ export { AnyAutoCustoms, AutoFragmentIn, AutoFragmentOut, _AutoVertexIn as AutoVertexIn, AutoVertexOut, BindLayoutEntry, ColorAttachment, Configurable, Eventual, ExtractBindGroupInputFromLayout, INTERNAL_GlobalExt, IndexFlag, InitFromDeviceOptions, InitOptions, LayoutEntryToInput, MissingBindGroupsError, MissingSlotValueError, MissingVertexBuffersError, Namespace, NotUniformError, RawCodeSnippetOrigin, RenderFlag, ResolutionError, SampledFlag, ShaderGenerator, Storage, StorageFlag, TextureProps, TgpuAccessor, TgpuBindGroup, TgpuBindGroupLayout, TgpuBuffer, TgpuBufferMutable, TgpuBufferReadonly, TgpuBufferUniform, TgpuComparisonSampler, TgpuComptime, TgpuComputeFn, TgpuComputeFnShell, TgpuComputePipeline, TgpuConst, TgpuDeclare, TgpuFixedComparisonSampler, TgpuFixedSampler, TgpuFn, TgpuFnShell, TgpuFragmentFn, TgpuFragmentFnShell, TgpuGenericFn, TgpuGuardedComputePipeline, TgpuLayoutComparisonSampler, TgpuLayoutEntry, TgpuLayoutExternalTexture, TgpuLayoutSampler, TgpuLayoutStorage, TgpuLayoutTexture, TgpuLayoutUniform, TgpuLazy, TgpuMutable, TgpuMutableAccessor, TgpuPrimitiveState, TgpuQuerySet, TgpuRawCodeSnippet, TgpuReadonly, TgpuRenderPipeline, TgpuRenderPipelineDescriptor, TgpuRoot, TgpuSampler, TgpuSlot, TgpuTexture, TgpuTextureView, TgpuUniform, TgpuVar, TgpuVertexFn, TgpuVertexFnShell, TgpuVertexLayout, Uniform, UniformFlag, ValidUsagesFor, ValidateBufferSchema, ValidateStorageSchema, ValidateUniformSchema, VariableScope, Vertex, VertexFlag, WgslGenerator, WithBinding, WithCompute, WithFragment, WithVertex, Withable, index_d_exports as common, index_d_exports$1 as d, tgpu as default, tgpu, isAccessor, isBuffer, isBufferShorthand, isComparisonSampler, isLazy, isMutableAccessor, isSampler, isSlot, isTexture, isTgpuComputeFn, isTgpuFn, isTgpuFragmentFn, isTgpuVertexFn, isUsableAsRender, isUsableAsSampled, isUsableAsStorage, isUsableAsUniform, isUsableAsVertex, isVariable, patchArrayBuffer, readFromArrayBuffer, index_d_exports$2 as std, writeToArrayBuffer };
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { MissingBindGroupsError, MissingLinksError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError } from "./errors.js";
1
+ import { MissingBindGroupsError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError } from "./errors.js";
2
2
  import { isAccessor, isLazy, isMutableAccessor, isSlot } from "./core/slot/slotTypes.js";
3
3
  import { shaderGenerator_members_exports } from "./tgsl/shaderGenerator_members.js";
4
4
  import { isTgpuFn } from "./core/function/tgpuFn.js";
@@ -25,4 +25,4 @@ import { common_exports } from "./common/index.js";
25
25
  var src_default = tgpu_exports;
26
26
 
27
27
  //#endregion
28
- export { MissingBindGroupsError, MissingLinksError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError, shaderGenerator_members_exports as ShaderGenerator, WgslGenerator, common_exports as common, data_exports as d, src_default as default, isAccessor, isBuffer, isBufferShorthand, isComparisonSampler, isLazy, isMutableAccessor, isSampler, isSlot, isTexture, isTgpuComputeFn, isTgpuFn, isTgpuFragmentFn, isTgpuVertexFn, isUsableAsRender, isUsableAsSampled, isUsableAsStorage, isUsableAsUniform, isUsableAsVertex, isVariable, patchArrayBuffer, readFromArrayBuffer, std_exports as std, tgpu_exports as tgpu, writeToArrayBuffer };
28
+ export { MissingBindGroupsError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError, shaderGenerator_members_exports as ShaderGenerator, WgslGenerator, common_exports as common, data_exports as d, src_default as default, isAccessor, isBuffer, isBufferShorthand, isComparisonSampler, isLazy, isMutableAccessor, isSampler, isSlot, isTexture, isTgpuComputeFn, isTgpuFn, isTgpuFragmentFn, isTgpuVertexFn, isUsableAsRender, isUsableAsSampled, isUsableAsStorage, isUsableAsUniform, isUsableAsVertex, isVariable, patchArrayBuffer, readFromArrayBuffer, std_exports as std, tgpu_exports as tgpu, writeToArrayBuffer };
@@ -7,7 +7,7 @@ import { TgpuComputeFn, TgpuComputeFnShell, isTgpuComputeFn } from "./core/funct
7
7
  import { TgpuVar, VariableScope, isVariable } from "./core/variable/tgpuVariable.js";
8
8
  import { Eventual, TgpuAccessor, TgpuLazy, TgpuMutableAccessor, TgpuSlot, isAccessor, isLazy, isMutableAccessor, isSlot } from "./core/slot/slotTypes.js";
9
9
  import { TgpuComputePipeline } from "./core/pipeline/computePipeline.js";
10
- import { AutoFragmentIn, AutoFragmentOut, AutoVertexOut, _AutoVertexIn } from "./core/function/autoIO.js";
10
+ import { AnyAutoCustoms, AutoFragmentIn, AutoFragmentOut, AutoVertexOut, _AutoVertexIn } from "./core/function/autoIO.js";
11
11
  import { TgpuFragmentFn, TgpuFragmentFnShell, isTgpuFragmentFn } from "./core/function/tgpuFragmentFn.js";
12
12
  import { TgpuVertexFn, TgpuVertexFnShell, isTgpuVertexFn } from "./core/function/tgpuVertexFn.js";
13
13
  import { TextureProps } from "./core/texture/textureProps.js";
@@ -30,7 +30,7 @@ import { RawCodeSnippetOrigin, TgpuRawCodeSnippet } from "./core/rawCodeSnippet/
30
30
  import { index_d_exports } from "./data/index.js";
31
31
  import { index_d_exports as index_d_exports$1 } from "./std/index.js";
32
32
  import { index_d_exports as index_d_exports$2 } from "./common/index.js";
33
- import { MissingBindGroupsError, MissingLinksError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError } from "./errors.js";
33
+ import { MissingBindGroupsError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError } from "./errors.js";
34
34
  import { WgslGenerator } from "./tgsl/wgslGenerator.js";
35
35
  import { readFromArrayBuffer, writeToArrayBuffer } from "./data/dataIO.js";
36
36
  import { patchArrayBuffer } from "./data/partialIO.js";
package/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.11.5";
2
+ var version = "0.11.7";
3
3
 
4
4
  //#endregion
5
5
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typegpu",
3
- "version": "0.11.5",
3
+ "version": "0.11.7",
4
4
  "description": "A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.",
5
5
  "keywords": [
6
6
  "compute",
@@ -22,6 +22,7 @@
22
22
  "url": "git+https://github.com/software-mansion/TypeGPU.git",
23
23
  "directory": "packages/typegpu"
24
24
  },
25
+ "bin": "./bin.mjs",
25
26
  "type": "module",
26
27
  "sideEffects": false,
27
28
  "exports": {
@@ -44,9 +45,9 @@
44
45
  }
45
46
  },
46
47
  "dependencies": {
47
- "tinyest": "~0.3.1",
48
- "tsover-runtime": "^0.0.6",
49
- "typed-binary": "^4.3.3"
48
+ "tsover-runtime": "^0.0.7",
49
+ "typed-binary": "^4.3.3",
50
+ "tinyest": "~0.3.2"
50
51
  },
51
52
  "engines": {
52
53
  "node": ">=12.20.0"
package/resolutionCtx.js CHANGED
@@ -1,14 +1,13 @@
1
1
  import { $internal, $providing, $resolve, isMarkedInternal } from "./shared/symbols.js";
2
- import { getName, hasTinyestMetadata, setName } from "./shared/meta.js";
3
2
  import { Void, isPtr, isWgslArray, isWgslStruct } from "./data/wgslTypes.js";
3
+ import { safeStringify } from "./shared/stringify.js";
4
+ import { getName, hasTinyestMetadata, setName } from "./shared/meta.js";
4
5
  import { UnknownData, isData } from "./data/dataTypes.js";
5
6
  import { snip } from "./data/snippet.js";
6
7
  import { MissingSlotValueError, ResolutionError, WgslTypeError, invariant } from "./errors.js";
7
8
  import { isLazy, isProviding, isSlot } from "./core/slot/slotTypes.js";
8
9
  import { CodegenState, NormalState, isSelfResolvable } from "./types.js";
9
10
  import { provideCtx, topLevelState } from "./execMode.js";
10
- import { stitch } from "./core/resolve/stitch.js";
11
- import { safeStringify } from "./shared/stringify.js";
12
11
  import { getBestConversion } from "./tgsl/conversion.js";
13
12
  import { bool } from "./data/numeric.js";
14
13
  import { coerceToSnippet, concretize, numericLiteralToSnippet } from "./tgsl/generationHelpers.js";
@@ -338,7 +337,7 @@ var ResolutionCtxImpl = class {
338
337
  get logResources() {
339
338
  return this.#logGenerator.logResources;
340
339
  }
341
- fnToWgsl(options) {
340
+ resolveFunction(options) {
342
341
  try {
343
342
  const scope = this._itemStateStack.pushFunctionScope(options.functionType, {}, options.returnType, options.externalMap);
344
343
  this._itemStateStack.pushBlockScope();
@@ -359,7 +358,7 @@ var ResolutionCtxImpl = class {
359
358
  else if (firstParam?.type === FuncParameterType.identifier) {
360
359
  const proxyEntries = [];
361
360
  for (const a of positionalArgs) {
362
- const arg = createArgument(this.makeUniqueIdentifier(`_arg_${a.schemaKey}`, "block"), a.type);
361
+ const arg = createArgument(this.makeUniqueIdentifier(a.schemaKey, "block"), a.type);
363
362
  args.push(arg);
364
363
  proxyEntries.push({
365
364
  schemaKey: a.schemaKey,
@@ -403,6 +402,8 @@ var ResolutionCtxImpl = class {
403
402
  let returnType;
404
403
  const code = this.gen.functionDefinition({
405
404
  functionType: options.functionType,
405
+ name: options.name,
406
+ workgroupSize: options.workgroupSize,
406
407
  args,
407
408
  body: options.body,
408
409
  determineReturnType: () => {
@@ -486,7 +487,7 @@ var ResolutionCtxImpl = class {
486
487
  setName(item, name);
487
488
  return callback();
488
489
  } finally {
489
- setName(item, oldName);
490
+ if (oldName) setName(item, oldName);
490
491
  }
491
492
  }
492
493
  unwrap(eventual) {
@@ -578,24 +579,16 @@ var ResolutionCtxImpl = class {
578
579
  if (typeof item === "number") {
579
580
  const realSchema = schema ?? numericLiteralToSnippet(item).dataType;
580
581
  invariant(realSchema !== UnknownData, "Schema has to be known for resolving numbers");
581
- if (realSchema.type === "abstractInt") return snip(`${item}`, realSchema, "constant");
582
- if (realSchema.type === "u32") return snip(`${item}u`, realSchema, "constant");
583
- if (realSchema.type === "i32") return snip(`${item}i`, realSchema, "constant");
584
- const exp = item.toExponential();
585
- const decimal = realSchema.type === "abstractFloat" && Number.isInteger(item) ? `${item}.` : `${item}`;
586
- const base = exp.length < decimal.length ? exp : decimal;
587
- if (realSchema.type === "f32") return snip(`${base}f`, realSchema, "constant");
588
- if (realSchema.type === "f16") return snip(`${base}h`, realSchema, "constant");
589
- return snip(base, realSchema, "constant");
582
+ return this.gen.numericLiteral(item, realSchema);
590
583
  }
591
584
  if (typeof item === "boolean") return snip(item ? "true" : "false", bool, "constant");
592
585
  if (typeof item === "string") return snip(item, Void, "runtime");
593
586
  if (schema && isWgslArray(schema)) {
594
587
  if (!Array.isArray(item)) throw new WgslTypeError(`Cannot coerce ${item} into value of type '${schema}'`);
595
588
  if (schema.elementCount !== item.length) throw new WgslTypeError(`Cannot create value of type '${schema}' from an array of length: ${item.length}`);
596
- return snip(stitch`array<${this.resolve(schema.elementType)}, ${schema.elementCount}>(${item.map((element) => snip(element, schema.elementType, "runtime"))})`, schema, "runtime");
589
+ return this.gen.typeInstantiation(schema, item.map((element) => snip(element, schema.elementType, "runtime")));
597
590
  }
598
- if (schema && isWgslStruct(schema)) return snip(stitch`${this.resolve(schema)}(${Object.entries(schema.propTypes).map(([key, propType]) => snip(item[key], propType, "runtime"))})`, schema, "runtime");
591
+ if (schema && isWgslStruct(schema)) return this.gen.typeInstantiation(schema, Object.entries(schema.propTypes).map(([key, propType]) => snip(item[key], propType, "runtime")));
599
592
  throw new WgslTypeError(`Value ${safeStringify(item)} is not resolvable${schema ? ` to type ${safeStringify(schema)}` : ""}`);
600
593
  }
601
594
  resolveSnippet(snippet) {
package/shared/meta.d.ts CHANGED
@@ -1,16 +1,7 @@
1
- import { Block, FuncParameter } from "tinyest";
1
+ import { RawMetadata } from "./normalizeMetadata.js";
2
2
 
3
3
  //#region src/shared/meta.d.ts
4
- interface MetaData {
5
- v?: number;
6
- name?: string | undefined;
7
- ast?: {
8
- params: FuncParameter[];
9
- body: Block;
10
- externalNames: string[];
11
- } | undefined;
12
- externals?: Record<string, unknown> | (() => Record<string, unknown>) | undefined;
13
- }
4
+
14
5
  /**
15
6
  * Don't use or you WILL get fired from your job.
16
7
  *
@@ -21,11 +12,11 @@ interface MetaData {
21
12
  * @internal
22
13
  */
23
14
  type INTERNAL_GlobalExt = typeof globalThis & {
24
- __TYPEGPU_VERSION__: string | undefined;
25
- __TYPEGPU_META__: WeakMap<object, MetaData>;
26
- __TYPEGPU_AUTONAME__: <T>(exp: T, label: string) => T;
15
+ __TYPEGPU_VERSION__?: string;
16
+ __TYPEGPU_META__?: WeakMap<object, RawMetadata>;
17
+ __TYPEGPU_AUTONAME__?: <T>(exp: T, label: string) => T;
27
18
  __TYPEGPU_MEASURE_PERF__?: boolean | undefined;
28
- __TYPEGPU_PERF_RECORDS__?: Map<string, unknown[]> | undefined;
19
+ __TYPEGPU_PERF_RECORDS__?: Map<string, unknown[]>;
29
20
  };
30
21
  /**
31
22
  * Can be assigned a name. Not to be confused with just having a name.
package/shared/meta.js CHANGED
@@ -1,63 +1,70 @@
1
1
  import { version } from "../package.js";
2
2
  import { DEV, TEST } from "./env.js";
3
3
  import { $getNameForward, isMarkedInternal } from "./symbols.js";
4
+ import { normalizeMetadata } from "./normalizeMetadata.js";
4
5
 
5
6
  //#region src/shared/meta.ts
6
- const globalWithMeta = globalThis;
7
- if (globalWithMeta.__TYPEGPU_VERSION__ !== void 0) console.warn(`Found duplicate TypeGPU version. First was ${globalWithMeta.__TYPEGPU_VERSION__}, this one is ${version}. This may cause unexpected behavior.`);
8
- globalWithMeta.__TYPEGPU_VERSION__ = version;
9
- globalWithMeta.__TYPEGPU_AUTONAME__ = (exp, label) => isNamable(exp) && isMarkedInternal(exp) && !getName(exp) ? exp.$name(label) : exp;
10
- /**
11
- * Performance measurements are only enabled in dev & test environments for now
12
- */
13
- const PERF = (DEV || TEST) && {
14
- get enabled() {
15
- return !!globalWithMeta.__TYPEGPU_MEASURE_PERF__;
16
- },
17
- record(name, data) {
18
- const records = globalWithMeta.__TYPEGPU_PERF_RECORDS__ ??= /* @__PURE__ */ new Map();
19
- let entries = records.get(name);
20
- if (!entries) {
21
- entries = [];
22
- records.set(name, entries);
23
- }
24
- entries.push(data);
25
- }
26
- } || void 0;
7
+ const globalExt = globalThis;
8
+ if (globalExt.__TYPEGPU_VERSION__ !== void 0) console.warn(`Found duplicate TypeGPU version. First was ${globalExt.__TYPEGPU_VERSION__}, this one is ${version}. This may cause unexpected behavior.`);
9
+ globalExt.__TYPEGPU_VERSION__ = version;
10
+ globalExt.__TYPEGPU_AUTONAME__ = (exp, label) => isNamable(exp) && isMarkedInternal(exp) && !getName(exp) ? exp.$name(label) : exp;
11
+ const nameMap = /* @__PURE__ */ new WeakMap();
12
+ function isNamable(value) {
13
+ return !!value?.$name;
14
+ }
27
15
  function isForwarded(value) {
28
16
  return !!value?.[$getNameForward];
29
17
  }
30
18
  function getName(definition) {
31
19
  if (isForwarded(definition)) return getName(definition[$getNameForward]);
32
- return getMetaData(definition)?.name;
20
+ return nameMap.get(definition) ?? globalExt.__TYPEGPU_META__?.get(definition)?.name;
33
21
  }
34
22
  function setName(definition, name) {
35
23
  if (isForwarded(definition)) {
36
24
  setName(definition[$getNameForward], name);
37
25
  return;
38
26
  }
39
- setMetaData(definition, { name });
27
+ nameMap.set(definition, name);
40
28
  }
41
- function isNamable(value) {
42
- return !!value?.$name;
29
+ const metadataMap = /* @__PURE__ */ new WeakMap();
30
+ /**
31
+ * Retrieves normalized (non-raw) function metadata.
32
+ * If `globalExt.__TYPEGPU_META__` contains raw metadata for the function,
33
+ * it is normalized, and then deleted to avoid unnecessary re-normalization.
34
+ */
35
+ function getFunctionMetadata(definition) {
36
+ const maybeRawMeta = globalExt.__TYPEGPU_META__?.get(definition);
37
+ if (maybeRawMeta) {
38
+ globalExt.__TYPEGPU_META__?.delete(definition);
39
+ const normalized = normalizeMetadata(maybeRawMeta);
40
+ metadataMap.set(definition, normalized);
41
+ if (maybeRawMeta.name && nameMap.get(definition) === void 0) nameMap.set(definition, maybeRawMeta.name);
42
+ }
43
+ return metadataMap.get(definition);
43
44
  }
44
45
  /**
45
46
  * AST's are given to functions with a 'use gpu' directive, which this function checks for.
46
47
  */
47
48
  function hasTinyestMetadata(value) {
48
- return !!getMetaData(value)?.ast;
49
- }
50
- function getMetaData(definition) {
51
- return globalWithMeta.__TYPEGPU_META__.get(definition);
52
- }
53
- function setMetaData(definition, metaData) {
54
- globalWithMeta.__TYPEGPU_META__ ??= /* @__PURE__ */ new WeakMap();
55
- const map = globalWithMeta.__TYPEGPU_META__;
56
- map.set(definition, {
57
- ...map.get(definition),
58
- ...metaData
59
- });
49
+ return typeof value === "function" && !!getFunctionMetadata(value);
60
50
  }
51
+ /**
52
+ * Performance measurements are only enabled in dev & test environments for now
53
+ */
54
+ const PERF = (DEV || TEST) && {
55
+ get enabled() {
56
+ return !!globalExt.__TYPEGPU_MEASURE_PERF__;
57
+ },
58
+ record(name, data) {
59
+ const records = globalExt.__TYPEGPU_PERF_RECORDS__ ??= /* @__PURE__ */ new Map();
60
+ let entries = records.get(name);
61
+ if (!entries) {
62
+ entries = [];
63
+ records.set(name, entries);
64
+ }
65
+ entries.push(data);
66
+ }
67
+ } || void 0;
61
68
 
62
69
  //#endregion
63
- export { PERF, getMetaData, getName, hasTinyestMetadata, isNamable, setName };
70
+ export { PERF, getFunctionMetadata, getName, hasTinyestMetadata, isNamable, setName };
@@ -0,0 +1,32 @@
1
+ import { Block, FuncParameter } from "tinyest";
2
+
3
+ //#region src/shared/normalizeMetadata.d.ts
4
+ interface RawMetadataV1 {
5
+ v: 1;
6
+ name: string;
7
+ ast: {
8
+ params: FuncParameter[];
9
+ body: Block;
10
+ externalNames: string[];
11
+ };
12
+ externals: Record<string, unknown> | (() => Record<string, unknown>);
13
+ }
14
+ interface ExternalsV2 {
15
+ [key: string]: ExternalsV2 | (() => unknown);
16
+ }
17
+ interface RawMetadataV2 {
18
+ v: 2;
19
+ name: string;
20
+ ast: {
21
+ params: FuncParameter[];
22
+ body: Block;
23
+ externalNames: string[];
24
+ };
25
+ externals: ExternalsV2;
26
+ }
27
+ /**
28
+ * Holds all function info collected by typegpu-unplugin
29
+ */
30
+ type RawMetadata = RawMetadataV1 | RawMetadataV2;
31
+ //#endregion
32
+ export { RawMetadata };
@@ -0,0 +1,40 @@
1
+ import { safeStringify } from "./stringify.js";
2
+
3
+ //#region src/shared/normalizeMetadata.ts
4
+ /**
5
+ * The values of ExternalsV2 are zero-argument functions for accessing the value.
6
+ * Since they would be recognized by the wgslGenerator as regular, non 'use gpu' functions,
7
+ * we turn them into getters.
8
+ *
9
+ * @example
10
+ * normalizeExternalsV2({ ext: { prop: () => ext.prop; }}); // { ext: { prop: [Getter] } }
11
+ */
12
+ function normalizeExternalsV2(externals) {
13
+ const result = {};
14
+ for (const [key, value] of Object.entries(externals)) if (typeof value === "function") Object.defineProperty(result, key, {
15
+ get: value,
16
+ enumerable: true
17
+ });
18
+ else result[key] = normalizeExternalsV2(value);
19
+ return result;
20
+ }
21
+ function normalizeMetadata(meta) {
22
+ if (meta.v === 1) {
23
+ const externals = typeof meta?.externals === "function" ? meta.externals() : meta?.externals;
24
+ return {
25
+ ...meta,
26
+ externals
27
+ };
28
+ }
29
+ if (meta.v === 2) {
30
+ const externals = normalizeExternalsV2(meta?.externals);
31
+ return {
32
+ ...meta,
33
+ externals
34
+ };
35
+ }
36
+ throw new Error(`Unrecognized TypeGPU metadata format: ${safeStringify(meta)}`);
37
+ }
38
+
39
+ //#endregion
40
+ export { normalizeMetadata };
package/std/atomic.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Void, isAtomic } from "../data/wgslTypes.js";
2
- import { stitch } from "../core/resolve/stitch.js";
3
2
  import { safeStringify } from "../shared/stringify.js";
3
+ import { stitch } from "../core/resolve/stitch.js";
4
4
  import { i32, u32 } from "../data/numeric.js";
5
5
  import { dualImpl } from "../core/function/dualImpl.js";
6
6