typegpu 0.11.3 → 0.11.5

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 (59) hide show
  1. package/README.md +4 -2
  2. package/core/buffer/buffer.js +17 -53
  3. package/core/buffer/bufferUsage.js +2 -2
  4. package/core/constant/tgpuConstant.js +1 -1
  5. package/core/function/fnCore.js +12 -6
  6. package/core/function/tgpuFragmentFn.d.ts +1 -1
  7. package/core/pipeline/computePipeline.d.ts +1 -1
  8. package/core/pipeline/computePipeline.js +1 -1
  9. package/core/pipeline/renderPipeline.js +1 -1
  10. package/core/resolve/namespace.d.ts +2 -11
  11. package/core/resolve/namespace.js +7 -24
  12. package/core/resolve/resolveData.js +3 -2
  13. package/core/resolve/tgpuResolve.js +1 -1
  14. package/core/root/init.d.ts +1 -0
  15. package/core/root/init.js +6 -0
  16. package/core/root/rootTypes.d.ts +21 -15
  17. package/core/sampler/sampler.js +2 -2
  18. package/core/simulate/tgpuSimulate.js +1 -1
  19. package/core/slot/accessor.js +1 -1
  20. package/core/texture/externalTexture.js +1 -1
  21. package/core/texture/texture.js +2 -2
  22. package/core/variable/tgpuVariable.js +1 -1
  23. package/data/autoStruct.js +3 -2
  24. package/data/dataIO.d.ts +11 -0
  25. package/data/dataIO.js +45 -1
  26. package/data/dataTypes.d.ts +1 -1
  27. package/data/dataTypes.js +2 -11
  28. package/data/partialIO.d.ts +8 -0
  29. package/data/partialIO.js +6 -1
  30. package/data/struct.js +3 -2
  31. package/data/wgslTypes.d.ts +16 -16
  32. package/index.d.ts +3 -1
  33. package/index.js +3 -1
  34. package/indexNamedExports.d.ts +2 -0
  35. package/{nameRegistry.js → nameUtils.js} +46 -90
  36. package/package.js +1 -1
  37. package/package.json +1 -1
  38. package/resolutionCtx.js +64 -30
  39. package/shared/stringify.js +1 -0
  40. package/shared/tseynit.js +90 -0
  41. package/std/copy.d.ts +7 -0
  42. package/std/copy.js +27 -0
  43. package/std/index.d.ts +3 -2
  44. package/std/index.js +3 -1
  45. package/tgpuUnstable.js +1 -1
  46. package/tgsl/accessIndex.js +2 -1
  47. package/tgsl/consoleLog/deserializers.js +1 -1
  48. package/tgsl/consoleLog/logGenerator.js +1 -6
  49. package/tgsl/consoleLog/types.d.ts +4 -5
  50. package/tgsl/conversion.js +4 -1
  51. package/tgsl/generationHelpers.d.ts +2 -1
  52. package/tgsl/jsPolyfills.d.ts +25 -0
  53. package/tgsl/jsPolyfills.js +44 -0
  54. package/tgsl/wgslGenerator.d.ts +20 -2
  55. package/tgsl/wgslGenerator.js +114 -57
  56. package/types.d.ts +29 -2
  57. package/nameRegistry.d.ts +0 -30
  58. package/tgsl/consoleLog/types.js +0 -12
  59. package/tgsl/math.js +0 -45
package/resolutionCtx.js CHANGED
@@ -12,12 +12,12 @@ import { safeStringify } from "./shared/stringify.js";
12
12
  import { getBestConversion } from "./tgsl/conversion.js";
13
13
  import { bool } from "./data/numeric.js";
14
14
  import { coerceToSnippet, concretize, numericLiteralToSnippet } from "./tgsl/generationHelpers.js";
15
+ import { sanitizePrimer, validateIdentifier } from "./nameUtils.js";
15
16
  import { createIoSchema } from "./core/function/ioSchema.js";
16
17
  import { AutoStruct } from "./data/autoStruct.js";
17
18
  import { EntryInputRouter } from "./core/function/entryInputRouter.js";
18
19
  import { accessProp } from "./tgsl/accessProp.js";
19
20
  import { isTgpuFn } from "./core/function/tgpuFn.js";
20
- import { getUniqueName } from "./core/resolve/namespace.js";
21
21
  import { ConfigurableImpl } from "./core/root/configurableImpl.js";
22
22
  import { naturalsExcept } from "./shared/generators.js";
23
23
  import { TgpuBindGroupImpl, bindGroupLayout } from "./tgpuBindGroupLayout.js";
@@ -50,6 +50,9 @@ var ItemStateStackImpl = class {
50
50
  get topFunctionScope() {
51
51
  return this._stack.findLast((e) => e.type === "functionScope");
52
52
  }
53
+ get topBlockScope() {
54
+ return this._stack.findLast((e) => e.type === "blockScope");
55
+ }
53
56
  pushItem() {
54
57
  this._itemDepth++;
55
58
  this._stack.push({
@@ -70,7 +73,9 @@ var ItemStateStackImpl = class {
70
73
  argAccess,
71
74
  returnType,
72
75
  externalMap,
73
- reportedReturnTypes: /* @__PURE__ */ new Set()
76
+ reportedReturnTypes: /* @__PURE__ */ new Set(),
77
+ placeholderForVariable: /* @__PURE__ */ new Map(),
78
+ modifiedVariables: /* @__PURE__ */ new Set()
74
79
  };
75
80
  this._stack.push(scope);
76
81
  return scope;
@@ -78,6 +83,7 @@ var ItemStateStackImpl = class {
78
83
  pushBlockScope() {
79
84
  this._stack.push({
80
85
  type: "blockScope",
86
+ takenLocalIdentifiers: /* @__PURE__ */ new Set(),
81
87
  declarations: /* @__PURE__ */ new Map(),
82
88
  externals: /* @__PURE__ */ new Map()
83
89
  });
@@ -116,6 +122,16 @@ var ItemStateStackImpl = class {
116
122
  }
117
123
  }
118
124
  }
125
+ isIdentifierTakenLocally(id) {
126
+ for (let i = this._stack.length - 1; i >= 0; --i) {
127
+ const layer = this._stack[i];
128
+ if (layer?.type === "functionScope") return false;
129
+ if (layer?.type === "blockScope") {
130
+ if (layer.takenLocalIdentifiers.has(id)) return true;
131
+ }
132
+ }
133
+ return false;
134
+ }
119
135
  defineBlockVariable(id, snippet) {
120
136
  if (snippet.dataType === UnknownData) throw Error(`Tried to define variable '${id}' of unknown type`);
121
137
  for (let i = this._stack.length - 1; i >= 0; --i) {
@@ -232,17 +248,41 @@ var ResolutionCtxImpl = class {
232
248
  fixedBindings = [];
233
249
  enableExtensions;
234
250
  expectedType;
251
+ /**
252
+ * A counter used to generate unique identifiers for globally-scoped definitions in the 'random' strategy.
253
+ */
254
+ #lastUniqueId = 0;
235
255
  constructor(opts) {
236
256
  this.enableExtensions = opts.enableExtensions;
237
257
  this.gen = opts.shaderGenerator ?? wgslGenerator_default;
238
258
  this.#logGenerator = opts.root ? new LogGeneratorImpl(opts.root) : new LogGeneratorNullImpl();
239
259
  this.#namespaceInternal = opts.namespace[$internal];
240
260
  }
241
- getUniqueName(resource) {
242
- return getUniqueName(this.#namespaceInternal, resource);
261
+ isIdentifierTaken(name) {
262
+ return this.#namespaceInternal.takenGlobalIdentifiers.has(name) || this._itemStateStack.isIdentifierTakenLocally(name);
243
263
  }
244
- makeNameValid(name) {
245
- return this.#namespaceInternal.nameRegistry.makeValid(name);
264
+ makeUniqueIdentifier(primer = "item", scope) {
265
+ if (scope === "block" && (/* @__PURE__ */ validateIdentifier(primer)).success && !this.isIdentifierTaken(primer)) {
266
+ this.reserveIdentifier(primer, "block");
267
+ return primer;
268
+ }
269
+ const base = /* @__PURE__ */ sanitizePrimer(primer);
270
+ let index = 0;
271
+ const random = this.#namespaceInternal.strategy === "random";
272
+ let name = random ? `${base}_${this.#lastUniqueId++}` : base;
273
+ while (this.isIdentifierTaken(name)) name = random ? `${base}_${this.#lastUniqueId++}` : `${base}_${++index}`;
274
+ this.reserveIdentifier(name, scope);
275
+ return name;
276
+ }
277
+ reserveIdentifier(name, scope) {
278
+ if (scope === "block") {
279
+ const blockScope = this._itemStateStack.topBlockScope;
280
+ if (blockScope) {
281
+ blockScope.takenLocalIdentifiers.add(name);
282
+ return;
283
+ }
284
+ }
285
+ this.#namespaceInternal.takenGlobalIdentifiers.add(name);
246
286
  }
247
287
  get pre() {
248
288
  return this._indentController.pre;
@@ -281,11 +321,9 @@ var ResolutionCtxImpl = class {
281
321
  scope.reportedReturnTypes.add(dataType);
282
322
  }
283
323
  pushBlockScope() {
284
- this.#namespaceInternal.nameRegistry.pushBlockScope();
285
324
  this._itemStateStack.pushBlockScope();
286
325
  }
287
326
  popBlockScope() {
288
- this.#namespaceInternal.nameRegistry.popBlockScope();
289
327
  this._itemStateStack.pop("blockScope");
290
328
  }
291
329
  setBlockExternals(externals) {
@@ -301,28 +339,27 @@ var ResolutionCtxImpl = class {
301
339
  return this.#logGenerator.logResources;
302
340
  }
303
341
  fnToWgsl(options) {
304
- let fnScopePushed = false;
305
342
  try {
306
- this.#namespaceInternal.nameRegistry.pushFunctionScope();
343
+ const scope = this._itemStateStack.pushFunctionScope(options.functionType, {}, options.returnType, options.externalMap);
344
+ this._itemStateStack.pushBlockScope();
307
345
  const args = [];
308
- const argAccess = {};
309
346
  if (options.entryInput) {
310
347
  const { dataSchema, positionalArgs } = options.entryInput;
311
348
  const firstParam = options.params[0];
312
- const structArg = dataSchema ? createArgument(this.makeNameValid("_arg_0"), dataSchema) : void 0;
349
+ const structArg = dataSchema ? createArgument(this.makeUniqueIdentifier("_arg_0", "block"), dataSchema) : void 0;
313
350
  if (structArg) args.push(structArg);
314
351
  if (firstParam?.type === FuncParameterType.destructuredObject) for (const { name, alias } of firstParam.props) {
315
352
  const argInfo = positionalArgs.find((a) => a.schemaKey === name);
316
353
  if (argInfo) {
317
- const arg = createArgument(this.makeNameValid(alias), argInfo.type);
354
+ const arg = createArgument(this.makeUniqueIdentifier(alias, "block"), argInfo.type);
318
355
  args.push(arg);
319
- argAccess[alias] = arg.access;
320
- } else if (structArg) argAccess[alias] = createArgumentPropAccess(structArg.access, name);
356
+ scope.argAccess[alias] = arg.access;
357
+ } else if (structArg) scope.argAccess[alias] = createArgumentPropAccess(structArg.access, name);
321
358
  }
322
359
  else if (firstParam?.type === FuncParameterType.identifier) {
323
360
  const proxyEntries = [];
324
361
  for (const a of positionalArgs) {
325
- const arg = createArgument(this.makeNameValid(`_arg_${a.schemaKey}`), a.type);
362
+ const arg = createArgument(this.makeUniqueIdentifier(`_arg_${a.schemaKey}`, "block"), a.type);
326
363
  args.push(arg);
327
364
  proxyEntries.push({
328
365
  schemaKey: a.schemaKey,
@@ -330,31 +367,31 @@ var ResolutionCtxImpl = class {
330
367
  });
331
368
  }
332
369
  const router = new EntryInputRouter(structArg?.access, proxyEntries);
333
- argAccess[firstParam.name] = () => snip("N/A", router, "argument");
370
+ scope.argAccess[firstParam.name] = () => snip("N/A", router, "argument");
334
371
  } else for (const a of positionalArgs) {
335
- const argName = this.makeNameValid(`_arg_${a.schemaKey}`);
372
+ const argName = this.makeUniqueIdentifier(`_arg_${a.schemaKey}`, "block");
336
373
  const arg = createArgument(argName, a.type);
337
374
  args.push(arg);
338
- argAccess[argName] = arg.access;
375
+ scope.argAccess[argName] = arg.access;
339
376
  }
340
377
  } else for (const [i, argType] of options.argTypes.entries()) {
341
378
  const astParam = options.params[i];
342
379
  const origin = isPtr(argType) ? argType.addressSpace === "storage" ? argType.access === "read" ? "readonly" : "mutable" : argType.addressSpace : "argument";
343
380
  switch (astParam?.type) {
344
381
  case FuncParameterType.identifier: {
345
- const arg = createArgument(this.makeNameValid(astParam.name), argType, origin);
382
+ const arg = createArgument(this.makeUniqueIdentifier(astParam.name, "block"), argType, origin);
346
383
  args.push(arg);
347
- argAccess[astParam.name] = arg.access;
384
+ scope.argAccess[astParam.name] = arg.access;
348
385
  break;
349
386
  }
350
387
  case FuncParameterType.destructuredObject: {
351
- const objArg = createArgument(this.makeNameValid(`_arg_${i}`), argType, origin);
388
+ const objArg = createArgument(this.makeUniqueIdentifier(`_arg_${i}`, "block"), argType, origin);
352
389
  args.push(objArg);
353
- for (const { name, alias } of astParam.props) argAccess[alias] = createArgumentPropAccess(objArg.access, name);
390
+ for (const { name, alias } of astParam.props) scope.argAccess[alias] = createArgumentPropAccess(objArg.access, name);
354
391
  break;
355
392
  }
356
393
  case void 0: if (!(argType instanceof AutoStruct)) args.push({
357
- name: this.makeNameValid(`_arg_${i}`),
394
+ name: this.makeUniqueIdentifier(`_arg_${i}`, "block"),
358
395
  access: () => {
359
396
  throw new Error(`Unreachable: Accessing an argument that wasn't named in the function signature`);
360
397
  },
@@ -363,8 +400,6 @@ var ResolutionCtxImpl = class {
363
400
  });
364
401
  }
365
402
  }
366
- const scope = this._itemStateStack.pushFunctionScope(options.functionType, argAccess, options.returnType, options.externalMap);
367
- fnScopePushed = true;
368
403
  let returnType;
369
404
  const code = this.gen.functionDefinition({
370
405
  functionType: options.functionType,
@@ -395,8 +430,8 @@ var ResolutionCtxImpl = class {
395
430
  returnType
396
431
  };
397
432
  } finally {
398
- if (fnScopePushed) this._itemStateStack.pop("functionScope");
399
- this.#namespaceInternal.nameRegistry.popFunctionScope();
433
+ this._itemStateStack.pop("blockScope");
434
+ this._itemStateStack.pop("functionScope");
400
435
  }
401
436
  }
402
437
  addDeclaration(declaration) {
@@ -560,9 +595,8 @@ var ResolutionCtxImpl = class {
560
595
  if (schema.elementCount !== item.length) throw new WgslTypeError(`Cannot create value of type '${schema}' from an array of length: ${item.length}`);
561
596
  return snip(stitch`array<${this.resolve(schema.elementType)}, ${schema.elementCount}>(${item.map((element) => snip(element, schema.elementType, "runtime"))})`, schema, "runtime");
562
597
  }
563
- if (Array.isArray(item)) return snip(stitch`array(${item.map((element) => this.resolve(element))})`, UnknownData, "runtime");
564
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");
565
- throw new WgslTypeError(`Value ${item} (as json: ${safeStringify(item)}) is not resolvable${schema ? ` to type ${safeStringify(schema)}` : ""}`);
599
+ throw new WgslTypeError(`Value ${safeStringify(item)} is not resolvable${schema ? ` to type ${safeStringify(schema)}` : ""}`);
566
600
  }
567
601
  resolveSnippet(snippet) {
568
602
  return snip(this.resolve(snippet.value, snippet.dataType).value, snippet.dataType, snippet.origin);
@@ -2,6 +2,7 @@ import { isMatInstance, isVecInstance } from "../data/wgslTypes.js";
2
2
 
3
3
  //#region src/shared/stringify.ts
4
4
  function safeStringify(item) {
5
+ if (Array.isArray(item)) return `[${item.map(safeStringify).join(", ")}]`;
5
6
  const asString = String(item);
6
7
  if (asString !== "[object Object]") return asString;
7
8
  try {
@@ -0,0 +1,90 @@
1
+ import * as tinyest from "tinyest";
2
+
3
+ //#region src/shared/tseynit.ts
4
+ const { NodeTypeCatalog: NODE } = tinyest;
5
+ function stringifyNode(node) {
6
+ if (isExpression(node)) return stringifyExpression(node, "");
7
+ return stringifyStatement(node, "");
8
+ }
9
+ function stringifyStatement(node, ident) {
10
+ if (isExpression(node)) return `${ident}${stringifyExpression(node, ident)};`;
11
+ if (node[0] === NODE.block) return `{\n${node[1].map((n) => stringifyStatement(n, ident + " ")).join("\n")}\n${ident}}`;
12
+ if (node[0] === NODE.return) return `${ident}return${node[1] === void 0 ? "" : ` ${stringifyExpression(node[1], "")}`};`;
13
+ if (node[0] === NODE.if) {
14
+ const base = `${ident}if (${stringifyExpression(node[1], ident)}) ${stringifyStatement(node[2], ident)}`;
15
+ if (node[3] !== void 0) return `${base} else ${stringifyStatement(node[3], ident)}`;
16
+ return base;
17
+ }
18
+ if (node[0] === NODE.let) {
19
+ if (node[2] !== void 0) return `${ident}let ${node[1]} = ${stringifyExpression(node[2], ident)};`;
20
+ return `${ident}let ${node[1]};`;
21
+ }
22
+ if (node[0] === NODE.const) {
23
+ if (node[2] !== void 0) return `${ident}const ${node[1]} = ${stringifyExpression(node[2], ident)};`;
24
+ return `${ident}const ${node[1]};`;
25
+ }
26
+ if (node[0] === NODE.for) {
27
+ const init = node[1] ? stringifyStatement(node[1], "") : ";";
28
+ const cond = node[2] ? stringifyExpression(node[2], ident) : "";
29
+ const update = node[3] ? stringifyStatement(node[3], "") : "";
30
+ const body = stringifyStatement(node[4], ident);
31
+ return `${ident}for (${init} ${cond}; ${update.slice(0, -1)}) ${body}`;
32
+ }
33
+ if (node[0] === NODE.while) return `${ident}while (${stringifyExpression(node[1], ident)}) ${stringifyStatement(node[2], ident)}`;
34
+ if (node[0] === NODE.continue) return `${ident}continue;`;
35
+ if (node[0] === NODE.break) return `${ident}break;`;
36
+ if (node[0] === NODE.forOf) return `${ident}for (${node[1][0] === NODE.const ? "const" : "let"} ${node[1][1]} of ${stringifyExpression(node[2], ident)}) ${stringifyStatement(node[3], ident)}`;
37
+ assertExhaustive(node);
38
+ }
39
+ function stringifyExpression(node, ident) {
40
+ if (typeof node === "string") return node;
41
+ if (typeof node === "boolean") return `${node}`;
42
+ if (node[0] === NODE.numericLiteral) return node[1];
43
+ if (node[0] === NODE.stringLiteral) return JSON.stringify(node[1]);
44
+ if (node[0] === NODE.arrayExpr) return `[${node[1].map((n) => stringifyExpression(n, ident)).join(", ")}]`;
45
+ if (node[0] === NODE.binaryExpr) return `${wrapIfComplex(node[1], ident)} ${node[2]} ${wrapIfComplex(node[3], ident)}`;
46
+ if (node[0] === NODE.assignmentExpr) return `${stringifyExpression(node[1], ident)} ${node[2]} ${stringifyExpression(node[3], ident)}`;
47
+ if (node[0] === NODE.logicalExpr) return `${wrapIfComplex(node[1], ident)} ${node[2]} ${wrapIfComplex(node[3], ident)}`;
48
+ if (node[0] === NODE.unaryExpr) {
49
+ const sep = node[1].length > 1 ? " " : "";
50
+ return `${node[1]}${sep}${wrapIfComplex(node[2], ident)}`;
51
+ }
52
+ if (node[0] === NODE.call) return `${wrapIfComplex(node[1], ident)}(${node[2].map((n) => stringifyExpression(n, ident)).join(", ")})`;
53
+ if (node[0] === NODE.memberAccess) {
54
+ if (Array.isArray(node[1]) && node[1][0] === NODE.numericLiteral) return `(${stringifyExpression(node[1], ident)}).${node[2]}`;
55
+ return `${wrapIfComplex(node[1], ident)}.${node[2]}`;
56
+ }
57
+ if (node[0] === NODE.indexAccess) return `${wrapIfComplex(node[1], ident)}[${stringifyExpression(node[2], ident)}]`;
58
+ if (node[0] === NODE.preUpdate) return `${node[1]}${wrapIfComplex(node[2], ident)}`;
59
+ if (node[0] === NODE.postUpdate) return `${wrapIfComplex(node[2], ident)}${node[1]}`;
60
+ if (node[0] === NODE.objectExpr) return `{ ${Object.entries(node[1]).map(([key, val]) => `${key}: ${stringifyExpression(val, ident)}`).join(", ")} }`;
61
+ if (node[0] === NODE.conditionalExpr) return `${wrapIfComplex(node[1], ident)} ? ${wrapIfComplex(node[2], ident)} : ${wrapIfComplex(node[3], ident)}`;
62
+ assertExhaustive(node);
63
+ }
64
+ function assertExhaustive(value) {
65
+ throw new Error(`'${JSON.stringify(value)}' was not handled by the stringify function.`);
66
+ }
67
+ function isExpression(node) {
68
+ if (typeof node === "string" || typeof node === "boolean" || node[0] === NODE.numericLiteral || node[0] === NODE.stringLiteral || node[0] === NODE.arrayExpr || node[0] === NODE.binaryExpr || node[0] === NODE.assignmentExpr || node[0] === NODE.logicalExpr || node[0] === NODE.unaryExpr || node[0] === NODE.call || node[0] === NODE.memberAccess || node[0] === NODE.indexAccess || node[0] === NODE.preUpdate || node[0] === NODE.postUpdate || node[0] === NODE.objectExpr || node[0] === NODE.conditionalExpr) return true;
69
+ return false;
70
+ }
71
+ const SIMPLE_NODES = [
72
+ NODE.memberAccess,
73
+ NODE.indexAccess,
74
+ NODE.call,
75
+ NODE.arrayExpr,
76
+ NODE.stringLiteral,
77
+ NODE.numericLiteral
78
+ ];
79
+ /**
80
+ * Stringifies expression, and wraps it in parentheses if they cannot be trivially omitted
81
+ */
82
+ function wrapIfComplex(node, ident) {
83
+ const s = stringifyExpression(node, ident);
84
+ if (typeof node === "string" || typeof node === "boolean") return s;
85
+ if (SIMPLE_NODES.includes(node[0])) return s;
86
+ return `(${s})`;
87
+ }
88
+
89
+ //#endregion
90
+ export { stringifyNode };
package/std/copy.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { DualFn } from "../types.js";
2
+
3
+ //#region src/std/copy.d.ts
4
+ declare function cpuCopy<T>(e: T): T;
5
+ declare const copy: DualFn<typeof cpuCopy>;
6
+ //#endregion
7
+ export { copy };
package/std/copy.js ADDED
@@ -0,0 +1,27 @@
1
+ import { WORKAROUND_getSchema, isMatInstance, isVecInstance } from "../data/wgslTypes.js";
2
+ import { stitch } from "../core/resolve/stitch.js";
3
+ import { dualImpl } from "../core/function/dualImpl.js";
4
+
5
+ //#region src/std/copy.ts
6
+ function cpuCopy(e) {
7
+ if (isVecInstance(e) || isMatInstance(e)) return WORKAROUND_getSchema(e)(e);
8
+ if (Array.isArray(e)) return e.map(cpuCopy);
9
+ if (typeof e === "object" && e !== null) return Object.fromEntries(Object.entries(e).map(([key, value]) => [key, cpuCopy(value)]));
10
+ return e;
11
+ }
12
+ const copy = dualImpl({
13
+ name: "copy",
14
+ signature: (arg) => {
15
+ return {
16
+ argTypes: [arg],
17
+ returnType: arg
18
+ };
19
+ },
20
+ normalImpl: cpuCopy,
21
+ codegenImpl(_ctx, [a]) {
22
+ return stitch`${a}`;
23
+ }
24
+ });
25
+
26
+ //#endregion
27
+ export { copy };
package/std/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { identity2, identity3, identity4, rotationX4, rotationY4, rotationZ4, scaling4, translation4 } from "../data/matrix.js";
2
+ import { copy } from "./copy.js";
2
3
  import { discard } from "./discard.js";
3
4
  import { abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceil, clamp, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, distance, dot, dot4I8Packed, dot4U8Packed, exp, exp2, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, insertBits, inverseSqrt, ldexp, length, log, log2, max, min, mix, modf, normalize, pow, quantizeToF16, radians, reflect, refract, reverseBits, round, saturate, sign, sin, sinh, smoothstep, sqrt, step, tan, tanh, transpose, trunc } from "./numeric.js";
4
5
  import { add, bitShiftLeft, bitShiftRight, div, mod, mul, neg, sub } from "./operators.js";
@@ -16,7 +17,7 @@ import { range } from "./range.js";
16
17
 
17
18
  //#region src/std/index.d.ts
18
19
  declare namespace index_d_exports {
19
- export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, gt, identity2, identity3, identity4, insertBits, inverseSqrt, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
20
+ export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, copy, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, gt, identity2, identity3, identity4, insertBits, inverseSqrt, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
20
21
  }
21
22
  //#endregion
22
- export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, gt, identity2, identity3, identity4, index_d_exports, insertBits, inverseSqrt, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
23
+ export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, copy, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, gt, identity2, identity3, identity4, index_d_exports, insertBits, inverseSqrt, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
package/std/index.js CHANGED
@@ -7,6 +7,7 @@ import { range } from "./range.js";
7
7
  import { bitcastU32toF32, bitcastU32toI32 } from "./bitcast.js";
8
8
  import { pack2x16float, pack4x8unorm, unpack2x16float, unpack4x8unorm } from "./packing.js";
9
9
  import { all, allEq, and, any, eq, ge, gt, isCloseTo, le, lt, ne, not, or, select } from "./boolean.js";
10
+ import { copy } from "./copy.js";
10
11
  import { discard } from "./discard.js";
11
12
  import { rotateX4, rotateY4, rotateZ4, scale4, translate4 } from "./matrix.js";
12
13
  import { atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, storageBarrier, textureBarrier, workgroupBarrier } from "./atomic.js";
@@ -46,6 +47,7 @@ var std_exports = /* @__PURE__ */ __export({
46
47
  bitcastU32toI32: () => bitcastU32toI32,
47
48
  ceil: () => ceil,
48
49
  clamp: () => clamp,
50
+ copy: () => copy,
49
51
  cos: () => cos,
50
52
  cosh: () => cosh,
51
53
  countLeadingZeros: () => countLeadingZeros,
@@ -179,4 +181,4 @@ var std_exports = /* @__PURE__ */ __export({
179
181
  });
180
182
 
181
183
  //#endregion
182
- export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, gt, identity2, identity3, identity4, insertBits, inverseSqrt, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, std_exports, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
184
+ export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, copy, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, gt, identity2, identity3, identity4, insertBits, inverseSqrt, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, std_exports, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
package/tgpuUnstable.js CHANGED
@@ -2,9 +2,9 @@ import { __export } from "./_virtual/rolldown_runtime.js";
2
2
  import { comptime } from "./core/function/comptime.js";
3
3
  import { constant } from "./core/constant/tgpuConstant.js";
4
4
  import { fn } from "./core/function/tgpuFn.js";
5
- import { namespace } from "./core/resolve/namespace.js";
6
5
  import { slot } from "./core/slot/slot.js";
7
6
  import { privateVar, workgroupVar } from "./core/variable/tgpuVariable.js";
7
+ import { namespace } from "./core/resolve/namespace.js";
8
8
  import { computeFn } from "./core/function/tgpuComputeFn.js";
9
9
  import { vertexLayout } from "./core/vertexLayout/vertexLayout.js";
10
10
  import { lazy } from "./core/slot/lazy.js";
@@ -4,7 +4,7 @@ import { isEphemeralSnippet, snip } from "../data/snippet.js";
4
4
  import { isKnownAtComptime } from "../types.js";
5
5
  import { stitch } from "../core/resolve/stitch.js";
6
6
  import { derefSnippet } from "../data/ref.js";
7
- import { coerceToSnippet } from "./generationHelpers.js";
7
+ import { ArrayExpression, coerceToSnippet } from "./generationHelpers.js";
8
8
  import { vec2f, vec3f, vec4f } from "../data/vector.js";
9
9
  import { accessProp } from "./accessProp.js";
10
10
 
@@ -28,6 +28,7 @@ function accessIndex(target, indexArg) {
28
28
  else if (!isTargetEphemeral && !isElementNatEph) origin = target.origin;
29
29
  else if (isIndexConstant && target.origin === "constant") origin = "constant";
30
30
  else origin = "runtime";
31
+ if (target.value instanceof ArrayExpression && isKnownAtComptime(index)) return target.value.elements[index.value];
31
32
  return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, elementType, origin);
32
33
  }
33
34
  if (isVec(target.dataType)) return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, target.dataType.primitive, target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
@@ -103,7 +103,7 @@ function logDataFromGPU(resources) {
103
103
  const { argTypes, op } = logIdToMeta.get(id);
104
104
  const results = deserializeAndStringify(new Uint32Array(serializedData), argTypes);
105
105
  if (results.length === 0) results.push("");
106
- console[op](`%c${options.messagePrefix}%c ${results[0]}`, "background: #936ff5; color: white;", "color: inherit; background: none", ...results.slice(1));
106
+ op.bind(console)(`%c${options.messagePrefix}%c ${results[0]}`, "background: #936ff5; color: white;", "color: inherit; background: none", ...results.slice(1));
107
107
  });
108
108
  });
109
109
  indexBuffer.read().then((totalCalls) => {
@@ -12,7 +12,6 @@ import { shaderStageSlot } from "../../core/slot/internalSlots.js";
12
12
  import { arrayOf } from "../../data/array.js";
13
13
  import { atomic } from "../../data/atomic.js";
14
14
  import { createLoggingFunction } from "./serializers.js";
15
- import { supportedLogOps } from "./types.js";
16
15
 
17
16
  //#region src/tgsl/consoleLog/logGenerator.ts
18
17
  const defaultOptions = {
@@ -56,11 +55,7 @@ var LogGeneratorImpl = class {
56
55
  */
57
56
  generateLog(ctx, op, args) {
58
57
  if (shaderStageSlot.$ === "vertex") {
59
- console.warn(`'console.${op}' is not supported in vertex shaders.`);
60
- return fallbackSnippet;
61
- }
62
- if (!supportedLogOps.includes(op)) {
63
- console.warn(`Unsupported log method '${op}'.`);
58
+ console.warn(`'console' operations are not supported in vertex shaders.`);
64
59
  return fallbackSnippet;
65
60
  }
66
61
  const id = this.#firstUnusedId++;
@@ -1,10 +1,11 @@
1
1
  import "../../data/snippet.js";
2
2
  import { TgpuMutable } from "../../core/buffer/bufferShorthand.js";
3
3
  import "../generationHelpers.js";
4
+ import { supportedLogOps } from "../jsPolyfills.js";
4
5
  import { AnyWgslData, Atomic, U32, WgslArray, WgslStruct } from "../../data/wgslTypes.js";
5
6
 
6
7
  //#region src/tgsl/consoleLog/types.d.ts
7
-
8
+ type SupportedLogOp = ReturnType<typeof supportedLogOps>[number];
8
9
  /**
9
10
  * Options for configuring GPU log generation.
10
11
  */
@@ -32,7 +33,7 @@ type SerializedLogCallData = WgslStruct<{
32
33
  serializedData: WgslArray<U32>;
33
34
  }>;
34
35
  interface LogMeta {
35
- op: SupportedLogOps;
36
+ op: SupportedLogOp;
36
37
  argTypes: (string | AnyWgslData)[];
37
38
  }
38
39
  /**
@@ -49,7 +50,5 @@ interface LogResources {
49
50
  options: Required<LogGeneratorOptions>;
50
51
  logIdToMeta: Map<number, LogMeta>;
51
52
  }
52
- declare const supportedLogOps: readonly ["log", "debug", "info", "warn", "error", "clear"];
53
- type SupportedLogOps = (typeof supportedLogOps)[number];
54
53
  //#endregion
55
- export { LogGeneratorOptions, LogResources };
54
+ export { LogGeneratorOptions, LogResources, SupportedLogOp };
@@ -158,7 +158,10 @@ function getBestConversion(types, targetTypes) {
158
158
  if (implicitResult) return implicitResult;
159
159
  }
160
160
  function applyActionToSnippet(ctx, snippet, action, targetType) {
161
- if (action.action === "none") return snip(snippet.value, targetType, snippet.origin);
161
+ if (action.action === "none") {
162
+ if (targetType === snippet.dataType) return snippet;
163
+ return snip(snippet.value, targetType, snippet.origin);
164
+ }
162
165
  switch (action.action) {
163
166
  case "ref": return snip(new RefOperator(snippet, targetType), targetType, snippet.origin);
164
167
  case "deref": return derefSnippet(snippet);
@@ -1,5 +1,6 @@
1
1
  import { Snippet } from "../data/snippet.js";
2
2
  import { ShelllessRepository } from "./shellless.js";
3
+ import { SupportedLogOp } from "./consoleLog/types.js";
3
4
  import { FunctionScopeLayer, ResolutionCtx } from "../types.js";
4
5
  import { BaseData } from "../data/wgslTypes.js";
5
6
 
@@ -21,7 +22,7 @@ type GenerationCtx = ResolutionCtx & {
21
22
  dedent(): string;
22
23
  pushBlockScope(): void;
23
24
  popBlockScope(): void;
24
- generateLog(op: string, args: Snippet[]): Snippet;
25
+ generateLog(op: SupportedLogOp, args: Snippet[]): Snippet;
25
26
  getById(id: string): Snippet | null;
26
27
  defineVariable(id: string, snippet: Snippet): void;
27
28
  setBlockExternals(externals: Record<string, Snippet>): void;
@@ -0,0 +1,25 @@
1
+ import "../core/function/fnTypes.js";
2
+ import "../types.js";
3
+
4
+ //#region src/tgsl/jsPolyfills.d.ts
5
+ declare const supportedLogOps: () => readonly [{
6
+ (...data: any[]): void;
7
+ (message?: any, ...optionalParams: any[]): void;
8
+ }, {
9
+ (...data: any[]): void;
10
+ (message?: any, ...optionalParams: any[]): void;
11
+ }, {
12
+ (...data: any[]): void;
13
+ (message?: any, ...optionalParams: any[]): void;
14
+ }, {
15
+ (...data: any[]): void;
16
+ (message?: any, ...optionalParams: any[]): void;
17
+ }, {
18
+ (...data: any[]): void;
19
+ (message?: any, ...optionalParams: any[]): void;
20
+ }, {
21
+ (): void;
22
+ (): void;
23
+ }];
24
+ //#endregion
25
+ export { supportedLogOps };
@@ -0,0 +1,44 @@
1
+ import { f32 } from "../data/numeric.js";
2
+ import { abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceil, cos, cosh, countLeadingZeros, exp, floor, log, log2, max, min, pow, sign, sin, sinh, sqrt, tan, tanh, trunc } from "../std/numeric.js";
3
+
4
+ //#region src/tgsl/jsPolyfills.ts
5
+ const mathToStd = new Map([
6
+ [Math.abs, abs],
7
+ [Math.acos, acos],
8
+ [Math.acosh, acosh],
9
+ [Math.asin, asin],
10
+ [Math.asinh, asinh],
11
+ [Math.atan, atan],
12
+ [Math.atan2, atan2],
13
+ [Math.atanh, atanh],
14
+ [Math.ceil, ceil],
15
+ [Math.cos, cos],
16
+ [Math.cosh, cosh],
17
+ [Math.exp, exp],
18
+ [Math.floor, floor],
19
+ [Math.fround, f32],
20
+ [Math.clz32, countLeadingZeros],
21
+ [Math.trunc, trunc],
22
+ [Math.log, log],
23
+ [Math.log2, log2],
24
+ [Math.pow, pow],
25
+ [Math.sign, sign],
26
+ [Math.sin, sin],
27
+ [Math.sinh, sinh],
28
+ [Math.sqrt, sqrt],
29
+ [Math.tan, tan],
30
+ [Math.tanh, tanh],
31
+ [Math.max, max],
32
+ [Math.min, min]
33
+ ]);
34
+ const supportedLogOps = () => [
35
+ console.log,
36
+ console.debug,
37
+ console.info,
38
+ console.warn,
39
+ console.error,
40
+ console.clear
41
+ ];
42
+
43
+ //#endregion
44
+ export { mathToStd, supportedLogOps };
@@ -13,9 +13,14 @@ declare class WgslGenerator implements ShaderGenerator {
13
13
  initGenerator(ctx: GenerationCtx): void;
14
14
  protected get ctx(): GenerationCtx;
15
15
  _block([_, statements]: tinyest.Block, externalMap?: ExternalMap): string;
16
+ _blockStatement(block: tinyest.Block, externalMap?: ExternalMap): string;
16
17
  refVariable(id: string, dataType: StorableData): string;
17
- blockVariable(varType: 'var' | 'let' | 'const', id: string, dataType: BaseData | UnknownData, origin: Origin): Snippet;
18
- protected emitVarDecl(pre: string, keyword: 'var' | 'let' | 'const', name: string, _dataType: BaseData | UnknownData, rhsStr: string): string;
18
+ blockVariable(varType: 'var' | 'let' | 'const' | '<deferred>', id: string, dataType: BaseData | UnknownData, origin: Origin): Snippet;
19
+ /**
20
+ * Creates a variable declaration string.
21
+ * `keyword` may be a placeholder filled in later.
22
+ */
23
+ protected emitVarDecl(pre: string, keyword: 'var' | 'let' | 'const' | `#VAR_${number}#`, name: string, _dataType: BaseData | UnknownData, rhsStr: string): string;
19
24
  _identifier(id: string): Snippet;
20
25
  /**
21
26
  * A wrapper for `generateExpression` that updates `ctx.expectedType`
@@ -33,6 +38,19 @@ declare class WgslGenerator implements ShaderGenerator {
33
38
  typeInstantiation(schema: BaseData, args: readonly Snippet[]): ResolvedSnippet;
34
39
  _return(statement: tinyest.Return): string;
35
40
  _statement(statement: tinyest.Statement): string;
41
+ /**
42
+ * Attempts a member access lookup to mark a variable as modified.
43
+ * @example
44
+ * // given `let a; a = 1;`
45
+ * tryMarkModified('a') // `a` is marked in the function scope
46
+ *
47
+ * // given `const obj; obj.prop = 1;`
48
+ * tryMarkModified('obj.prop') // `obj` is marked in the function scope
49
+ *
50
+ * // given `this.buffer.$;`
51
+ * tryMarkModified('this.buffer.$') // `this` is not marked, since there is no placeholder for it
52
+ */
53
+ private tryMarkModified;
36
54
  }
37
55
  //#endregion
38
56
  export { WgslGenerator };