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.
- package/README.md +4 -2
- package/core/buffer/buffer.js +17 -53
- package/core/buffer/bufferUsage.js +2 -2
- package/core/constant/tgpuConstant.js +1 -1
- package/core/function/fnCore.js +12 -6
- package/core/function/tgpuFragmentFn.d.ts +1 -1
- package/core/pipeline/computePipeline.d.ts +1 -1
- package/core/pipeline/computePipeline.js +1 -1
- package/core/pipeline/renderPipeline.js +1 -1
- package/core/resolve/namespace.d.ts +2 -11
- package/core/resolve/namespace.js +7 -24
- package/core/resolve/resolveData.js +3 -2
- package/core/resolve/tgpuResolve.js +1 -1
- package/core/root/init.d.ts +1 -0
- package/core/root/init.js +6 -0
- package/core/root/rootTypes.d.ts +21 -15
- package/core/sampler/sampler.js +2 -2
- package/core/simulate/tgpuSimulate.js +1 -1
- package/core/slot/accessor.js +1 -1
- package/core/texture/externalTexture.js +1 -1
- package/core/texture/texture.js +2 -2
- package/core/variable/tgpuVariable.js +1 -1
- package/data/autoStruct.js +3 -2
- package/data/dataIO.d.ts +11 -0
- package/data/dataIO.js +45 -1
- package/data/dataTypes.d.ts +1 -1
- package/data/dataTypes.js +2 -11
- package/data/partialIO.d.ts +8 -0
- package/data/partialIO.js +6 -1
- package/data/struct.js +3 -2
- package/data/wgslTypes.d.ts +16 -16
- package/index.d.ts +3 -1
- package/index.js +3 -1
- package/indexNamedExports.d.ts +2 -0
- package/{nameRegistry.js → nameUtils.js} +46 -90
- package/package.js +1 -1
- package/package.json +1 -1
- package/resolutionCtx.js +64 -30
- package/shared/stringify.js +1 -0
- package/shared/tseynit.js +90 -0
- package/std/copy.d.ts +7 -0
- package/std/copy.js +27 -0
- package/std/index.d.ts +3 -2
- package/std/index.js +3 -1
- package/tgpuUnstable.js +1 -1
- package/tgsl/accessIndex.js +2 -1
- package/tgsl/consoleLog/deserializers.js +1 -1
- package/tgsl/consoleLog/logGenerator.js +1 -6
- package/tgsl/consoleLog/types.d.ts +4 -5
- package/tgsl/conversion.js +4 -1
- package/tgsl/generationHelpers.d.ts +2 -1
- package/tgsl/jsPolyfills.d.ts +25 -0
- package/tgsl/jsPolyfills.js +44 -0
- package/tgsl/wgslGenerator.d.ts +20 -2
- package/tgsl/wgslGenerator.js +114 -57
- package/types.d.ts +29 -2
- package/nameRegistry.d.ts +0 -30
- package/tgsl/consoleLog/types.js +0 -12
- 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
|
-
|
|
242
|
-
return
|
|
261
|
+
isIdentifierTaken(name) {
|
|
262
|
+
return this.#namespaceInternal.takenGlobalIdentifiers.has(name) || this._itemStateStack.isIdentifierTakenLocally(name);
|
|
243
263
|
}
|
|
244
|
-
|
|
245
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
399
|
-
this
|
|
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 ${
|
|
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);
|
package/shared/stringify.js
CHANGED
|
@@ -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
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";
|
package/tgsl/accessIndex.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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:
|
|
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 };
|
package/tgsl/conversion.js
CHANGED
|
@@ -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")
|
|
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:
|
|
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 };
|
package/tgsl/wgslGenerator.d.ts
CHANGED
|
@@ -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
|
-
|
|
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 };
|