typegpu 0.11.6 → 0.11.8

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 (72) 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/declare/tgpuDeclare.js +2 -2
  8. package/core/function/comptime.js +8 -3
  9. package/core/function/createCallableSchema.js +7 -5
  10. package/core/function/dualImpl.js +2 -2
  11. package/core/function/fnCore.js +12 -13
  12. package/core/function/tgpuComputeFn.js +1 -1
  13. package/core/function/tgpuFn.js +3 -2
  14. package/core/pipeline/computePipeline.js +3 -3
  15. package/core/pipeline/renderPipeline.js +3 -3
  16. package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +1 -1
  17. package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +2 -2
  18. package/core/resolve/externals.d.ts +1 -1
  19. package/core/resolve/externals.js +24 -10
  20. package/core/resolve/tgpuResolve.d.ts +2 -2
  21. package/core/resolve/tgpuResolve.js +2 -2
  22. package/core/root/init.js +1 -1
  23. package/core/slot/accessor.js +1 -1
  24. package/core/texture/texture.js +8 -2
  25. package/core/variable/tgpuVariable.js +8 -6
  26. package/core/vertexLayout/vertexLayout.js +1 -1
  27. package/data/alignmentOf.js +1 -1
  28. package/data/attributes.d.ts +1 -1
  29. package/data/dataIO.js +1 -1
  30. package/data/dataTypes.d.ts +0 -1
  31. package/data/dataTypes.js +2 -12
  32. package/data/index.js +6 -23
  33. package/data/ref.js +20 -7
  34. package/data/snippet.d.ts +2 -1
  35. package/data/snippet.js +37 -10
  36. package/errors.d.ts +1 -4
  37. package/errors.js +1 -7
  38. package/index.d.ts +2 -2
  39. package/index.js +2 -2
  40. package/indexNamedExports.d.ts +1 -1
  41. package/package.js +1 -1
  42. package/package.json +5 -4
  43. package/resolutionCtx.js +9 -16
  44. package/shared/meta.d.ts +6 -15
  45. package/shared/meta.js +45 -38
  46. package/shared/normalizeMetadata.d.ts +32 -0
  47. package/shared/normalizeMetadata.js +41 -0
  48. package/std/atomic.js +1 -1
  49. package/std/boolean.js +36 -5
  50. package/std/environment.d.ts +48 -0
  51. package/std/environment.js +57 -0
  52. package/std/extensions.d.ts +2 -2
  53. package/std/extensions.js +2 -2
  54. package/std/index.d.ts +3 -2
  55. package/std/index.js +5 -2
  56. package/tgpuBindGroupLayout.js +1 -1
  57. package/tgsl/accessIndex.js +8 -14
  58. package/tgsl/accessProp.js +16 -29
  59. package/tgsl/consoleLog/serializers.js +1 -1
  60. package/tgsl/conversion.js +3 -3
  61. package/tgsl/forOfUtils.js +8 -5
  62. package/tgsl/generationHelpers.js +10 -11
  63. package/tgsl/infixDispatch.js +53 -0
  64. package/tgsl/shaderGenerator.d.ts +4 -1
  65. package/tgsl/shaderGenerator_members.d.ts +20 -2
  66. package/tgsl/shaderGenerator_members.js +5 -1
  67. package/tgsl/shellless.js +4 -4
  68. package/tgsl/wgslGenerator.d.ts +15 -11
  69. package/tgsl/wgslGenerator.js +173 -96
  70. package/types.d.ts +6 -4
  71. package/wgslExtensions.d.ts +3 -3
  72. package/wgslExtensions.js +3 -3
package/shared/meta.js CHANGED
@@ -1,63 +1,70 @@
1
1
  import { version } from "../package.js";
2
2
  import { DEV, TEST } from "./env.js";
3
3
  import { $getNameForward, isMarkedInternal } from "./symbols.js";
4
+ import { normalizeMetadata } from "./normalizeMetadata.js";
4
5
 
5
6
  //#region src/shared/meta.ts
6
- const globalWithMeta = globalThis;
7
- if (globalWithMeta.__TYPEGPU_VERSION__ !== void 0) console.warn(`Found duplicate TypeGPU version. First was ${globalWithMeta.__TYPEGPU_VERSION__}, this one is ${version}. This may cause unexpected behavior.`);
8
- globalWithMeta.__TYPEGPU_VERSION__ = version;
9
- globalWithMeta.__TYPEGPU_AUTONAME__ = (exp, label) => isNamable(exp) && isMarkedInternal(exp) && !getName(exp) ? exp.$name(label) : exp;
10
- /**
11
- * Performance measurements are only enabled in dev & test environments for now
12
- */
13
- const PERF = (DEV || TEST) && {
14
- get enabled() {
15
- return !!globalWithMeta.__TYPEGPU_MEASURE_PERF__;
16
- },
17
- record(name, data) {
18
- const records = globalWithMeta.__TYPEGPU_PERF_RECORDS__ ??= /* @__PURE__ */ new Map();
19
- let entries = records.get(name);
20
- if (!entries) {
21
- entries = [];
22
- records.set(name, entries);
23
- }
24
- entries.push(data);
25
- }
26
- } || void 0;
7
+ const globalExt = globalThis;
8
+ if (globalExt.__TYPEGPU_VERSION__ !== void 0) console.warn(`Found duplicate TypeGPU version. First was ${globalExt.__TYPEGPU_VERSION__}, this one is ${version}. This may cause unexpected behavior.`);
9
+ globalExt.__TYPEGPU_VERSION__ = version;
10
+ globalExt.__TYPEGPU_AUTONAME__ = (exp, label) => isNamable(exp) && isMarkedInternal(exp) && !getName(exp) ? exp.$name(label) : exp;
11
+ const nameMap = /* @__PURE__ */ new WeakMap();
12
+ function isNamable(value) {
13
+ return !!value?.$name;
14
+ }
27
15
  function isForwarded(value) {
28
16
  return !!value?.[$getNameForward];
29
17
  }
30
18
  function getName(definition) {
31
19
  if (isForwarded(definition)) return getName(definition[$getNameForward]);
32
- return getMetaData(definition)?.name;
20
+ return nameMap.get(definition) ?? globalExt.__TYPEGPU_META__?.get(definition)?.name;
33
21
  }
34
22
  function setName(definition, name) {
35
23
  if (isForwarded(definition)) {
36
24
  setName(definition[$getNameForward], name);
37
25
  return;
38
26
  }
39
- setMetaData(definition, { name });
27
+ nameMap.set(definition, name);
40
28
  }
41
- function isNamable(value) {
42
- return !!value?.$name;
29
+ const metadataMap = /* @__PURE__ */ new WeakMap();
30
+ /**
31
+ * Retrieves normalized (non-raw) function metadata.
32
+ * If `globalExt.__TYPEGPU_META__` contains raw metadata for the function,
33
+ * it is normalized, and then deleted to avoid unnecessary re-normalization.
34
+ */
35
+ function getFunctionMetadata(definition) {
36
+ const maybeRawMeta = globalExt.__TYPEGPU_META__?.get(definition);
37
+ if (maybeRawMeta) {
38
+ globalExt.__TYPEGPU_META__?.delete(definition);
39
+ const normalized = normalizeMetadata(maybeRawMeta);
40
+ metadataMap.set(definition, normalized);
41
+ if (maybeRawMeta.name && nameMap.get(definition) === void 0) nameMap.set(definition, maybeRawMeta.name);
42
+ }
43
+ return metadataMap.get(definition);
43
44
  }
44
45
  /**
45
46
  * AST's are given to functions with a 'use gpu' directive, which this function checks for.
46
47
  */
47
48
  function hasTinyestMetadata(value) {
48
- return !!getMetaData(value)?.ast;
49
- }
50
- function getMetaData(definition) {
51
- return globalWithMeta.__TYPEGPU_META__.get(definition);
52
- }
53
- function setMetaData(definition, metaData) {
54
- globalWithMeta.__TYPEGPU_META__ ??= /* @__PURE__ */ new WeakMap();
55
- const map = globalWithMeta.__TYPEGPU_META__;
56
- map.set(definition, {
57
- ...map.get(definition),
58
- ...metaData
59
- });
49
+ return typeof value === "function" && !!getFunctionMetadata(value);
60
50
  }
51
+ /**
52
+ * Performance measurements are only enabled in dev & test environments for now
53
+ */
54
+ const PERF = (DEV || TEST) && {
55
+ get enabled() {
56
+ return !!globalExt.__TYPEGPU_MEASURE_PERF__;
57
+ },
58
+ record(name, data) {
59
+ const records = globalExt.__TYPEGPU_PERF_RECORDS__ ??= /* @__PURE__ */ new Map();
60
+ let entries = records.get(name);
61
+ if (!entries) {
62
+ entries = [];
63
+ records.set(name, entries);
64
+ }
65
+ entries.push(data);
66
+ }
67
+ } || void 0;
61
68
 
62
69
  //#endregion
63
- export { PERF, getMetaData, getName, hasTinyestMetadata, isNamable, setName };
70
+ export { PERF, getFunctionMetadata, getName, hasTinyestMetadata, isNamable, setName };
@@ -0,0 +1,32 @@
1
+ import { Block, FuncParameter } from "tinyest";
2
+
3
+ //#region src/shared/normalizeMetadata.d.ts
4
+ interface RawMetadataV1 {
5
+ v: 1;
6
+ name: string;
7
+ ast: {
8
+ params: FuncParameter[];
9
+ body: Block;
10
+ externalNames: string[];
11
+ };
12
+ externals: Record<string, unknown> | (() => Record<string, unknown>);
13
+ }
14
+ interface ExternalsV2 {
15
+ [key: string]: ExternalsV2 | (() => unknown);
16
+ }
17
+ interface RawMetadataV2 {
18
+ v: 2;
19
+ name: string;
20
+ ast: {
21
+ params: FuncParameter[];
22
+ body: Block;
23
+ externalNames: string[];
24
+ };
25
+ externals: ExternalsV2;
26
+ }
27
+ /**
28
+ * Holds all function info collected by typegpu-unplugin
29
+ */
30
+ type RawMetadata = RawMetadataV1 | RawMetadataV2;
31
+ //#endregion
32
+ export { RawMetadata };
@@ -0,0 +1,41 @@
1
+ import { safeStringify } from "./stringify.js";
2
+
3
+ //#region src/shared/normalizeMetadata.ts
4
+ /**
5
+ * The values of ExternalsV2 are zero-argument functions for accessing the value.
6
+ * Since they would be recognized by the wgslGenerator as regular, non 'use gpu' functions,
7
+ * we turn them into getters.
8
+ *
9
+ * @example
10
+ * normalizeExternalsV2({ ext: { prop: () => ext.prop; }}); // { ext: { prop: [Getter] } }
11
+ */
12
+ function normalizeExternalsV2(externals) {
13
+ const result = {};
14
+ for (const [key, value] of Object.entries(externals)) if (typeof value === "function") Object.defineProperty(result, key, {
15
+ get: value,
16
+ enumerable: true
17
+ });
18
+ else result[key] = normalizeExternalsV2(value);
19
+ return result;
20
+ }
21
+ function normalizeMetadata(meta) {
22
+ if (meta.v === 1) {
23
+ const rawExternals = meta.externals;
24
+ const externals = typeof rawExternals === "function" ? rawExternals : () => rawExternals;
25
+ return {
26
+ ...meta,
27
+ externals
28
+ };
29
+ }
30
+ if (meta.v === 2) {
31
+ const externals = normalizeExternalsV2(meta?.externals);
32
+ return {
33
+ ...meta,
34
+ externals: () => externals
35
+ };
36
+ }
37
+ throw new Error(`Unrecognized TypeGPU metadata format: ${safeStringify(meta)}`);
38
+ }
39
+
40
+ //#endregion
41
+ export { normalizeMetadata };
package/std/atomic.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Void, isAtomic } from "../data/wgslTypes.js";
2
- import { stitch } from "../core/resolve/stitch.js";
3
2
  import { safeStringify } from "../shared/stringify.js";
3
+ import { stitch } from "../core/resolve/stitch.js";
4
4
  import { i32, u32 } from "../data/numeric.js";
5
5
  import { dualImpl } from "../core/function/dualImpl.js";
6
6
 
package/std/boolean.js CHANGED
@@ -2,8 +2,8 @@ import { isBool, isNumericSchema, isVec, isVecBool, isVecInstance } from "../dat
2
2
  import { isSnippetNumeric, snip } from "../data/snippet.js";
3
3
  import { stitch } from "../core/resolve/stitch.js";
4
4
  import { unify } from "../tgsl/conversion.js";
5
- import { bool, f32 } from "../data/numeric.js";
6
- import { vec2b, vec3b, vec4b } from "../data/vector.js";
5
+ import { bool, f16, f32, i32, u32 } from "../data/numeric.js";
6
+ import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../data/vector.js";
7
7
  import { dualImpl } from "../core/function/dualImpl.js";
8
8
  import { VectorOps } from "../data/vectorOps.js";
9
9
  import { sub } from "./operators.js";
@@ -271,6 +271,28 @@ function cpuSelect(f, t, cond) {
271
271
  if (typeof cond === "boolean") return cond ? t : f;
272
272
  return VectorOps.select[f.kind](f, t, cond);
273
273
  }
274
+ const validSelectBranchTypes = [
275
+ f32,
276
+ f16,
277
+ i32,
278
+ u32,
279
+ bool,
280
+ vec2f,
281
+ vec3f,
282
+ vec4f,
283
+ vec2h,
284
+ vec3h,
285
+ vec4h,
286
+ vec2i,
287
+ vec3i,
288
+ vec4i,
289
+ vec2u,
290
+ vec3u,
291
+ vec4u,
292
+ vec2b,
293
+ vec3b,
294
+ vec4b
295
+ ];
274
296
  /**
275
297
  * Returns `t` if `cond` is `true`, and `f` otherwise.
276
298
  * Component-wise if `cond` is a vector.
@@ -283,7 +305,7 @@ function cpuSelect(f, t, cond) {
283
305
  const select = dualImpl({
284
306
  name: "select",
285
307
  signature: (f, t, cond) => {
286
- const [uf, ut] = unify([f, t]) ?? [f, t];
308
+ const [uf, ut] = unify([f, t], validSelectBranchTypes) ?? [f, t];
287
309
  return {
288
310
  argTypes: [
289
311
  uf,
@@ -294,8 +316,17 @@ const select = dualImpl({
294
316
  };
295
317
  },
296
318
  normalImpl: cpuSelect,
297
- codegenImpl: (_ctx, [f, t, cond]) => stitch`select(${f}, ${t}, ${cond})`
319
+ codegenImpl: (ctx, [f, t, cond]) => {
320
+ const result = stitch`select(${f}, ${t}, ${cond})`;
321
+ if (!validSelectBranchTypes.includes(f.dataType) || !validSelectBranchTypes.includes(t.dataType)) throw new Error(`'${result}' is invalid, std.select requires both branches to be either scalars or vectors.`);
322
+ if (f.dataType !== t.dataType) {
323
+ const fStr = ctx.resolve(f.dataType);
324
+ const tStr = ctx.resolve(t.dataType);
325
+ throw new Error(`'${result}' is invalid, std.select requires both branches to be the same type, got [${fStr.value}, ${tStr.value}].`);
326
+ }
327
+ return result;
328
+ }
298
329
  });
299
330
 
300
331
  //#endregion
301
- export { all, allEq, and, any, eq, ge, gt, isCloseTo, le, lt, ne, not, or, select };
332
+ export { all, allEq, and, any, eq, ge, gt, isCloseTo, le, lt, ne, not, or, select, validSelectBranchTypes };
@@ -0,0 +1,48 @@
1
+ import { DualFn } from "../types.js";
2
+ import { TgpuComptime } from "../core/function/comptime.js";
3
+ import "../indexNamedExports.js";
4
+
5
+ //#region src/std/environment.d.ts
6
+
7
+ /**
8
+ * Returns `true` when the direct callee is being transpiled for GPU, otherwise `false`.
9
+ *
10
+ * @example
11
+ * const f = () => {
12
+ * 'use gpu';
13
+ * return isBeingTranspiled() ? 1 : 0;
14
+ * };
15
+ *
16
+ * f(); // returns 0, but resolved WGSL looks like this:
17
+ *
18
+ * fn f() -> i32 {
19
+ * return 1;
20
+ * }
21
+ *
22
+ * @note
23
+ * Inside `comptime`, `lazy` or `simulate`, it always returns `false`.
24
+ */
25
+ declare const isBeingTranspiled: DualFn<() => boolean>;
26
+ /**
27
+ * Returns `wgsl` if invoked during the resolution process; otherwise, returns `undefined`.
28
+ *
29
+ * @example
30
+ * const f = () => {
31
+ * 'use gpu';
32
+ * return getTargetShaderLanguage() === 'wgsl';
33
+ * };
34
+ *
35
+ * f(); // returns false, but resolved WGSL looks like this:
36
+ *
37
+ * fn f() -> bool {
38
+ * return true;
39
+ * }
40
+ *
41
+ * @note
42
+ * Inside `lazy`, it always returns `wgsl`.
43
+ * Inside `simulate`, it always returns `undefined`.
44
+ * Inside `comptime`, it returns `wgsl` if called during the resolution process; otherwise, `undefined`.
45
+ */
46
+ declare const getTargetShaderLanguage: TgpuComptime<() => string | undefined>;
47
+ //#endregion
48
+ export { getTargetShaderLanguage, isBeingTranspiled };
@@ -0,0 +1,57 @@
1
+ import { $gpuCallable } from "../shared/symbols.js";
2
+ import { getExecMode, getResolutionCtx } from "../execMode.js";
3
+ import { coerceToSnippet } from "../tgsl/generationHelpers.js";
4
+ import { comptime } from "../core/function/comptime.js";
5
+
6
+ //#region src/std/environment.ts
7
+ const impl = (() => false);
8
+ impl.toString = () => "isBeingTranspiled";
9
+ impl[$gpuCallable] = { call(_ctx, _args) {
10
+ return coerceToSnippet(true);
11
+ } };
12
+ /**
13
+ * Returns `true` when the direct callee is being transpiled for GPU, otherwise `false`.
14
+ *
15
+ * @example
16
+ * const f = () => {
17
+ * 'use gpu';
18
+ * return isBeingTranspiled() ? 1 : 0;
19
+ * };
20
+ *
21
+ * f(); // returns 0, but resolved WGSL looks like this:
22
+ *
23
+ * fn f() -> i32 {
24
+ * return 1;
25
+ * }
26
+ *
27
+ * @note
28
+ * Inside `comptime`, `lazy` or `simulate`, it always returns `false`.
29
+ */
30
+ const isBeingTranspiled = impl;
31
+ /**
32
+ * Returns `wgsl` if invoked during the resolution process; otherwise, returns `undefined`.
33
+ *
34
+ * @example
35
+ * const f = () => {
36
+ * 'use gpu';
37
+ * return getTargetShaderLanguage() === 'wgsl';
38
+ * };
39
+ *
40
+ * f(); // returns false, but resolved WGSL looks like this:
41
+ *
42
+ * fn f() -> bool {
43
+ * return true;
44
+ * }
45
+ *
46
+ * @note
47
+ * Inside `lazy`, it always returns `wgsl`.
48
+ * Inside `simulate`, it always returns `undefined`.
49
+ * Inside `comptime`, it returns `wgsl` if called during the resolution process; otherwise, `undefined`.
50
+ */
51
+ const getTargetShaderLanguage = comptime((() => {
52
+ if (!getResolutionCtx()) return;
53
+ return getExecMode().type !== "simulate" ? "wgsl" : void 0;
54
+ }));
55
+
56
+ //#endregion
57
+ export { getTargetShaderLanguage, isBeingTranspiled };
@@ -1,8 +1,8 @@
1
- import { WgslExtension } from "../wgslExtensions.js";
1
+ import { WgslEnableExtension } from "../wgslExtensions.js";
2
2
  import { TgpuComptime } from "../core/function/comptime.js";
3
3
  import "../indexNamedExports.js";
4
4
 
5
5
  //#region src/std/extensions.d.ts
6
- declare const extensionEnabled: TgpuComptime<(extensionName: WgslExtension) => boolean>;
6
+ declare const extensionEnabled: TgpuComptime<(extensionName: WgslEnableExtension) => boolean>;
7
7
  //#endregion
8
8
  export { extensionEnabled };
package/std/extensions.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { getResolutionCtx } from "../execMode.js";
2
2
  import { comptime } from "../core/function/comptime.js";
3
- import { wgslExtensions } from "../wgslExtensions.js";
3
+ import { wgslEnableExtensions } from "../wgslExtensions.js";
4
4
 
5
5
  //#region src/std/extensions.ts
6
6
  const extensionEnabled = comptime((extensionName) => {
7
7
  const resolutionCtx = getResolutionCtx();
8
8
  if (!resolutionCtx) throw new Error("Functions using `extensionEnabled` cannot be called directly. Either generate WGSL from them, or use tgpu['~unstable'].simulate(...)");
9
- if (typeof extensionName !== "string" || !wgslExtensions.includes(extensionName)) throw new Error(`extensionEnabled has to be called with a string literal representing a valid WGSL extension name. Got: '${extensionName}'`);
9
+ if (typeof extensionName !== "string" || !wgslEnableExtensions.includes(extensionName)) throw new Error(`extensionEnabled has to be called with a string literal representing a valid WGSL extension name. Got: '${extensionName}'`);
10
10
  return (resolutionCtx.enableExtensions ?? []).includes(extensionName);
11
11
  });
12
12
 
package/std/index.d.ts CHANGED
@@ -14,10 +14,11 @@ import { subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, sub
14
14
  import { extensionEnabled } from "./extensions.js";
15
15
  import { bitcastU32toF32, bitcastU32toI32 } from "./bitcast.js";
16
16
  import { range } from "./range.js";
17
+ import { getTargetShaderLanguage, isBeingTranspiled } from "./environment.js";
17
18
 
18
19
  //#region src/std/index.d.ts
19
20
  declare namespace index_d_exports {
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 };
21
+ 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, getTargetShaderLanguage, gt, identity2, identity3, identity4, insertBits, inverseSqrt, isBeingTranspiled, 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 };
21
22
  }
22
23
  //#endregion
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 };
24
+ 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, getTargetShaderLanguage, gt, identity2, identity3, identity4, index_d_exports, insertBits, inverseSqrt, isBeingTranspiled, 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
@@ -4,9 +4,9 @@ import { add, bitShiftLeft, bitShiftRight, div, mod, mul, neg, sub } from "./ope
4
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";
5
5
  import { arrayLength } from "./array.js";
6
6
  import { range } from "./range.js";
7
+ import { all, allEq, and, any, eq, ge, gt, isCloseTo, le, lt, ne, not, or, select } from "./boolean.js";
7
8
  import { bitcastU32toF32, bitcastU32toI32 } from "./bitcast.js";
8
9
  import { pack2x16float, pack4x8unorm, unpack2x16float, unpack4x8unorm } from "./packing.js";
9
- import { all, allEq, and, any, eq, ge, gt, isCloseTo, le, lt, ne, not, or, select } from "./boolean.js";
10
10
  import { copy } from "./copy.js";
11
11
  import { discard } from "./discard.js";
12
12
  import { rotateX4, rotateY4, rotateZ4, scale4, translate4 } from "./matrix.js";
@@ -15,6 +15,7 @@ import { dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, fwidth, fwidthC
15
15
  import { textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore } from "./texture.js";
16
16
  import { subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor } from "./subgroup.js";
17
17
  import { extensionEnabled } from "./extensions.js";
18
+ import { getTargetShaderLanguage, isBeingTranspiled } from "./environment.js";
18
19
 
19
20
  //#region src/std/index.ts
20
21
  var std_exports = /* @__PURE__ */ __export({
@@ -84,12 +85,14 @@ var std_exports = /* @__PURE__ */ __export({
84
85
  fwidthCoarse: () => fwidthCoarse,
85
86
  fwidthFine: () => fwidthFine,
86
87
  ge: () => ge,
88
+ getTargetShaderLanguage: () => getTargetShaderLanguage,
87
89
  gt: () => gt,
88
90
  identity2: () => identity2,
89
91
  identity3: () => identity3,
90
92
  identity4: () => identity4,
91
93
  insertBits: () => insertBits,
92
94
  inverseSqrt: () => inverseSqrt,
95
+ isBeingTranspiled: () => isBeingTranspiled,
93
96
  isCloseTo: () => isCloseTo,
94
97
  ldexp: () => ldexp,
95
98
  le: () => le,
@@ -181,4 +184,4 @@ var std_exports = /* @__PURE__ */ __export({
181
184
  });
182
185
 
183
186
  //#endregion
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 };
187
+ 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, getTargetShaderLanguage, gt, identity2, identity3, identity4, insertBits, inverseSqrt, isBeingTranspiled, 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 };
@@ -1,7 +1,7 @@
1
1
  import { $gpuValueOf, $internal } from "./shared/symbols.js";
2
+ import { safeStringify } from "./shared/stringify.js";
2
3
  import { getName, setName } from "./shared/meta.js";
3
4
  import { NotUniformError } from "./errors.js";
4
- import { safeStringify } from "./shared/stringify.js";
5
5
  import { f32, i32, u32 } from "./data/numeric.js";
6
6
  import { NotStorageError, isUsableAsStorage } from "./extension.js";
7
7
  import { TgpuLaidOutBufferImpl, isUsableAsUniform } from "./core/buffer/bufferUsage.js";
@@ -1,6 +1,6 @@
1
- import { isNaturallyEphemeral, isPtr, isVec, isWgslArray, isWgslStruct } from "../data/wgslTypes.js";
1
+ import { isPtr, isVec, isWgslArray, isWgslStruct } from "../data/wgslTypes.js";
2
2
  import { MatrixColumnsAccess, isDisarray } from "../data/dataTypes.js";
3
- import { isEphemeralSnippet, snip } from "../data/snippet.js";
3
+ import { 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";
@@ -18,24 +18,18 @@ function accessIndex(target, indexArg) {
18
18
  const index = typeof indexArg === "number" ? coerceToSnippet(indexArg) : indexArg;
19
19
  if (isWgslArray(target.dataType) || isDisarray(target.dataType)) {
20
20
  const elementType = target.dataType.elementType;
21
- const isElementNatEph = isNaturallyEphemeral(elementType);
22
- const isTargetEphemeral = isEphemeralSnippet(target);
23
- const isIndexConstant = index.origin === "constant";
24
21
  let origin;
25
- if (target.origin === "constant-tgpu-const-ref") if (isIndexConstant) origin = isElementNatEph ? "constant" : "constant-tgpu-const-ref";
26
- else origin = isElementNatEph ? "runtime" : "runtime-tgpu-const-ref";
27
- else if (target.origin === "runtime-tgpu-const-ref") origin = isElementNatEph ? "runtime" : "runtime-tgpu-const-ref";
28
- else if (!isTargetEphemeral && !isElementNatEph) origin = target.origin;
29
- else if (isIndexConstant && target.origin === "constant") origin = "constant";
30
- else origin = "runtime";
22
+ if (target.origin === "constant-immutable-def") origin = index.origin === "constant" || index.origin === "constant-immutable-def" ? "constant-immutable-def" : "runtime-immutable-def";
23
+ else if (target.origin === "constant") origin = index.origin === "constant" || index.origin === "constant-immutable-def" ? "constant" : "runtime";
24
+ else origin = target.origin;
31
25
  if (target.value instanceof ArrayExpression && isKnownAtComptime(index)) return target.value.elements[index.value];
32
- return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, elementType, origin);
26
+ return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, elementType, origin, target.possibleSideEffects || index.possibleSideEffects);
33
27
  }
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");
28
+ if (isVec(target.dataType)) return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, target.dataType.primitive, target.origin, target.possibleSideEffects || index.possibleSideEffects);
35
29
  if (isPtr(target.dataType)) return accessIndex(derefSnippet(target), index);
36
30
  if (target.value instanceof MatrixColumnsAccess) {
37
31
  const propType = indexableTypeToResult[target.value.matrix.dataType.type];
38
- return snip(stitch`${target.value.matrix}[${index}]`, propType, target.origin);
32
+ return snip(stitch`${target.value.matrix}[${index}]`, propType, target.origin, target.possibleSideEffects || index.possibleSideEffects);
39
33
  }
40
34
  if (target.dataType.type in indexableTypeToResult) throw new Error("The only way of accessing matrix elements in TypeGPU functions is through the 'columns' property.");
41
35
  if (isKnownAtComptime(target) && isKnownAtComptime(index)) return coerceToSnippet(target.value[index.value]);
@@ -1,16 +1,15 @@
1
- import { $gpuCallable } from "../shared/symbols.js";
2
- import { isMat, isNaturallyEphemeral, isPtr, isVec, isWgslArray, isWgslStruct } from "../data/wgslTypes.js";
3
- import { InfixDispatch, MatrixColumnsAccess, UnknownData, isUnstruct, undecorate } from "../data/dataTypes.js";
4
- import { isEphemeralSnippet, isSnippet, snip } from "../data/snippet.js";
1
+ import { isMat, isPtr, isVec, isWgslArray, isWgslStruct } from "../data/wgslTypes.js";
2
+ import { MatrixColumnsAccess, UnknownData, isUnstruct, undecorate } from "../data/dataTypes.js";
3
+ import { isSnippet, snip } from "../data/snippet.js";
5
4
  import { isKnownAtComptime } from "../types.js";
6
5
  import { stitch } from "../core/resolve/stitch.js";
7
6
  import { derefSnippet } from "../data/ref.js";
8
- import { abstractInt, bool, f16, f32, i32, u32 } from "../data/numeric.js";
9
- import { coerceToSnippet } from "./generationHelpers.js";
7
+ import { bool, f16, f32, i32, u32 } from "../data/numeric.js";
8
+ import { coerceToSnippet, numericLiteralToSnippet } from "./generationHelpers.js";
10
9
  import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../data/vector.js";
11
10
  import { AutoStruct } from "../data/autoStruct.js";
12
11
  import { EntryInputRouter } from "../core/function/entryInputRouter.js";
13
- import { add, bitShiftLeft, bitShiftRight, div, mod, mul, sub } from "../std/operators.js";
12
+ import { InfixDispatch, infixOperators } from "./infixDispatch.js";
14
13
 
15
14
  //#region src/tgsl/accessProp.ts
16
15
  const infixKinds = [
@@ -30,15 +29,6 @@ const infixKinds = [
30
29
  "mat3x3f",
31
30
  "mat4x4f"
32
31
  ];
33
- const infixOperators = {
34
- add,
35
- sub,
36
- mul,
37
- div,
38
- mod,
39
- bitShiftLeft,
40
- bitShiftRight
41
- };
42
32
  const swizzleLenToType = {
43
33
  f: {
44
34
  1: f32,
@@ -74,23 +64,23 @@ const swizzleLenToType = {
74
64
  function accessProp(target, propName) {
75
65
  if (infixKinds.includes(target.dataType.type) && propName in infixOperators) {
76
66
  const operator = infixOperators[propName];
77
- return snip(new InfixDispatch(propName, target, operator[$gpuCallable].call.bind(operator)), UnknownData, target.origin);
67
+ return snip(new InfixDispatch(target, operator), UnknownData, target.origin, target.possibleSideEffects);
78
68
  }
79
69
  if (isWgslArray(target.dataType) && propName === "length") {
80
- if (target.dataType.elementCount === 0) return snip(stitch`arrayLength(&${target})`, u32, "runtime");
81
- return snip(target.dataType.elementCount, abstractInt, "constant");
70
+ if (target.dataType.elementCount === 0) return snip(stitch`arrayLength(&${target})`, u32, "runtime", target.possibleSideEffects);
71
+ return numericLiteralToSnippet(target.dataType.elementCount);
82
72
  }
83
- if (isMat(target.dataType) && propName === "columns") return snip(new MatrixColumnsAccess(target), UnknownData, target.origin);
73
+ if (isMat(target.dataType) && propName === "columns") return snip(new MatrixColumnsAccess(target), UnknownData, target.origin, target.possibleSideEffects);
84
74
  if (isWgslStruct(target.dataType) || isUnstruct(target.dataType)) {
85
75
  let propType = target.dataType.propTypes[propName];
86
76
  if (!propType) return;
87
77
  propType = undecorate(propType);
88
- return snip(stitch`${target}.${propName}`, propType, target.origin === "argument" ? "argument" : !isEphemeralSnippet(target) && !isNaturallyEphemeral(propType) ? target.origin : target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
78
+ return snip(stitch`${target}.${propName}`, propType, target.origin, target.possibleSideEffects);
89
79
  }
90
80
  if (target.dataType instanceof AutoStruct) {
91
81
  const result = target.dataType.accessProp(propName);
92
82
  if (!result) return;
93
- return snip(stitch`${target}.${result.prop}`, result.type, "argument");
83
+ return snip(stitch`${target}.${result.prop}`, result.type, "argument", target.possibleSideEffects);
94
84
  }
95
85
  if (target.dataType instanceof EntryInputRouter) {
96
86
  const result = target.dataType.accessProp(propName);
@@ -104,19 +94,16 @@ function accessProp(target, propName) {
104
94
  return accessProp(derefed, propName);
105
95
  }
106
96
  if (isVec(target.dataType)) {
107
- if (propName === "kind") return snip(target.dataType.type, UnknownData, "constant");
97
+ if (propName === "kind") return snip(target.dataType.type, UnknownData, "constant", false);
108
98
  }
109
99
  const propLength = propName.length;
110
- if (isVec(target.dataType) && propLength >= 1 && propLength <= 4) {
111
- const isXYZW = /^[xyzw]+$/.test(propName);
112
- const isRGBA = /^[rgba]+$/.test(propName);
113
- if (!isXYZW && !isRGBA) return;
100
+ if (isVec(target.dataType) && propLength >= 1 && propLength <= 4 && /^[xyzw]+$|^[rgba]+$/.test(propName)) {
114
101
  const swizzleType = swizzleLenToType[target.dataType.type.includes("bool") ? "b" : target.dataType.type[4]][propLength];
115
102
  if (!swizzleType) return;
116
- return snip(isKnownAtComptime(target) ? target.value[propName] : stitch`${target}.${propName}`, swizzleType, target.origin === "argument" && propLength === 1 ? "argument" : target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
103
+ return snip(isKnownAtComptime(target) ? target.value[propName] : stitch`${target}.${propName}`, swizzleType, propLength === 1 ? target.origin : target.origin === "constant" || target.origin === "constant-immutable-def" ? "constant" : "runtime", target.possibleSideEffects);
117
104
  }
118
105
  if (isKnownAtComptime(target) || target.dataType === UnknownData) return coerceToSnippet(target.value[propName]);
119
106
  }
120
107
 
121
108
  //#endregion
122
- export { accessProp, infixOperators };
109
+ export { accessProp };
@@ -1,5 +1,5 @@
1
- import { getName } from "../../shared/meta.js";
2
1
  import { isWgslArray, isWgslStruct } from "../../data/wgslTypes.js";
2
+ import { getName } from "../../shared/meta.js";
3
3
  import { bool, f16, f32, i32, u32 } from "../../data/numeric.js";
4
4
  import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../../data/vector.js";
5
5
  import { sizeOf } from "../../data/sizeOf.js";
@@ -1,12 +1,12 @@
1
1
  import { DEV, TEST } from "../shared/env.js";
2
2
  import { isMat, isPtr, isVec } from "../data/wgslTypes.js";
3
+ import { safeStringify } from "../shared/stringify.js";
3
4
  import { UnknownData, undecorate } from "../data/dataTypes.js";
4
- import { snip } from "../data/snippet.js";
5
+ import { snip, withDataType } from "../data/snippet.js";
5
6
  import { WgslTypeError, invariant } from "../errors.js";
6
7
  import { stitch } from "../core/resolve/stitch.js";
7
8
  import { RefOperator, derefSnippet } from "../data/ref.js";
8
9
  import { schemaCallWrapperGPU } from "../data/schemaCallWrapper.js";
9
- import { safeStringify } from "../shared/stringify.js";
10
10
  import { assertExhaustive } from "../shared/utilityTypes.js";
11
11
 
12
12
  //#region src/tgsl/conversion.ts
@@ -160,7 +160,7 @@ function getBestConversion(types, targetTypes) {
160
160
  function applyActionToSnippet(ctx, snippet, action, targetType) {
161
161
  if (action.action === "none") {
162
162
  if (targetType === snippet.dataType) return snippet;
163
- return snip(snippet.value, targetType, snippet.origin);
163
+ return withDataType(targetType, snippet);
164
164
  }
165
165
  switch (action.action) {
166
166
  case "ref": return snip(new RefOperator(snippet, targetType), targetType, snippet.origin);