typegpu 0.12.4 → 0.12.6

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 (78) hide show
  1. package/bin.mjs +39 -67
  2. package/common/index.d.ts +1 -0
  3. package/common/index.js +1 -0
  4. package/common/writeChannels.d.ts +31 -0
  5. package/common/writeChannels.js +32 -0
  6. package/core/commandEncoder/computePass.d.ts +13 -0
  7. package/core/commandEncoder/computePass.js +5 -2
  8. package/core/commandEncoder/renderPass.d.ts +18 -4
  9. package/core/commandEncoder/renderPass.js +6 -2
  10. package/core/declare/tgpuDeclare.d.ts +11 -0
  11. package/core/declare/tgpuDeclare.js +1 -1
  12. package/core/immediate/immediateVar.d.ts +52 -0
  13. package/core/immediate/immediateVar.js +149 -0
  14. package/core/pipeline/computePipeline.d.ts +23 -0
  15. package/core/pipeline/computePipeline.js +26 -9
  16. package/core/pipeline/drawState.d.ts +8 -4
  17. package/core/pipeline/drawState.js +41 -51
  18. package/core/pipeline/priors.js +1 -0
  19. package/core/pipeline/renderPipeline.d.ts +24 -1
  20. package/core/pipeline/renderPipeline.js +18 -1
  21. package/core/root/init.js +3 -0
  22. package/core/root/rootTypes.d.ts +11 -0
  23. package/core/slot/slotTypes.d.ts +2 -1
  24. package/core/texture/texture.d.ts +20 -14
  25. package/core/texture/texture.js +70 -65
  26. package/core/texture/textureUtils.d.ts +3 -6
  27. package/core/texture/textureUtils.js +142 -165
  28. package/core/texture/textureWrite.d.ts +61 -0
  29. package/core/texture/textureWrite.js +59 -0
  30. package/data/dataIO.d.ts +2 -2
  31. package/data/generalizeFn.d.ts +17 -1
  32. package/data/generalizeFn.js +39 -2
  33. package/data/snippet.d.ts +5 -1
  34. package/data/snippet.js +1 -0
  35. package/data/wgslTypes.d.ts +1 -1
  36. package/errors.d.ts +7 -0
  37. package/errors.js +15 -0
  38. package/indexNamedExports.d.ts +5 -2
  39. package/indexNamedExports.js +2 -1
  40. package/internal.d.ts +1 -1
  41. package/internal.js +1 -1
  42. package/package.json +2 -2
  43. package/resolutionCtx.d.ts +5 -0
  44. package/resolutionCtx.js +11 -0
  45. package/serial/restore.d.ts +3 -1
  46. package/serial/restore.js +2 -0
  47. package/shared/meta.js +1 -1
  48. package/shared/symbols.js +1 -1
  49. package/shared/tseynit.d.ts +1 -0
  50. package/shared/tseynit.js +39 -7
  51. package/shared/utilityTypes.d.ts +1 -1
  52. package/std/atomic.d.ts +13 -0
  53. package/std/atomic.js +63 -29
  54. package/std/bitcast.js +4 -0
  55. package/std/boolean.d.ts +1 -1
  56. package/std/boolean.js +35 -21
  57. package/std/derivative.js +17 -12
  58. package/std/index.d.ts +4 -4
  59. package/std/index.js +5 -5
  60. package/std/numeric.d.ts +5 -1
  61. package/std/numeric.js +75 -8
  62. package/std/operators.d.ts +2 -2
  63. package/std/operators.js +29 -17
  64. package/std/packing.d.ts +61 -1
  65. package/std/packing.js +214 -25
  66. package/std/subgroup.d.ts +4 -0
  67. package/std/subgroup.js +34 -0
  68. package/std/texture.d.ts +13 -0
  69. package/std/texture.js +48 -0
  70. package/tgpuUnstable.d.ts +1 -0
  71. package/tgpuUnstable.js +1 -0
  72. package/tgsl/conversion.d.ts +2 -0
  73. package/tgsl/conversion.js +3 -0
  74. package/tgsl/shaderGenerator.d.ts +1 -1
  75. package/tgsl/wgslGenerator.d.ts +5 -0
  76. package/tgsl/wgslGenerator.js +218 -50
  77. package/types.d.ts +9 -1
  78. package/types.js +5 -0
package/std/numeric.js CHANGED
@@ -6,7 +6,7 @@ import { abstractFloat, abstractInt, f16, f32, i32, u32 } from "../data/numeric.
6
6
  import { abstruct } from "../data/struct.js";
7
7
  import { vec2f, vec2h, vec2i, vec2u, vec3f, vec3h, vec3i, vec3u, vec4f, vec4h, vec4i, vec4u, } from "../data/vector.js";
8
8
  import { VectorOps } from "../data/vectorOps.js";
9
- import { generalizeFn, upCast } from "../data/generalizeFn.js";
9
+ import { floatKind, matrixKind, numericKind, signedKind, crossKind, assertEqualKinds, assertKind, upCast, generalizeFn, } from "../data/generalizeFn.js";
10
10
  import { isHalfPrecisionSchema, WORKAROUND_getSchema, } from "../data/wgslTypes.js";
11
11
  import { SignatureNotSupportedError } from "../errors.js";
12
12
  import { assertExhaustive } from "../shared/utilityTypes.js";
@@ -26,7 +26,7 @@ const variadicUnifySignature = (...args) => {
26
26
  returnType: uargs[0],
27
27
  };
28
28
  };
29
- const unifyRestrictedSignature = (restrict) => (...args) => {
29
+ export const unifyRestrictedSignature = (restrict) => (...args) => {
30
30
  const uargs = unify(args, restrict);
31
31
  if (!uargs) {
32
32
  throw new SignatureNotSupportedError(args, restrict);
@@ -61,6 +61,7 @@ const anyConcreteIntegerPrimitive = [i32, u32];
61
61
  const anyConcreteIntegerVec = [vec2i, vec3i, vec4i, vec2u, vec3u, vec4u];
62
62
  const anyConcreteInteger = [...anyConcreteIntegerPrimitive, ...anyConcreteIntegerVec];
63
63
  function cpuAbs(value) {
64
+ assertKind(value, numericKind);
64
65
  return generalizeFn(Math.abs, [value]);
65
66
  }
66
67
  export const abs = dualImpl({
@@ -71,6 +72,7 @@ export const abs = dualImpl({
71
72
  sideEffects: false,
72
73
  });
73
74
  function cpuAcos(value) {
75
+ assertKind(value, floatKind);
74
76
  return generalizeFn(Math.acos, [value]);
75
77
  }
76
78
  export const acos = dualImpl({
@@ -81,6 +83,7 @@ export const acos = dualImpl({
81
83
  sideEffects: false,
82
84
  });
83
85
  function cpuAcosh(value) {
86
+ assertKind(value, floatKind);
84
87
  return generalizeFn(Math.acosh, [value]);
85
88
  }
86
89
  export const acosh = dualImpl({
@@ -91,6 +94,7 @@ export const acosh = dualImpl({
91
94
  sideEffects: false,
92
95
  });
93
96
  function cpuAsin(value) {
97
+ assertKind(value, floatKind);
94
98
  return generalizeFn(Math.asin, [value]);
95
99
  }
96
100
  export const asin = dualImpl({
@@ -101,6 +105,7 @@ export const asin = dualImpl({
101
105
  sideEffects: false,
102
106
  });
103
107
  function cpuAsinh(value) {
108
+ assertKind(value, floatKind);
104
109
  return generalizeFn(Math.asinh, [value]);
105
110
  }
106
111
  export const asinh = dualImpl({
@@ -111,6 +116,7 @@ export const asinh = dualImpl({
111
116
  sideEffects: false,
112
117
  });
113
118
  function cpuAtan(value) {
119
+ assertKind(value, floatKind);
114
120
  return generalizeFn(Math.atan, [value]);
115
121
  }
116
122
  export const atan = dualImpl({
@@ -121,6 +127,7 @@ export const atan = dualImpl({
121
127
  sideEffects: false,
122
128
  });
123
129
  function cpuAtanh(value) {
130
+ assertKind(value, floatKind);
124
131
  return generalizeFn(Math.atanh, [value]);
125
132
  }
126
133
  export const atanh = dualImpl({
@@ -131,6 +138,8 @@ export const atanh = dualImpl({
131
138
  sideEffects: false,
132
139
  });
133
140
  function cpuAtan2(y, x) {
141
+ assertKind([y, x], floatKind);
142
+ assertEqualKinds(y, x);
134
143
  return generalizeFn(Math.atan2, [y, x]);
135
144
  }
136
145
  export const atan2 = dualImpl({
@@ -141,6 +150,7 @@ export const atan2 = dualImpl({
141
150
  sideEffects: false,
142
151
  });
143
152
  function cpuCeil(value) {
153
+ assertKind(value, floatKind);
144
154
  return generalizeFn(Math.ceil, [value]);
145
155
  }
146
156
  export const ceil = dualImpl({
@@ -151,6 +161,8 @@ export const ceil = dualImpl({
151
161
  sideEffects: false,
152
162
  });
153
163
  function cpuClamp(value, low, high) {
164
+ assertKind([value, low, high], numericKind);
165
+ assertEqualKinds(value, low, high);
154
166
  return generalizeFn(clampScalar, [value, low, high]);
155
167
  }
156
168
  export const clamp = dualImpl({
@@ -161,6 +173,7 @@ export const clamp = dualImpl({
161
173
  sideEffects: false,
162
174
  });
163
175
  function cpuCos(value) {
176
+ assertKind(value, floatKind);
164
177
  return generalizeFn(Math.cos, [value]);
165
178
  }
166
179
  export const cos = dualImpl({
@@ -171,6 +184,7 @@ export const cos = dualImpl({
171
184
  sideEffects: false,
172
185
  });
173
186
  function cpuCosh(value) {
187
+ assertKind(value, floatKind);
174
188
  return generalizeFn(Math.cosh, [value]);
175
189
  }
176
190
  export const cosh = dualImpl({
@@ -213,11 +227,16 @@ export const countTrailingZeros = dualImpl({
213
227
  export const cross = dualImpl({
214
228
  name: 'cross',
215
229
  signature: unifyRestrictedSignature([vec3f, vec3h]),
216
- normalImpl: (a, b) => VectorOps.cross[a.kind](a, b),
230
+ normalImpl: (a, b) => {
231
+ assertKind([a, b], crossKind);
232
+ assertEqualKinds(a, b);
233
+ return VectorOps.cross[a.kind](a, b);
234
+ },
217
235
  codegenImpl: (_ctx, [a, b]) => stitch `cross(${a}, ${b})`,
218
236
  sideEffects: false,
219
237
  });
220
238
  function cpuDegrees(value) {
239
+ assertKind(value, floatKind);
221
240
  if (typeof value === 'number') {
222
241
  return ((value * 180) / Math.PI);
223
242
  }
@@ -243,6 +262,8 @@ export const determinant = dualImpl({
243
262
  sideEffects: false,
244
263
  });
245
264
  function cpuDistance(a, b) {
265
+ assertKind([a, b], floatKind);
266
+ assertEqualKinds(a, b);
246
267
  if (typeof a === 'number' && typeof b === 'number') {
247
268
  return Math.abs(a - b);
248
269
  }
@@ -270,7 +291,11 @@ export const dot = dualImpl({
270
291
  argTypes: args,
271
292
  returnType: args[0].primitive,
272
293
  }),
273
- normalImpl: (lhs, rhs) => VectorOps.dot[lhs.kind](lhs, rhs),
294
+ normalImpl: (lhs, rhs) => {
295
+ assertKind([lhs, rhs], numericKind, true);
296
+ assertEqualKinds(lhs, rhs);
297
+ return VectorOps.dot[lhs.kind](lhs, rhs);
298
+ },
274
299
  codegenImpl: (_ctx, [lhs, rhs]) => stitch `dot(${lhs}, ${rhs})`,
275
300
  sideEffects: false,
276
301
  });
@@ -289,6 +314,7 @@ export const dot4I8Packed = dualImpl({
289
314
  sideEffects: false,
290
315
  });
291
316
  function cpuExp(value) {
317
+ assertKind(value, floatKind);
292
318
  return generalizeFn(Math.exp, [value]);
293
319
  }
294
320
  export const exp = dualImpl({
@@ -299,6 +325,7 @@ export const exp = dualImpl({
299
325
  sideEffects: false,
300
326
  });
301
327
  function cpuExp2(value) {
328
+ assertKind(value, floatKind);
302
329
  return generalizeFn((val) => 2 ** val, [value]);
303
330
  }
304
331
  export const exp2 = dualImpl({
@@ -355,6 +382,7 @@ export const firstTrailingBit = dualImpl({
355
382
  sideEffects: false,
356
383
  });
357
384
  function cpuFloor(value) {
385
+ assertKind(value, floatKind);
358
386
  return generalizeFn(Math.floor, [value]);
359
387
  }
360
388
  export const floor = dualImpl({
@@ -365,6 +393,8 @@ export const floor = dualImpl({
365
393
  sideEffects: false,
366
394
  });
367
395
  function cpuFma(e1, e2, e3) {
396
+ assertKind([e1, e2, e3], floatKind);
397
+ assertEqualKinds(e1, e2, e3);
368
398
  if (typeof e1 === 'number') {
369
399
  return (e1 * e2 + e3);
370
400
  }
@@ -378,6 +408,7 @@ export const fma = dualImpl({
378
408
  sideEffects: false,
379
409
  });
380
410
  function cpuFract(value) {
411
+ assertKind(value, floatKind);
381
412
  return generalizeFn((value) => value - Math.floor(value), [value]);
382
413
  }
383
414
  export const fract = dualImpl({
@@ -431,6 +462,7 @@ export const insertBits = dualImpl({
431
462
  sideEffects: false,
432
463
  });
433
464
  function cpuInverseSqrt(value) {
465
+ assertKind(value, floatKind);
434
466
  if (typeof value === 'number') {
435
467
  return (1 / Math.sqrt(value));
436
468
  }
@@ -440,7 +472,7 @@ export const inverseSqrt = dualImpl({
440
472
  name: 'inverseSqrt',
441
473
  signature: unifyRestrictedSignature(anyFloat),
442
474
  normalImpl: cpuInverseSqrt,
443
- codegenImpl: (_ctx, [value]) => stitch `inverseSqrt(${value})`,
475
+ codegenImpl: (ctx, [value]) => ctx.gen.emitCall('inverseSqrt', [], [value]),
444
476
  sideEffects: false,
445
477
  });
446
478
  function cpuLdexp(_e1, _e2) {
@@ -473,6 +505,7 @@ export const ldexp = dualImpl({
473
505
  sideEffects: false,
474
506
  });
475
507
  function cpuLength(value) {
508
+ assertKind(value, floatKind);
476
509
  if (typeof value === 'number') {
477
510
  return Math.abs(value);
478
511
  }
@@ -495,6 +528,7 @@ export const length = dualImpl({
495
528
  sideEffects: false,
496
529
  });
497
530
  function cpuLog(value) {
531
+ assertKind(value, floatKind);
498
532
  return generalizeFn(Math.log, [value]);
499
533
  }
500
534
  export const log = dualImpl({
@@ -505,6 +539,7 @@ export const log = dualImpl({
505
539
  sideEffects: false,
506
540
  });
507
541
  function cpuLog2(value) {
542
+ assertKind(value, floatKind);
508
543
  return generalizeFn(Math.log2, [value]);
509
544
  }
510
545
  export const log2 = dualImpl({
@@ -515,6 +550,8 @@ export const log2 = dualImpl({
515
550
  sideEffects: false,
516
551
  });
517
552
  function cpuMax(a, b) {
553
+ assertKind([a, b], numericKind);
554
+ assertEqualKinds(a, b);
518
555
  return generalizeFn(Math.max, [a, b]);
519
556
  }
520
557
  export const max = dualImpl({
@@ -525,6 +562,8 @@ export const max = dualImpl({
525
562
  sideEffects: false,
526
563
  });
527
564
  function cpuMin(a, b) {
565
+ assertKind([a, b], numericKind);
566
+ assertEqualKinds(a, b);
528
567
  return generalizeFn(Math.min, [a, b]);
529
568
  }
530
569
  export const min = dualImpl({
@@ -535,6 +574,13 @@ export const min = dualImpl({
535
574
  sideEffects: false,
536
575
  });
537
576
  function cpuMix(e1, e2, e3) {
577
+ assertKind([e1, e2, e3], floatKind);
578
+ if (typeof e3 === 'number') {
579
+ assertEqualKinds(e1, e2);
580
+ }
581
+ else {
582
+ assertEqualKinds(e1, e2, e3);
583
+ }
538
584
  return generalizeFn((e1, e2, e3) => e1 * (1 - e3) + e2 * e3, [e1, ...upCast([e2, e3])]);
539
585
  }
540
586
  export const mix = dualImpl({
@@ -588,6 +634,7 @@ export const normalize = dualImpl({
588
634
  name: 'normalize',
589
635
  signature: unifyRestrictedSignature(anyFloatVec),
590
636
  normalImpl: (v) => {
637
+ assertKind(v, floatKind);
591
638
  const len = length(v);
592
639
  return generalizeFn((e) => e / len, [v]);
593
640
  },
@@ -595,6 +642,8 @@ export const normalize = dualImpl({
595
642
  sideEffects: false,
596
643
  });
597
644
  function powCpu(base, exponent) {
645
+ assertKind([base, exponent], floatKind);
646
+ assertEqualKinds(base, exponent);
598
647
  return generalizeFn((a, b) => a ** b, [base, exponent]);
599
648
  }
600
649
  export const pow = dualImpl({
@@ -622,6 +671,7 @@ export const quantizeToF16 = dualImpl({
622
671
  sideEffects: false,
623
672
  });
624
673
  function cpuRadians(value) {
674
+ assertKind(value, floatKind);
625
675
  if (typeof value === 'number') {
626
676
  return ((value * Math.PI) / 180);
627
677
  }
@@ -646,7 +696,11 @@ export const reflect = dualImpl({
646
696
  returnType: uargs[0],
647
697
  };
648
698
  },
649
- normalImpl: (e1, e2) => sub(e1, mul(2 * dot(e2, e1), e2)),
699
+ normalImpl: (e1, e2) => {
700
+ assertKind([e1, e2], floatKind, true);
701
+ assertEqualKinds(e1, e2);
702
+ return sub(e1, mul(2 * dot(e2, e1), e2));
703
+ },
650
704
  codegenImpl: (_ctx, [e1, e2]) => stitch `reflect(${e1}, ${e2})`,
651
705
  sideEffects: false,
652
706
  });
@@ -671,6 +725,7 @@ export const reverseBits = dualImpl({
671
725
  sideEffects: false,
672
726
  });
673
727
  function cpuRound(value) {
728
+ assertKind(value, floatKind);
674
729
  if (typeof value === 'number') {
675
730
  const floor = Math.floor(value);
676
731
  if (value === floor + 0.5) {
@@ -691,6 +746,7 @@ export const round = dualImpl({
691
746
  sideEffects: false,
692
747
  });
693
748
  function cpuSaturate(value) {
749
+ assertKind(value, floatKind);
694
750
  if (typeof value === 'number') {
695
751
  return Math.max(0, Math.min(1, value));
696
752
  }
@@ -704,6 +760,7 @@ export const saturate = dualImpl({
704
760
  sideEffects: false,
705
761
  });
706
762
  function cpuSign(e) {
763
+ assertKind(e, signedKind);
707
764
  return generalizeFn(Math.sign, [e]);
708
765
  }
709
766
  export const sign = dualImpl({
@@ -721,6 +778,7 @@ export const sign = dualImpl({
721
778
  sideEffects: false,
722
779
  });
723
780
  function cpuSin(value) {
781
+ assertKind(value, floatKind);
724
782
  return generalizeFn(Math.sin, [value]);
725
783
  }
726
784
  export const sin = dualImpl({
@@ -731,6 +789,7 @@ export const sin = dualImpl({
731
789
  sideEffects: false,
732
790
  });
733
791
  function cpuSinh(value) {
792
+ assertKind(value, floatKind);
734
793
  return generalizeFn(Math.sinh, [value]);
735
794
  }
736
795
  export const sinh = dualImpl({
@@ -741,6 +800,8 @@ export const sinh = dualImpl({
741
800
  sideEffects: false,
742
801
  });
743
802
  function cpuSmoothstep(edge0, edge1, x) {
803
+ assertKind([edge0, edge1, x], floatKind);
804
+ assertEqualKinds(edge0, edge1, x);
744
805
  return generalizeFn(smoothstepScalar, [edge0, edge1, x]);
745
806
  }
746
807
  export const smoothstep = dualImpl({
@@ -751,6 +812,7 @@ export const smoothstep = dualImpl({
751
812
  sideEffects: false,
752
813
  });
753
814
  function cpuSqrt(value) {
815
+ assertKind(value, floatKind);
754
816
  return generalizeFn(Math.sqrt, [value]);
755
817
  }
756
818
  export const sqrt = dualImpl({
@@ -761,6 +823,8 @@ export const sqrt = dualImpl({
761
823
  sideEffects: false,
762
824
  });
763
825
  function cpuStep(edge, x) {
826
+ assertKind([edge, x], floatKind);
827
+ assertEqualKinds(edge, x);
764
828
  if (typeof edge === 'number') {
765
829
  return (edge <= x ? 1.0 : 0.0);
766
830
  }
@@ -774,6 +838,7 @@ export const step = dualImpl({
774
838
  sideEffects: false,
775
839
  });
776
840
  function cpuTan(value) {
841
+ assertKind(value, floatKind);
777
842
  if (typeof value === 'number') {
778
843
  return Math.tan(value);
779
844
  }
@@ -787,6 +852,7 @@ export const tan = dualImpl({
787
852
  sideEffects: false,
788
853
  });
789
854
  function cpuTanh(value) {
855
+ assertKind(value, floatKind);
790
856
  return generalizeFn(Math.tanh, [value]);
791
857
  }
792
858
  export const tanh = dualImpl({
@@ -797,6 +863,7 @@ export const tanh = dualImpl({
797
863
  sideEffects: false,
798
864
  });
799
865
  function cpuTranspose(value) {
866
+ assertKind(value, matrixKind);
800
867
  const schema = WORKAROUND_getSchema(value);
801
868
  // NOTE: This assumes all matrices are square
802
869
  const transposed = schema();
@@ -879,9 +946,9 @@ function cpuIntdiv(lhs, rhs) {
879
946
  export const intdiv = dualImpl({
880
947
  name: 'intdiv',
881
948
  signature: (lhs, rhs) => {
882
- const unified = unify([lhs, rhs], [u32, i32]);
949
+ const unified = unify([lhs, rhs], [i32, u32]);
883
950
  if (!unified) {
884
- throw new SignatureNotSupportedError([lhs, rhs], [u32, i32, abstractInt]);
951
+ throw new SignatureNotSupportedError([lhs, rhs], [i32, u32, abstractInt]);
885
952
  }
886
953
  return { argTypes: unified, returnType: unified[0] };
887
954
  },
@@ -1,4 +1,4 @@
1
- import { type AnyIntegerVecInstance, type AnyMatInstance, type AnyNumericVecInstance, type mBaseForVec, type vBaseForMat, type vecIToVecU } from '../data/wgslTypes.ts';
1
+ import { type AnyIntegerVecInstance, type AnyMatInstance, type AnyNumericVecInstance, type AnySignedVecInstance, type mBaseForVec, type vBaseForMat, type vecIToVecU } from '../data/wgslTypes.ts';
2
2
  type NumVec = AnyNumericVecInstance;
3
3
  type Mat = AnyMatInstance;
4
4
  declare function cpuAdd(lhs: number, rhs: number): number;
@@ -39,7 +39,7 @@ type ModOverload = {
39
39
  */
40
40
  export declare const mod: import("../types.ts").DualFn<ModOverload>;
41
41
  declare function cpuNeg(value: number): number;
42
- declare function cpuNeg<T extends NumVec>(value: T): T;
42
+ declare function cpuNeg<T extends AnySignedVecInstance>(value: T): T;
43
43
  export declare const neg: import("../types.ts").DualFn<typeof cpuNeg>;
44
44
  declare function cpuBitShiftLeft<T extends AnyIntegerVecInstance>(lhs: T, rhs: number | vecIToVecU<T>): T;
45
45
  export declare const bitShiftLeft: import("../types.ts").DualFn<typeof cpuBitShiftLeft>;
package/std/operators.js CHANGED
@@ -3,9 +3,9 @@ import { stitch } from "../core/resolve/stitch.js";
3
3
  import { abstractFloat, f16, f32, u32 } from "../data/numeric.js";
4
4
  import { vec2i, vec2u, vec3i, vec3u, vec4i, vec4u } from "../data/vector.js";
5
5
  import { VectorOps } from "../data/vectorOps.js";
6
- import { generalizeFn, upCast } from "../data/generalizeFn.js";
7
- import { isFloat32VecInstance, isInteger32VecInstance, isMat, isMatInstance, isUint32VecInstance, isVec, isVecInstance, } from "../data/wgslTypes.js";
8
- import { SignatureNotSupportedError } from "../errors.js";
6
+ import { generalizeFn, kindOf, numericKind, numericOrMatrixKind, signedKind, upCast, assertEqualKinds, assertKind, } from "../data/generalizeFn.js";
7
+ import { isFloat32VecInstance, isMat, isMatInstance, isVec, isVecInstance, isInteger32VecInstance, isUint32VecInstance, } from "../data/wgslTypes.js";
8
+ import { SignatureNotSupportedError, WgslTypeError } from "../errors.js";
9
9
  import { unify } from "../tgsl/conversion.js";
10
10
  const getPrimitive = (t) => ('primitive' in t ? t.primitive : t);
11
11
  const makeBinarySignature = (opts) => (lhs, rhs) => {
@@ -56,19 +56,15 @@ const binaryDivSignature = makeBinarySignature({
56
56
  restrict: [f32, f16, abstractFloat],
57
57
  });
58
58
  function cpuAdd(lhs, rhs) {
59
- if (typeof lhs === 'number' && typeof rhs === 'number') {
60
- return lhs + rhs; // default addition
61
- }
62
- if (typeof lhs === 'number' && isVecInstance(rhs)) {
63
- return generalizeFn((e) => lhs + e, [rhs]); // mixed addition
64
- }
65
- if (isVecInstance(lhs) && typeof rhs === 'number') {
66
- return generalizeFn((e) => e + rhs, [lhs]); // mixed addition
59
+ assertKind([lhs, rhs], numericOrMatrixKind);
60
+ if (isMatInstance(lhs) !== isMatInstance(rhs)) {
61
+ throw new WgslTypeError('There is no matrix/non-matrix addition or subtraction in WGSL.');
67
62
  }
68
- if ((isVecInstance(lhs) && isVecInstance(rhs)) || (isMatInstance(lhs) && isMatInstance(rhs))) {
69
- return generalizeFn((a, b) => a + b, [lhs, rhs]); // component-wise addition
63
+ if ((typeof lhs === 'number') === (typeof rhs === 'number')) {
64
+ // If exactly one is a number, then it's fine, since we already know the other one is not a matrix.
65
+ assertEqualKinds(lhs, rhs);
70
66
  }
71
- throw new Error('Add/Sub called with invalid arguments.');
67
+ return generalizeFn((a, b) => a + b, upCast([lhs, rhs]));
72
68
  }
73
69
  export const add = dualImpl({
74
70
  name: 'add',
@@ -89,6 +85,7 @@ export const sub = dualImpl({
89
85
  sideEffects: false,
90
86
  });
91
87
  function cpuMul(lhs, rhs) {
88
+ assertKind([lhs, rhs], numericOrMatrixKind);
92
89
  if (typeof lhs === 'number' && typeof rhs === 'number') {
93
90
  return lhs * rhs; // default multiplication
94
91
  }
@@ -99,18 +96,26 @@ function cpuMul(lhs, rhs) {
99
96
  return generalizeFn((e) => e * rhs, [lhs]); // scale
100
97
  }
101
98
  if (isVecInstance(lhs) && isVecInstance(rhs)) {
99
+ assertEqualKinds(lhs, rhs);
102
100
  return generalizeFn((a, b) => a * b, [lhs, rhs]); // component-wise
103
101
  }
104
102
  if (isFloat32VecInstance(lhs) && isMatInstance(rhs)) {
103
+ if (lhs.length !== rhs.columns.length) {
104
+ throw new WgslTypeError(`Unsupported signature. Kind '${kindOf(lhs)}' cannot be multiplied by '${kindOf(rhs)}'.`);
105
+ }
105
106
  return VectorOps.mulVxM[rhs.kind](lhs, rhs); // row-vector-matrix
106
107
  }
107
108
  if (isMatInstance(lhs) && isFloat32VecInstance(rhs)) {
109
+ if (lhs.columns.length !== rhs.length) {
110
+ throw new WgslTypeError(`Unsupported signature. Kind '${kindOf(lhs)}' cannot be multiplied by '${kindOf(rhs)}'.`);
111
+ }
108
112
  return VectorOps.mulMxV[lhs.kind](lhs, rhs); // matrix-column-vector
109
113
  }
110
114
  if (isMatInstance(lhs) && isMatInstance(rhs)) {
115
+ assertEqualKinds(lhs, rhs);
111
116
  return VectorOps.mulMxM[lhs.kind](lhs, rhs); // matrix multiplication
112
117
  }
113
- throw new Error('Mul called with invalid arguments.');
118
+ throw new WgslTypeError(`Unsupported signature. Kind '${kindOf(lhs)}' cannot be multiplied by '${kindOf(rhs)}'.`);
114
119
  }
115
120
  export const mul = dualImpl({
116
121
  name: 'mul',
@@ -120,7 +125,10 @@ export const mul = dualImpl({
120
125
  sideEffects: false,
121
126
  });
122
127
  function cpuDiv(lhs, rhs) {
123
- return generalizeFn((a, b) => a / b, upCast([lhs, rhs]));
128
+ assertKind([lhs, rhs], numericKind);
129
+ const cast = upCast([lhs, rhs]);
130
+ assertEqualKinds(...cast);
131
+ return generalizeFn((a, b) => a / b, cast);
124
132
  }
125
133
  export const div = dualImpl({
126
134
  name: 'div',
@@ -138,12 +146,16 @@ export const mod = dualImpl({
138
146
  name: 'mod',
139
147
  signature: binaryDivSignature,
140
148
  normalImpl: ((a, b) => {
141
- return generalizeFn((a, b) => a % b, upCast([a, b]));
149
+ assertKind([a, b], numericKind);
150
+ const cast = upCast([a, b]);
151
+ assertEqualKinds(...cast);
152
+ return generalizeFn((a, b) => a % b, cast);
142
153
  }),
143
154
  codegenImpl: (ctx, [lhs, rhs]) => ctx.gen.emitBinaryOp(lhs, '%', rhs),
144
155
  sideEffects: false,
145
156
  });
146
157
  function cpuNeg(value) {
158
+ assertKind(value, signedKind);
147
159
  return generalizeFn((value) => -value, [value]);
148
160
  }
149
161
  export const neg = dualImpl({
package/std/packing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { v2f, v4f } from '../data/wgslTypes.ts';
1
+ import type { v2f, v4f, v4i, v4u } from '../data/wgslTypes.ts';
2
2
  /**
3
3
  * @privateRemarks
4
4
  * https://gpuweb.github.io/gpuweb/wgsl/#unpack2x16float-builtin
@@ -9,13 +9,73 @@ export declare const unpack2x16float: import("../types.ts").DualFn<(e: number) =
9
9
  * https://gpuweb.github.io/gpuweb/wgsl/#pack2x16float-builtin
10
10
  */
11
11
  export declare const pack2x16float: import("../types.ts").DualFn<(e: v2f) => number>;
12
+ /**
13
+ * @privateRemarks
14
+ * https://www.w3.org/TR/WGSL/#pack2x16snorm-builtin
15
+ */
16
+ export declare const pack2x16snorm: import("../types.ts").DualFn<(e: v2f) => number>;
17
+ /**
18
+ * @privateRemarks
19
+ * https://www.w3.org/TR/WGSL/#pack2x16unorm-builtin
20
+ */
21
+ export declare const pack2x16unorm: import("../types.ts").DualFn<(e: v2f) => number>;
12
22
  /**
13
23
  * @privateRemarks
14
24
  * https://gpuweb.github.io/gpuweb/wgsl/#unpack4x8unorm-builtin
15
25
  */
16
26
  export declare const unpack4x8unorm: import("../types.ts").DualFn<(e: number) => v4f>;
27
+ /**
28
+ * @privateRemarks
29
+ * https://www.w3.org/TR/WGSL/#unpack4x8snorm-builtin
30
+ */
31
+ export declare const unpack4x8snorm: import("../types.ts").DualFn<(e: number) => v4f>;
32
+ /**
33
+ * @privateRemarks
34
+ * https://www.w3.org/TR/WGSL/#unpack4xi8-builtin
35
+ */
36
+ export declare const unpack4xI8: import("../types.ts").DualFn<(e: number) => v4i>;
37
+ /**
38
+ * @privateRemarks
39
+ * https://www.w3.org/TR/WGSL/#unpack4xu8-builtin
40
+ */
41
+ export declare const unpack4xU8: import("../types.ts").DualFn<(e: number) => v4u>;
42
+ /**
43
+ * @privateRemarks
44
+ * https://www.w3.org/TR/WGSL/#unpack2x16snorm-builtin
45
+ */
46
+ export declare const unpack2x16snorm: import("../types.ts").DualFn<(e: number) => v2f>;
47
+ /**
48
+ * @privateRemarks
49
+ * https://www.w3.org/TR/WGSL/#unpack2x16unorm-builtin
50
+ */
51
+ export declare const unpack2x16unorm: import("../types.ts").DualFn<(e: number) => v2f>;
17
52
  /**
18
53
  * @privateRemarks
19
54
  * https://gpuweb.github.io/gpuweb/wgsl/#pack4x8unorm-builtin
20
55
  */
21
56
  export declare const pack4x8unorm: import("../types.ts").DualFn<(e: v4f) => number>;
57
+ /**
58
+ * @privateRemarks
59
+ * https://www.w3.org/TR/WGSL/#pack4x8snorm-builtin
60
+ */
61
+ export declare const pack4x8snorm: import("../types.ts").DualFn<(e: v4f) => number>;
62
+ /**
63
+ * @privateRemarks
64
+ * https://www.w3.org/TR/WGSL/#pack4xi8-builtin
65
+ */
66
+ export declare const pack4xI8: import("../types.ts").DualFn<(e: v4i) => number>;
67
+ /**
68
+ * @privateRemarks
69
+ * https://www.w3.org/TR/WGSL/#pack4xu8-builtin
70
+ */
71
+ export declare const pack4xU8: import("../types.ts").DualFn<(e: v4u) => number>;
72
+ /**
73
+ * @privateRemarks
74
+ * https://www.w3.org/TR/WGSL/#pack4xi8clamp-builtin
75
+ */
76
+ export declare const pack4xI8Clamp: import("../types.ts").DualFn<(e: v4i) => number>;
77
+ /**
78
+ * @privateRemarks
79
+ * https://www.w3.org/TR/WGSL/#pack4xu8clamp-builtin
80
+ */
81
+ export declare const pack4xU8Clamp: import("../types.ts").DualFn<(e: v4u) => number>;