typegpu 0.11.6 → 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 +2 -2
  35. package/index.js +2 -2
  36. package/indexNamedExports.d.ts +1 -1
  37. package/package.js +1 -1
  38. package/package.json +5 -4
  39. package/resolutionCtx.js +9 -16
  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 +173 -96
  66. package/types.d.ts +6 -4
  67. package/wgslExtensions.d.ts +3 -3
  68. package/wgslExtensions.js +3 -3
package/bin.mjs ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'node:child_process';
3
+ import pkg from './package.json' with { type: 'json' };
4
+
5
+ /**
6
+ * Used to extract the version of `typegpu` that was used to
7
+ * trigger the CLI, which then allows us to download the latest
8
+ * version matching the major and minor of the `typegpu` package.
9
+ */
10
+ const versionPattern = /^(\d+)\.(\d+)\.(\d+)/;
11
+
12
+ const result = versionPattern.exec(pkg.version);
13
+ const [_, major, minor] = result;
14
+
15
+ if (major === undefined || minor === undefined) {
16
+ throw new Error(`TypeGPU version doesn't match the expected major.minor.patch format`);
17
+ }
18
+
19
+ /**
20
+ * Targeting the latest version with the same major and minor as `typegpu`
21
+ */
22
+ const semver = `^${major}.${minor}.0`;
23
+
24
+ function asyncSpawn(...args) {
25
+ return new Promise((resolve, _reject) => {
26
+ const child = spawn(...args);
27
+
28
+ child.on('exit', (code, signal) => {
29
+ if (signal) {
30
+ process.kill(process.pid, signal);
31
+ process.exit(0);
32
+ return;
33
+ }
34
+
35
+ resolve(code);
36
+ });
37
+ });
38
+ }
39
+
40
+ (async () => {
41
+ const code = await asyncSpawn('npx', [`@typegpu/cli@${semver}`, ...process.argv.slice(2)], {
42
+ stdio: ['inherit', 'inherit', 'ignore'],
43
+ });
44
+
45
+ if (code !== 0) {
46
+ console.warn(
47
+ `Couldn't find @typegpu/cli version matching ${semver}, falling back to latest...`,
48
+ );
49
+ // Fallback to latest
50
+ const code = await asyncSpawn('npx', [`@typegpu/cli@latest`, ...process.argv.slice(2)], {
51
+ stdio: 'inherit',
52
+ });
53
+ process.exit(code ?? 0);
54
+ }
55
+
56
+ process.exit(code ?? 0);
57
+ })();
package/builtin.d.ts CHANGED
@@ -13,7 +13,9 @@ type BuiltinSampleMask = Decorated<U32, [Builtin<'sample_mask'>]>;
13
13
  type BuiltinLocalInvocationId = Decorated<Vec3u, [Builtin<'local_invocation_id'>]>;
14
14
  type BuiltinLocalInvocationIndex = Decorated<U32, [Builtin<'local_invocation_index'>]>;
15
15
  type BuiltinGlobalInvocationId = Decorated<Vec3u, [Builtin<'global_invocation_id'>]>;
16
+ type BuiltinGlobalInvocationIndex = Decorated<U32, [Builtin<'global_invocation_index'>]>;
16
17
  type BuiltinWorkgroupId = Decorated<Vec3u, [Builtin<'workgroup_id'>]>;
18
+ type BuiltinWorkgroupIndex = Decorated<U32, [Builtin<'workgroup_index'>]>;
17
19
  type BuiltinNumWorkgroups = Decorated<Vec3u, [Builtin<'num_workgroups'>]>;
18
20
  type BuiltinSubgroupInvocationId = Decorated<U32, [Builtin<'subgroup_invocation_id'>]>;
19
21
  type BuiltinSubgroupSize = Decorated<U32, [Builtin<'subgroup_size'>]>;
@@ -32,7 +34,9 @@ declare const builtin: {
32
34
  readonly localInvocationId: BuiltinLocalInvocationId;
33
35
  readonly localInvocationIndex: BuiltinLocalInvocationIndex;
34
36
  readonly globalInvocationId: BuiltinGlobalInvocationId;
37
+ readonly globalInvocationIndex: BuiltinGlobalInvocationIndex;
35
38
  readonly workgroupId: BuiltinWorkgroupId;
39
+ readonly workgroupIndex: BuiltinWorkgroupIndex;
36
40
  readonly numWorkgroups: BuiltinNumWorkgroups;
37
41
  readonly subgroupInvocationId: BuiltinSubgroupInvocationId;
38
42
  readonly subgroupSize: BuiltinSubgroupSize;
@@ -40,7 +44,7 @@ declare const builtin: {
40
44
  readonly numSubgroups: BuiltinNumSubgroups;
41
45
  };
42
46
  type AnyBuiltin = (typeof builtin)[keyof typeof builtin];
43
- type AnyComputeBuiltin = BuiltinLocalInvocationId | BuiltinLocalInvocationIndex | BuiltinGlobalInvocationId | BuiltinWorkgroupId | BuiltinNumWorkgroups | BuiltinSubgroupInvocationId | BuiltinSubgroupSize | BuiltinSubgroupId | BuiltinNumSubgroups;
47
+ type AnyComputeBuiltin = BuiltinLocalInvocationId | BuiltinLocalInvocationIndex | BuiltinGlobalInvocationId | BuiltinGlobalInvocationIndex | BuiltinWorkgroupId | BuiltinWorkgroupIndex | BuiltinNumWorkgroups | BuiltinSubgroupInvocationId | BuiltinSubgroupSize | BuiltinSubgroupId | BuiltinNumSubgroups;
44
48
  type AnyVertexInputBuiltin = BuiltinVertexIndex | BuiltinInstanceIndex;
45
49
  type AnyVertexOutputBuiltin = BuiltinClipDistances | BuiltinPosition;
46
50
  type AnyFragmentInputBuiltin = BuiltinPosition | BuiltinFrontFacing | BuiltinPrimitiveIndex | BuiltinSampleIndex | BuiltinSampleMask | BuiltinSubgroupInvocationId | BuiltinSubgroupSize;
package/builtin.js CHANGED
@@ -25,7 +25,9 @@ const builtin = {
25
25
  localInvocationId: defineBuiltin(vec3u, "local_invocation_id"),
26
26
  localInvocationIndex: defineBuiltin(u32, "local_invocation_index"),
27
27
  globalInvocationId: defineBuiltin(vec3u, "global_invocation_id"),
28
+ globalInvocationIndex: defineBuiltin(u32, "global_invocation_index"),
28
29
  workgroupId: defineBuiltin(vec3u, "workgroup_id"),
30
+ workgroupIndex: defineBuiltin(u32, "workgroup_index"),
29
31
  numWorkgroups: defineBuiltin(vec3u, "num_workgroups"),
30
32
  subgroupInvocationId: defineBuiltin(u32, "subgroup_invocation_id"),
31
33
  subgroupSize: defineBuiltin(u32, "subgroup_size"),
@@ -1,6 +1,6 @@
1
1
  import { $internal } from "../../shared/symbols.js";
2
- import { getName, setName } from "../../shared/meta.js";
3
2
  import { isWgslData } from "../../data/wgslTypes.js";
3
+ import { getName, setName } from "../../shared/meta.js";
4
4
  import { isGPUBuffer } from "../../types.js";
5
5
  import { sizeOf } from "../../data/sizeOf.js";
6
6
  import { getCompiledWriter } from "../../data/compiledIO.js";
@@ -1,6 +1,5 @@
1
1
  import { $getNameForward, $gpuValueOf, $internal, $ownSnippet, $resolve } from "../../shared/symbols.js";
2
2
  import { getName, setName } from "../../shared/meta.js";
3
- import { isNaturallyEphemeral } from "../../data/wgslTypes.js";
4
3
  import { snip } from "../../data/snippet.js";
5
4
  import { IllegalBufferAccessError } from "../../errors.js";
6
5
  import { getExecMode, inCodegenMode, isInsideTgpuFn } from "../../execMode.js";
@@ -13,11 +12,6 @@ import { isUsableAsStorage } from "../../extension.js";
13
12
  function isUsableAsUniform(buffer) {
14
13
  return !!buffer.usableAsUniform;
15
14
  }
16
- const usageToVarTemplateMap = {
17
- uniform: "uniform",
18
- mutable: "storage, read_write",
19
- readonly: "storage, read"
20
- };
21
15
  var TgpuFixedBufferImpl = class {
22
16
  resourceType = "buffer-usage";
23
17
  usage;
@@ -41,9 +35,14 @@ var TgpuFixedBufferImpl = class {
41
35
  storage: dataType,
42
36
  access: this.usage
43
37
  }, this.buffer);
44
- const usage = usageToVarTemplateMap[this.usage];
45
- ctx.addDeclaration(`@group(${group}) @binding(${binding}) var<${usage}> ${id}: ${ctx.resolve(dataType).value};`);
46
- return snip(id, dataType, isNaturallyEphemeral(dataType) ? "runtime" : this.usage);
38
+ return ctx.gen.declareGlobalVar({
39
+ group,
40
+ binding,
41
+ scope: this.usage,
42
+ id,
43
+ dataType,
44
+ init: void 0
45
+ });
47
46
  }
48
47
  toString() {
49
48
  return `${this.usage}:${getName(this) ?? "<unnamed>"}`;
@@ -54,7 +53,7 @@ var TgpuFixedBufferImpl = class {
54
53
  return new Proxy({
55
54
  [$internal]: true,
56
55
  get [$ownSnippet]() {
57
- return snip(this, dataType, isNaturallyEphemeral(dataType) ? "runtime" : usage);
56
+ return snip(this, dataType, usage);
58
57
  },
59
58
  [$resolve]: (ctx) => ctx.resolve(this),
60
59
  toString: () => `${this.usage}:${getName(this) ?? "<unnamed>"}.$`
@@ -105,9 +104,14 @@ var TgpuLaidOutBufferImpl = class {
105
104
  [$resolve](ctx) {
106
105
  const id = ctx.makeUniqueIdentifier(getName(this), "global");
107
106
  const group = ctx.allocateLayoutEntry(this.#membership.layout);
108
- const usage = usageToVarTemplateMap[this.usage];
109
- ctx.addDeclaration(`@group(${group}) @binding(${this.#membership.idx}) var<${usage}> ${id}: ${ctx.resolve(this.dataType).value};`);
110
- return snip(id, this.dataType, isNaturallyEphemeral(this.dataType) ? "runtime" : this.usage);
107
+ return ctx.gen.declareGlobalVar({
108
+ group,
109
+ binding: this.#membership.idx,
110
+ scope: this.usage,
111
+ id,
112
+ dataType: this.dataType,
113
+ init: void 0
114
+ });
111
115
  }
112
116
  toString() {
113
117
  return `${this.usage}:${getName(this) ?? "<unnamed>"}`;
@@ -118,7 +122,7 @@ var TgpuLaidOutBufferImpl = class {
118
122
  return new Proxy({
119
123
  [$internal]: true,
120
124
  get [$ownSnippet]() {
121
- return snip(this, schema, isNaturallyEphemeral(schema) ? "runtime" : usage);
125
+ return snip(this, schema, usage);
122
126
  },
123
127
  [$resolve]: (ctx) => ctx.resolve(this),
124
128
  toString: () => `${this.usage}:${getName(this) ?? "<unnamed>"}.$`
@@ -1,6 +1,5 @@
1
1
  import { $gpuValueOf, $internal, $ownSnippet, $resolve } from "../../shared/symbols.js";
2
2
  import { getName, setName } from "../../shared/meta.js";
3
- import { isNaturallyEphemeral } from "../../data/wgslTypes.js";
4
3
  import { isData } from "../../data/dataTypes.js";
5
4
  import { snip } from "../../data/snippet.js";
6
5
  import { inCodegenMode } from "../../execMode.js";
@@ -38,10 +37,11 @@ var TgpuConstImpl = class {
38
37
  }
39
38
  [$resolve](ctx) {
40
39
  const id = ctx.makeUniqueIdentifier(getName(this), "global");
41
- const resolvedDataType = ctx.resolve(this.dataType).value;
42
- const resolvedValue = ctx.resolve(this.#value, this.dataType).value;
43
- ctx.addDeclaration(`const ${id}: ${resolvedDataType} = ${resolvedValue};`);
44
- return snip(id, this.dataType, isNaturallyEphemeral(this.dataType) ? "constant" : "constant-tgpu-const-ref");
40
+ return ctx.gen.declareGlobalConst({
41
+ id,
42
+ dataType: this.dataType,
43
+ init: snip(this.#value, this.dataType, "constant")
44
+ });
45
45
  }
46
46
  toString() {
47
47
  return `const:${getName(this) ?? "<unnamed>"}`;
@@ -51,7 +51,7 @@ var TgpuConstImpl = class {
51
51
  return new Proxy({
52
52
  [$internal]: true,
53
53
  get [$ownSnippet]() {
54
- return snip(this, dataType, isNaturallyEphemeral(dataType) ? "constant" : "constant-tgpu-const-ref");
54
+ return snip(this, dataType, "constant-immutable-def");
55
55
  },
56
56
  [$resolve]: (ctx) => ctx.resolve(this),
57
57
  toString: () => `const:${getName(this) ?? "<unnamed>"}.$`
@@ -1,7 +1,7 @@
1
1
  import { $getNameForward, $gpuCallable, $internal } from "../../shared/symbols.js";
2
2
  import { setName } from "../../shared/meta.js";
3
3
  import { WgslTypeError } from "../../errors.js";
4
- import { isKnownAtComptime } from "../../types.js";
4
+ import { NormalState, isKnownAtComptime } from "../../types.js";
5
5
  import { coerceToSnippet } from "../../tgsl/generationHelpers.js";
6
6
 
7
7
  //#region src/core/function/comptime.ts
@@ -35,9 +35,14 @@ function comptime(func) {
35
35
  });
36
36
  impl.toString = () => "comptime";
37
37
  impl[$getNameForward] = func;
38
- impl[$gpuCallable] = { call(_ctx, args) {
38
+ impl[$gpuCallable] = { call(ctx, args) {
39
39
  if (!args.every((s) => isKnownAtComptime(s))) throw new WgslTypeError(`Called comptime function with runtime-known values: ${args.filter((s) => !isKnownAtComptime(s)).map((s) => `'${s.value}'`).join(", ")}`);
40
- return coerceToSnippet(func(...args.map((s) => s.value)));
40
+ ctx.pushMode(new NormalState());
41
+ try {
42
+ return coerceToSnippet(func(...args.map((s) => s.value)));
43
+ } finally {
44
+ ctx.popMode();
45
+ }
41
46
  } };
42
47
  impl.$name = (label) => {
43
48
  setName(func, label);
@@ -1,7 +1,7 @@
1
1
  import { $gpuCallable } from "../../shared/symbols.js";
2
- import { setName } from "../../shared/meta.js";
3
2
  import { isPtr } from "../../data/wgslTypes.js";
4
- import { snip } from "../../data/snippet.js";
3
+ import { setName } from "../../shared/meta.js";
4
+ import { noSideEffects, snip } from "../../data/snippet.js";
5
5
  import { NormalState, isKnownAtComptime } from "../../types.js";
6
6
  import { tryConvertSnippet } from "../../tgsl/conversion.js";
7
7
 
@@ -24,15 +24,17 @@ function callableSchema(options) {
24
24
  if (!argType) throw new Error("Function called with invalid arguments");
25
25
  return tryConvertSnippet(ctx, s, argType, false);
26
26
  });
27
+ let result;
27
28
  if (converted.every((s) => isKnownAtComptime(s))) {
28
29
  ctx.pushMode(new NormalState());
29
30
  try {
30
- return snip(options.normalImpl(...converted.map((s) => s.value)), options.schema(), "constant");
31
+ result = snip(options.normalImpl(...converted.map((s) => s.value)), options.schema(), "constant");
31
32
  } finally {
32
33
  ctx.popMode("normal");
33
34
  }
34
- }
35
- return options.codegenImpl(ctx, converted);
35
+ } else result = options.codegenImpl(ctx, converted);
36
+ if (!args.some((a) => a.possibleSideEffects)) return noSideEffects(result);
37
+ return result;
36
38
  }
37
39
  };
38
40
  return impl;
@@ -1,6 +1,6 @@
1
1
  import { $gpuCallable } from "../../shared/symbols.js";
2
- import { setName } from "../../shared/meta.js";
3
2
  import { isPtr } from "../../data/wgslTypes.js";
3
+ import { setName } from "../../shared/meta.js";
4
4
  import { snip } from "../../data/snippet.js";
5
5
  import { NormalState, isKnownAtComptime } from "../../types.js";
6
6
  import { tryConvertSnippet } from "../../tgsl/conversion.js";
@@ -18,7 +18,7 @@ function dualImpl(options) {
18
18
  if (typeof options.normalImpl === "string") throw new MissingCpuImplError(options.normalImpl);
19
19
  return options.normalImpl(...args);
20
20
  });
21
- setName(impl, options.name);
21
+ if (options.name) setName(impl, options.name);
22
22
  impl.toString = () => options.name ?? "<unknown>";
23
23
  impl[$gpuCallable] = {
24
24
  get strictSignature() {
@@ -1,9 +1,8 @@
1
1
  import { $getNameForward } from "../../shared/symbols.js";
2
- import { getMetaData, getName } from "../../shared/meta.js";
3
2
  import { Void, isWgslData, isWgslStruct } from "../../data/wgslTypes.js";
3
+ import { getFunctionMetadata, getName } from "../../shared/meta.js";
4
4
  import { undecorate } from "../../data/dataTypes.js";
5
5
  import { snip } from "../../data/snippet.js";
6
- import { MissingLinksError } from "../../errors.js";
7
6
  import { getAttributesString } from "../../data/attributes.js";
8
7
  import { validateIdentifier } from "../../nameUtils.js";
9
8
  import { applyExternals, replaceExternalsInWgsl } from "../resolve/externals.js";
@@ -64,17 +63,17 @@ function createFnCore(implementation, functionType, workgroupSize) {
64
63
  ctx.addDeclaration(`${attributes}fn ${id}${header}${body}`);
65
64
  return snip(id, returnType, "runtime");
66
65
  }
67
- const pluginData = getMetaData(implementation);
68
- const pluginExternals = typeof pluginData?.externals === "function" ? pluginData.externals() : pluginData?.externals;
66
+ const pluginData = getFunctionMetadata(implementation);
67
+ const pluginExternals = pluginData?.externals;
69
68
  if (pluginExternals) applyExternals(externalMap, Object.fromEntries(Object.entries(pluginExternals).filter(([name]) => !(name in externalMap))));
70
69
  const ast = pluginData?.ast;
71
70
  if (!ast) throw new Error("Missing metadata for tgpu.fn function body (either missing 'use gpu' directive, or misconfigured `unplugin-typegpu`)");
72
- const missingExternals = ast.externalNames.filter((name) => !(name in externalMap));
73
- if (missingExternals.length > 0) throw new MissingLinksError(getName(this), missingExternals);
74
71
  const maybeSecondArg = ast.params[1];
75
72
  if (maybeSecondArg && maybeSecondArg.type === "i" && functionType !== "normal") applyExternals(externalMap, { [maybeSecondArg.name]: undecorate(returnType) });
76
- const { code, returnType: actualReturnType } = ctx.fnToWgsl({
73
+ const { code, returnType: actualReturnType } = ctx.resolveFunction({
77
74
  functionType,
75
+ name: id,
76
+ workgroupSize,
78
77
  argTypes,
79
78
  entryInput,
80
79
  params: ast.params,
@@ -82,7 +81,7 @@ function createFnCore(implementation, functionType, workgroupSize) {
82
81
  body: ast.body,
83
82
  externalMap
84
83
  });
85
- ctx.addDeclaration(`${attributes}fn ${id}${code}`);
84
+ ctx.addDeclaration(code);
86
85
  return snip(id, actualReturnType, "runtime");
87
86
  }
88
87
  };
@@ -1,6 +1,6 @@
1
1
  import { $getNameForward, $internal, $resolve } from "../../shared/symbols.js";
2
- import { getName, setName } from "../../shared/meta.js";
3
2
  import { Void } from "../../data/wgslTypes.js";
3
+ import { getName, setName } from "../../shared/meta.js";
4
4
  import { separateBuiltins } from "./ioSchema.js";
5
5
  import { createFnCore } from "./fnCore.js";
6
6
  import { stripTemplate } from "./templateUtils.js";
@@ -1,6 +1,6 @@
1
1
  import { $getNameForward, $internal, $providing, $resolve, isMarkedInternal } from "../../shared/symbols.js";
2
- import { getName, setName } from "../../shared/meta.js";
3
2
  import { Void } from "../../data/wgslTypes.js";
3
+ import { getName, setName } from "../../shared/meta.js";
4
4
  import { ExecutionError } from "../../errors.js";
5
5
  import { isAccessor, isMutableAccessor } from "../slot/slotTypes.js";
6
6
  import { provideInsideTgpuFn } from "../../execMode.js";
@@ -157,7 +157,8 @@ function createGenericFn(inner, pairs) {
157
157
  return inner(...args);
158
158
  };
159
159
  const genericFn = Object.assign(call, fnBase);
160
- if (getName(inner)) setName(genericFn, getName(inner));
160
+ const innerName = getName(inner);
161
+ if (innerName) setName(genericFn, innerName);
161
162
  Object.defineProperty(genericFn, "toString", { value() {
162
163
  const fnLabel = getName(genericFn) ?? "<unnamed>";
163
164
  if (pairs.length > 0) return `fn*:${fnLabel}[${pairs.map(stringifyPair).join(", ")}]`;
@@ -1,6 +1,6 @@
1
1
  import { $getNameForward, $internal, $resolve } from "../../shared/symbols.js";
2
- import { PERF, getName, setName } from "../../shared/meta.js";
3
2
  import { Void } from "../../data/wgslTypes.js";
3
+ import { PERF, getName, setName } from "../../shared/meta.js";
4
4
  import { snip } from "../../data/snippet.js";
5
5
  import { isGPUBuffer } from "../../types.js";
6
6
  import { isBindGroup } from "../../tgpuBindGroupLayout.js";
@@ -9,7 +9,7 @@ import { isGPUCommandEncoder, isGPUComputePassEncoder } from "./typeGuards.js";
9
9
  import { namespace } from "../resolve/namespace.js";
10
10
  import { applyBindGroups } from "./applyPipelineState.js";
11
11
  import { logDataFromGPU } from "../../tgsl/consoleLog/deserializers.js";
12
- import { wgslExtensionToFeatureName, wgslExtensions } from "../../wgslExtensions.js";
12
+ import { wgslEnableExtensionToFeatureName, wgslEnableExtensions } from "../../wgslExtensions.js";
13
13
  import { resolveIndirectOffset } from "./pipelineUtils.js";
14
14
  import { createWithPerformanceCallback, createWithTimestampWrites, setupTimestampWrites, triggerPerformanceCallback } from "./timeable.js";
15
15
 
@@ -172,7 +172,7 @@ var ComputePipelineCore = class {
172
172
  unwrap() {
173
173
  if (this._memo === void 0) {
174
174
  const device = this.root.device;
175
- const enableExtensions = wgslExtensions.filter((extension) => this.root.enabledFeatures.has(wgslExtensionToFeatureName[extension]));
175
+ const enableExtensions = wgslEnableExtensions.filter((extension) => this.root.enabledFeatures.has(wgslEnableExtensionToFeatureName[extension]));
176
176
  let resolutionResult;
177
177
  let resolveMeasure;
178
178
  const ns = namespace({ names: this.root.nameRegistrySetting });
@@ -1,6 +1,6 @@
1
1
  import { $getNameForward, $internal, $resolve } from "../../shared/symbols.js";
2
- import { PERF, getName, setName } from "../../shared/meta.js";
3
2
  import { Void, isWgslData } from "../../data/wgslTypes.js";
3
+ import { PERF, getName, setName } from "../../shared/meta.js";
4
4
  import { getCustomLocation } from "../../data/dataTypes.js";
5
5
  import { snip } from "../../data/snippet.js";
6
6
  import { isGPUBuffer } from "../../types.js";
@@ -15,7 +15,7 @@ import { isGPUCommandEncoder, isGPURenderBundleEncoder, isGPURenderPassEncoder }
15
15
  import { namespace } from "../resolve/namespace.js";
16
16
  import { applyBindGroups, applyVertexBuffers } from "./applyPipelineState.js";
17
17
  import { logDataFromGPU } from "../../tgsl/consoleLog/deserializers.js";
18
- import { wgslExtensionToFeatureName, wgslExtensions } from "../../wgslExtensions.js";
18
+ import { wgslEnableExtensionToFeatureName, wgslEnableExtensions } from "../../wgslExtensions.js";
19
19
  import { resolveIndirectOffset } from "./pipelineUtils.js";
20
20
  import { createWithPerformanceCallback, createWithTimestampWrites, setupTimestampWrites, triggerPerformanceCallback } from "./timeable.js";
21
21
  import { AutoFragmentFn, AutoVertexFn } from "../function/autoIO.js";
@@ -378,7 +378,7 @@ var RenderPipelineCore = class {
378
378
  if (this._memo !== void 0) return this._memo;
379
379
  const { root, descriptor: tgpuDescriptor } = this.options;
380
380
  const device = root.device;
381
- const enableExtensions = wgslExtensions.filter((extension) => root.enabledFeatures.has(wgslExtensionToFeatureName[extension]));
381
+ const enableExtensions = wgslEnableExtensions.filter((extension) => root.enabledFeatures.has(wgslEnableExtensionToFeatureName[extension]));
382
382
  let resolutionResult;
383
383
  let resolveMeasure;
384
384
  const ns = namespace({ names: root.nameRegistrySetting });
@@ -16,7 +16,7 @@ interface TgpuRawCodeSnippet<TDataType extends BaseData> {
16
16
  readonly [$gpuValueOf]: InferGPU<TDataType>;
17
17
  $uses(dependencyMap: Record<string, unknown>): this;
18
18
  }
19
- type RawCodeSnippetOrigin = Exclude<Origin, 'function' | 'this-function' | 'argument' | 'constant-ref'>;
19
+ type RawCodeSnippetOrigin = Exclude<Origin, 'function' | 'local-def' | 'argument' | 'constant-immutable-def' | 'runtime-immutable-def'>;
20
20
  /**
21
21
  * An advanced API that creates a typed shader expression which
22
22
  * can be injected into the final shader bundle upon use.
@@ -1,5 +1,5 @@
1
- import { getName, hasTinyestMetadata, setName } from "../../shared/meta.js";
2
1
  import { isWgslStruct } from "../../data/wgslTypes.js";
2
+ import { getName, hasTinyestMetadata, setName } from "../../shared/meta.js";
3
3
  import { isLooseData } from "../../data/dataTypes.js";
4
4
  import { isWgsl } from "../../types.js";
5
5
 
@@ -1,6 +1,6 @@
1
1
  import { ShaderGenerator } from "../../tgsl/shaderGenerator.js";
2
2
  import { Configurable } from "../root/rootTypes.js";
3
- import { WgslExtension } from "../../wgslExtensions.js";
3
+ import { WgslEnableExtension } from "../../wgslExtensions.js";
4
4
  import { ResolvableObject, Wgsl } from "../../types.js";
5
5
  import { Namespace } from "./namespace.js";
6
6
  import { ResolutionResult } from "../../resolutionCtx.js";
@@ -27,7 +27,7 @@ interface TgpuResolveOptions {
27
27
  /**
28
28
  * List of WGSL shader extensions to enable.
29
29
  */
30
- enableExtensions?: WgslExtension[] | undefined;
30
+ enableExtensions?: WgslEnableExtension[] | undefined;
31
31
  /**
32
32
  * **NOTE: This is an unstable API and may change in the future.**
33
33
  *
package/core/root/init.js CHANGED
@@ -12,6 +12,7 @@ import { clearTextureUtilsCache } from "../texture/textureUtils.js";
12
12
  import { INTERNAL_createTexture, isTexture, isTextureView } from "../texture/texture.js";
13
13
  import { TgpuBindGroupImpl, isBindGroup, isBindGroupLayout } from "../../tgpuBindGroupLayout.js";
14
14
  import { ceil } from "../../std/numeric.js";
15
+ import { allEq } from "../../std/boolean.js";
15
16
  import { isComputePipeline, isRenderPipeline } from "../pipeline/typeGuards.js";
16
17
  import { builtin } from "../../builtin.js";
17
18
  import { INTERNAL_createQuerySet, isQuerySet } from "../querySet/querySet.js";
@@ -22,7 +23,6 @@ import { applyBindGroups, applyVertexBuffers } from "../pipeline/applyPipelineSt
22
23
  import { INTERNAL_createComputePipeline } from "../pipeline/computePipeline.js";
23
24
  import { isVertexLayout } from "../vertexLayout/vertexLayout.js";
24
25
  import { INTERNAL_createRenderPipeline } from "../pipeline/renderPipeline.js";
25
- import { allEq } from "../../std/boolean.js";
26
26
 
27
27
  //#region src/core/root/init.ts
28
28
  /**
@@ -51,7 +51,7 @@ var AccessorBase = class {
51
51
  if (isTgpuFn(value) || hasTinyestMetadata(value)) return ctx.withResetIndentLevel(() => snip(`${ctx.resolve(value).value}()`, this.schema, "runtime"));
52
52
  ctx.pushMode(new NormalState());
53
53
  try {
54
- return snip(schemaCallWrapper(this.schema, value), this.schema, "constant");
54
+ return snip(schemaCallWrapper(this.schema, value), this.schema, "constant", false);
55
55
  } finally {
56
56
  ctx.popMode("normal");
57
57
  }
@@ -251,8 +251,14 @@ var TgpuFixedTextureViewImpl = class {
251
251
  texture: this.schema,
252
252
  sampleType: this.#descriptor?.sampleType ?? this.schema.bindingSampleType[0]
253
253
  }, this);
254
- ctx.addDeclaration(`@group(${group}) @binding(${binding}) var ${id}: ${ctx.resolve(this.schema).value};`);
255
- return snip(id, this.schema, "handle");
254
+ return ctx.gen.declareGlobalVar({
255
+ group,
256
+ binding,
257
+ id,
258
+ dataType: this.schema,
259
+ scope: "handle",
260
+ init: void 0
261
+ });
256
262
  }
257
263
  };
258
264
  var TgpuLaidOutTextureViewImpl = class {
@@ -1,6 +1,5 @@
1
1
  import { $gpuValueOf, $internal, $ownSnippet, $resolve } from "../../shared/symbols.js";
2
2
  import { getName, setName } from "../../shared/meta.js";
3
- import { isNaturallyEphemeral } from "../../data/wgslTypes.js";
4
3
  import { snip } from "../../data/snippet.js";
5
4
  import { IllegalVarAccessError } from "../../errors.js";
6
5
  import { getExecMode, isInsideTgpuFn } from "../../execMode.js";
@@ -43,10 +42,13 @@ var TgpuVarImpl = class {
43
42
  }
44
43
  [$resolve](ctx) {
45
44
  const id = ctx.makeUniqueIdentifier(getName(this), "global");
46
- const pre = `var<${this.#scope}> ${id}: ${ctx.resolve(this.#dataType).value}`;
47
- if (this.#initialValue) ctx.addDeclaration(`${pre} = ${ctx.resolve(this.#initialValue, this.#dataType).value};`);
48
- else ctx.addDeclaration(`${pre};`);
49
- return snip(id, this.#dataType, isNaturallyEphemeral(this.#dataType) ? "runtime" : this.#scope);
45
+ const init = this.#initialValue ? snip(this.#initialValue, this.#dataType, "constant") : void 0;
46
+ return ctx.gen.declareGlobalVar({
47
+ scope: this.#scope,
48
+ id,
49
+ dataType: this.#dataType,
50
+ init
51
+ });
50
52
  }
51
53
  $name(label) {
52
54
  setName(this, label);
@@ -57,7 +59,7 @@ var TgpuVarImpl = class {
57
59
  }
58
60
  get [$gpuValueOf]() {
59
61
  const dataType = this.#dataType;
60
- const origin = isNaturallyEphemeral(dataType) ? "runtime" : this.#scope;
62
+ const origin = this.#scope;
61
63
  return new Proxy({
62
64
  [$internal]: true,
63
65
  get [$ownSnippet]() {
@@ -1,7 +1,7 @@
1
1
  import { $internal } from "../../shared/symbols.js";
2
+ import { isDecorated, isWgslStruct } from "../../data/wgslTypes.js";
2
3
  import { setName } from "../../shared/meta.js";
3
4
  import { kindToDefaultFormatMap, vertexFormats } from "../../shared/vertexFormat.js";
4
- import { isDecorated, isWgslStruct } from "../../data/wgslTypes.js";
5
5
  import { getCustomLocation, isLooseDecorated, isUnstruct } from "../../data/dataTypes.js";
6
6
  import { alignmentOf, customAlignmentOf } from "../../data/alignmentOf.js";
7
7
  import { roundUp } from "../../mathUtils.js";
@@ -1,6 +1,6 @@
1
1
  import { isDecorated, isWgslArray, isWgslStruct } from "./wgslTypes.js";
2
- import { getCustomAlignment, isDisarray, isLooseDecorated, isUnstruct } from "./dataTypes.js";
3
2
  import { safeStringify } from "../shared/stringify.js";
3
+ import { getCustomAlignment, isDisarray, isLooseDecorated, isUnstruct } from "./dataTypes.js";
4
4
  import { packedFormats } from "./vertexFormatData.js";
5
5
 
6
6
  //#region src/data/alignmentOf.ts
@@ -2,7 +2,7 @@ import { Align, AnyWgslData, BaseData, Builtin, Decorated, FlatInterpolatableDat
2
2
  import { AnyData, AnyLooseData, IsLooseData, LooseDecorated, Undecorate } from "./dataTypes.js";
3
3
 
4
4
  //#region src/data/attributes.d.ts
5
- declare const builtinNames: readonly ["vertex_index", "instance_index", "clip_distances", "position", "front_facing", "frag_depth", "primitive_index", "sample_index", "sample_mask", "fragment", "local_invocation_id", "local_invocation_index", "global_invocation_id", "workgroup_id", "num_workgroups", "subgroup_invocation_id", "subgroup_size", "subgroup_id", "num_subgroups"];
5
+ declare const builtinNames: readonly ["vertex_index", "instance_index", "clip_distances", "position", "front_facing", "frag_depth", "primitive_index", "sample_index", "sample_mask", "fragment", "local_invocation_id", "local_invocation_index", "global_invocation_id", "global_invocation_index", "workgroup_id", "workgroup_index", "num_workgroups", "subgroup_invocation_id", "subgroup_size", "subgroup_id", "num_subgroups"];
6
6
  type BuiltinName = (typeof builtinNames)[number];
7
7
  type AnyAttribute<AllowedBuiltins extends Builtin<BuiltinName> = Builtin<BuiltinName>> = Align<number> | Size<number> | Location | Interpolate | Invariant | AllowedBuiltins;
8
8
  type ExtractAttributes<T> = T extends {
package/data/dataIO.js CHANGED
@@ -1,5 +1,5 @@
1
- import { getName } from "../shared/meta.js";
2
1
  import { isWgslArray } from "./wgslTypes.js";
2
+ import { getName } from "../shared/meta.js";
3
3
  import { vec2f, vec2h, vec2i, vec2u, vec3f, vec3h, vec3i, vec3u, vec4f, vec4h, vec4i, vec4u } from "./vector.js";
4
4
  import { alignmentOf, customAlignmentOf } from "./alignmentOf.js";
5
5
  import { roundUp } from "../mathUtils.js";
@@ -4,7 +4,6 @@ import { Prettify } from "../shared/utilityTypes.js";
4
4
  import "./sampler.js";
5
5
  import "./snippet.js";
6
6
  import { PackedData } from "./vertexFormatData.js";
7
- import "../types.js";
8
7
  import { AnyWgslData, BaseData, TypedArrayFor } from "./wgslTypes.js";
9
8
  import "./texture.js";
10
9
  import { Infer, InferGPURecord, InferInput, InferInputRecord, InferPartial, InferPartialRecord, InferPatch, InferPatchRecord, InferRecord, IsValidVertexSchema, MemIdentityRecord } from "../shared/repr.js";
package/data/dataTypes.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { isMarkedInternal } from "../shared/symbols.js";
2
- import { vertexFormats } from "../shared/vertexFormat.js";
3
2
  import { isAlignAttrib, isDecorated, isLocationAttrib, isPtr, isSizeAttrib, isWgslData } from "./wgslTypes.js";
3
+ import { vertexFormats } from "../shared/vertexFormat.js";
4
4
 
5
5
  //#region src/data/dataTypes.ts
6
6
  /**
@@ -72,16 +72,6 @@ function isData(value) {
72
72
  return isWgslData(value) || isLooseData(value);
73
73
  }
74
74
  const UnknownData = Symbol("UNKNOWN");
75
- var InfixDispatch = class {
76
- name;
77
- lhs;
78
- operator;
79
- constructor(name, lhs, operator) {
80
- this.name = name;
81
- this.lhs = lhs;
82
- this.operator = operator;
83
- }
84
- };
85
75
  var MatrixColumnsAccess = class {
86
76
  matrix;
87
77
  constructor(matrix) {
@@ -90,4 +80,4 @@ var MatrixColumnsAccess = class {
90
80
  };
91
81
 
92
82
  //#endregion
93
- export { InfixDispatch, MatrixColumnsAccess, UnknownData, getCustomAlignment, getCustomLocation, getCustomSize, isData, isDisarray, isLooseData, isLooseDecorated, isUnstruct, undecorate, unptr };
83
+ export { MatrixColumnsAccess, UnknownData, getCustomAlignment, getCustomLocation, getCustomSize, isData, isDisarray, isLooseData, isLooseDecorated, isUnstruct, undecorate, unptr };