typegpu 0.12.5 → 0.12.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/common/index.d.ts +1 -0
- package/common/index.js +1 -0
- package/common/writeChannels.d.ts +31 -0
- package/common/writeChannels.js +32 -0
- package/common/writeSoA.js +16 -0
- package/core/buffer/buffer.js +47 -11
- package/core/commandEncoder/attachments.js +5 -2
- package/core/commandEncoder/computePass.d.ts +13 -0
- package/core/commandEncoder/computePass.js +5 -2
- package/core/commandEncoder/renderPass.d.ts +18 -4
- package/core/commandEncoder/renderPass.js +6 -2
- package/core/declare/tgpuDeclare.d.ts +11 -0
- package/core/declare/tgpuDeclare.js +1 -1
- package/core/function/autoIO.js +4 -2
- package/core/function/ioSchema.d.ts +7 -2
- package/core/function/ioSchema.js +41 -15
- package/core/function/tgpuFragmentFn.d.ts +1 -1
- package/core/function/tgpuFragmentFn.js +2 -1
- package/core/function/tgpuVertexFn.js +2 -1
- package/core/immediate/immediateVar.d.ts +52 -0
- package/core/immediate/immediateVar.js +149 -0
- package/core/pipeline/computePipeline.d.ts +17 -0
- package/core/pipeline/computePipeline.js +23 -9
- package/core/pipeline/connectAttachmentToShader.d.ts +2 -2
- package/core/pipeline/connectAttachmentToShader.js +16 -21
- package/core/pipeline/connectTargetsToShader.d.ts +5 -1
- package/core/pipeline/connectTargetsToShader.js +23 -18
- package/core/pipeline/drawState.d.ts +8 -4
- package/core/pipeline/drawState.js +41 -51
- package/core/pipeline/priors.js +1 -0
- package/core/pipeline/renderPipeline.d.ts +22 -4
- package/core/pipeline/renderPipeline.js +25 -13
- package/core/resolve/namespace.js +2 -2
- package/core/root/init.js +3 -0
- package/core/root/rootTypes.d.ts +17 -2
- package/core/slot/accessor.d.ts +1 -1
- package/core/slot/accessor.js +72 -5
- package/core/slot/slotTypes.d.ts +2 -1
- package/core/texture/texture.d.ts +20 -14
- package/core/texture/texture.js +78 -69
- package/core/texture/textureUtils.d.ts +3 -6
- package/core/texture/textureUtils.js +142 -165
- package/core/texture/textureWrite.d.ts +61 -0
- package/core/texture/textureWrite.js +59 -0
- package/data/autoStruct.d.ts +1 -1
- package/data/autoStruct.js +8 -4
- package/data/dataIO.d.ts +2 -2
- package/data/deepEqual.js +19 -9
- package/data/matrix.js +10 -3
- package/data/partialIO.d.ts +8 -1
- package/data/partialIO.js +36 -19
- package/data/ref.js +2 -2
- package/data/snippet.d.ts +11 -5
- package/data/snippet.js +9 -4
- package/data/wgslTypes.d.ts +4 -1
- package/errors.d.ts +7 -0
- package/errors.js +15 -0
- package/indexNamedExports.d.ts +5 -2
- package/indexNamedExports.js +2 -1
- package/internal.d.ts +2 -1
- package/internal.js +1 -1
- package/nameUtils.d.ts +7 -0
- package/nameUtils.js +60 -0
- package/package.json +2 -2
- package/resolutionCtx.d.ts +5 -0
- package/resolutionCtx.js +11 -0
- package/serial/restore.d.ts +3 -1
- package/serial/restore.js +2 -0
- package/shared/meta.js +1 -1
- package/shared/symbols.js +1 -1
- package/shared/tseynit.d.ts +1 -0
- package/shared/tseynit.js +80 -44
- package/std/atomic.d.ts +13 -0
- package/std/atomic.js +63 -29
- package/std/boolean.js +9 -10
- package/std/derivative.js +14 -9
- package/std/index.d.ts +4 -4
- package/std/index.js +5 -5
- package/std/numeric.d.ts +5 -1
- package/std/numeric.js +3 -3
- package/std/operators.js +9 -4
- package/std/packing.d.ts +61 -1
- package/std/packing.js +214 -25
- package/std/subgroup.d.ts +4 -0
- package/std/subgroup.js +34 -0
- package/std/texture.d.ts +15 -2
- package/std/texture.js +48 -0
- package/tgpuUnstable.d.ts +1 -0
- package/tgpuUnstable.js +1 -0
- package/tgsl/accessIndex.js +19 -23
- package/tgsl/conversion.d.ts +2 -0
- package/tgsl/conversion.js +3 -0
- package/tgsl/forOfUtils.js +6 -6
- package/tgsl/generationHelpers.js +2 -2
- package/tgsl/shaderGenerator.d.ts +1 -1
- package/tgsl/wgslGenerator.d.ts +5 -0
- package/tgsl/wgslGenerator.js +288 -58
- package/types.d.ts +9 -1
- package/types.js +5 -0
package/std/subgroup.js
CHANGED
|
@@ -181,3 +181,37 @@ export const subgroupXor = dualImpl({
|
|
|
181
181
|
codegenImpl: (_ctx, [e]) => stitch `subgroupXor(${e})`,
|
|
182
182
|
sideEffects: false,
|
|
183
183
|
});
|
|
184
|
+
export const quadBroadcast = dualImpl({
|
|
185
|
+
name: 'quadBroadcast',
|
|
186
|
+
signature: (...args) => {
|
|
187
|
+
const id = unify([args[1]], [i32, u32]);
|
|
188
|
+
if (!id) {
|
|
189
|
+
throw new Error(`quadBroadcast's second argument has to be compatible with i32 or u32. Got: ${args[1].type}`);
|
|
190
|
+
}
|
|
191
|
+
return { argTypes: [args[0], id[0]], returnType: args[0] };
|
|
192
|
+
},
|
|
193
|
+
normalImpl: errorMessage,
|
|
194
|
+
codegenImpl: (_ctx, [e, id]) => stitch `quadBroadcast(${e}, ${id})`,
|
|
195
|
+
sideEffects: false,
|
|
196
|
+
});
|
|
197
|
+
export const quadSwapDiagonal = dualImpl({
|
|
198
|
+
name: 'quadSwapDiagonal',
|
|
199
|
+
signature: (arg) => ({ argTypes: [arg], returnType: arg }),
|
|
200
|
+
normalImpl: errorMessage,
|
|
201
|
+
codegenImpl: (_ctx, [e]) => stitch `quadSwapDiagonal(${e})`,
|
|
202
|
+
sideEffects: false,
|
|
203
|
+
});
|
|
204
|
+
export const quadSwapX = dualImpl({
|
|
205
|
+
name: 'quadSwapX',
|
|
206
|
+
signature: (arg) => ({ argTypes: [arg], returnType: arg }),
|
|
207
|
+
normalImpl: errorMessage,
|
|
208
|
+
codegenImpl: (_ctx, [e]) => stitch `quadSwapX(${e})`,
|
|
209
|
+
sideEffects: false,
|
|
210
|
+
});
|
|
211
|
+
export const quadSwapY = dualImpl({
|
|
212
|
+
name: 'quadSwapY',
|
|
213
|
+
signature: (arg) => ({ argTypes: [arg], returnType: arg }),
|
|
214
|
+
normalImpl: errorMessage,
|
|
215
|
+
codegenImpl: (_ctx, [e]) => stitch `quadSwapY(${e})`,
|
|
216
|
+
sideEffects: false,
|
|
217
|
+
});
|
package/std/texture.d.ts
CHANGED
|
@@ -61,11 +61,19 @@ declare function textureStoreCpu<T extends textureStorage3d>(texture: T, coords:
|
|
|
61
61
|
export declare const textureStore: import("../types.ts").DualFn<typeof textureStoreCpu>;
|
|
62
62
|
declare function textureDimensionsCpu<T extends texture1d | textureStorage1d>(texture: T): number;
|
|
63
63
|
declare function textureDimensionsCpu<T extends texture1d>(texture: T, level: number): number;
|
|
64
|
-
declare function textureDimensionsCpu<T extends texture2d | texture2dArray | textureCube | textureCubeArray | textureStorage2d | textureStorage2dArray | textureExternal>(texture: T): v2u;
|
|
65
|
-
declare function textureDimensionsCpu<T extends texture2d | texture2dArray | textureCube | textureCubeArray>(texture: T, level: number): v2u;
|
|
64
|
+
declare function textureDimensionsCpu<T extends texture2d | texture2dArray | textureCube | textureCubeArray | textureMultisampled2d | textureDepth2d | textureDepth2dArray | textureDepthCube | textureDepthCubeArray | textureDepthMultisampled2d | textureStorage2d | textureStorage2dArray | textureExternal>(texture: T): v2u;
|
|
65
|
+
declare function textureDimensionsCpu<T extends texture2d | texture2dArray | textureCube | textureCubeArray | textureDepth2d | textureDepth2dArray | textureDepthCube | textureDepthCubeArray>(texture: T, level: number): v2u;
|
|
66
66
|
declare function textureDimensionsCpu<T extends texture3d | textureStorage3d>(texture: T): v3u;
|
|
67
67
|
declare function textureDimensionsCpu<T extends texture3d>(texture: T, level: number): v3u;
|
|
68
68
|
export declare const textureDimensions: import("../types.ts").DualFn<typeof textureDimensionsCpu>;
|
|
69
|
+
type ArrayTexture = texture2dArray | textureCubeArray | textureDepth2dArray | textureDepthCubeArray | textureStorage2dArray;
|
|
70
|
+
declare function textureNumLayersCpu<T extends ArrayTexture>(_texture: T): number;
|
|
71
|
+
export declare const textureNumLayers: import("../types.ts").DualFn<typeof textureNumLayersCpu>;
|
|
72
|
+
type MipmappedTexture = texture1d | texture2d | texture2dArray | texture3d | textureCube | textureCubeArray | textureDepth2d | textureDepth2dArray | textureDepthCube | textureDepthCubeArray;
|
|
73
|
+
declare function textureNumLevelsCpu<T extends MipmappedTexture>(_texture: T): number;
|
|
74
|
+
export declare const textureNumLevels: import("../types.ts").DualFn<typeof textureNumLevelsCpu>;
|
|
75
|
+
declare function textureNumSamplesCpu<T extends textureMultisampled2d | textureDepthMultisampled2d>(_texture: T): number;
|
|
76
|
+
export declare const textureNumSamples: import("../types.ts").DualFn<typeof textureNumSamplesCpu>;
|
|
69
77
|
type Gather2dArgs<T extends texture2d = texture2d> = [
|
|
70
78
|
component: number,
|
|
71
79
|
texture: T,
|
|
@@ -121,6 +129,11 @@ type TextureGatherCpuFn = {
|
|
|
121
129
|
};
|
|
122
130
|
export declare const textureGatherCpu: TextureGatherCpuFn;
|
|
123
131
|
export declare const textureGather: import("../types.ts").DualFn<TextureGatherCpuFn>;
|
|
132
|
+
declare function textureGatherCompareCpu<T extends textureDepth2d>(texture: T, sampler: comparisonSampler, coords: v2f, depthRef: number, offset?: v2i): v4f;
|
|
133
|
+
declare function textureGatherCompareCpu<T extends textureDepth2dArray>(texture: T, sampler: comparisonSampler, coords: v2f, arrayIndex: number, depthRef: number, offset?: v2i): v4f;
|
|
134
|
+
declare function textureGatherCompareCpu<T extends textureDepthCube>(texture: T, sampler: comparisonSampler, coords: v3f, depthRef: number): v4f;
|
|
135
|
+
declare function textureGatherCompareCpu<T extends textureDepthCubeArray>(texture: T, sampler: comparisonSampler, coords: v3f, arrayIndex: number, depthRef: number): v4f;
|
|
136
|
+
export declare const textureGatherCompare: import("../types.ts").DualFn<typeof textureGatherCompareCpu>;
|
|
124
137
|
declare function textureSampleCompareCpu<T extends textureDepth2d>(texture: T, sampler: comparisonSampler, coords: v2f, depthRef: number): number;
|
|
125
138
|
declare function textureSampleCompareCpu<T extends textureDepth2d>(texture: T, sampler: comparisonSampler, coords: v2f, depthRef: number, offset: v2i): number;
|
|
126
139
|
declare function textureSampleCompareCpu<T extends textureDepth2dArray>(texture: T, sampler: comparisonSampler, coords: v2f, arrayIndex: number, depthRef: number): number;
|
package/std/texture.js
CHANGED
|
@@ -129,6 +129,36 @@ export const textureDimensions = dualImpl({
|
|
|
129
129
|
},
|
|
130
130
|
sideEffects: false,
|
|
131
131
|
});
|
|
132
|
+
function textureNumLayersCpu(_texture) {
|
|
133
|
+
throw new MissingCpuImplError('`textureNumLayers` relies on GPU resources and cannot be executed outside of a draw call');
|
|
134
|
+
}
|
|
135
|
+
export const textureNumLayers = dualImpl({
|
|
136
|
+
name: 'textureNumLayers',
|
|
137
|
+
normalImpl: textureNumLayersCpu,
|
|
138
|
+
codegenImpl: (_ctx, [texture]) => stitch `textureNumLayers(${texture})`,
|
|
139
|
+
signature: (texture) => ({ argTypes: [texture], returnType: u32 }),
|
|
140
|
+
sideEffects: false,
|
|
141
|
+
});
|
|
142
|
+
function textureNumLevelsCpu(_texture) {
|
|
143
|
+
throw new MissingCpuImplError('`textureNumLevels` relies on GPU resources and cannot be executed outside of a draw call');
|
|
144
|
+
}
|
|
145
|
+
export const textureNumLevels = dualImpl({
|
|
146
|
+
name: 'textureNumLevels',
|
|
147
|
+
normalImpl: textureNumLevelsCpu,
|
|
148
|
+
codegenImpl: (_ctx, [texture]) => stitch `textureNumLevels(${texture})`,
|
|
149
|
+
signature: (texture) => ({ argTypes: [texture], returnType: u32 }),
|
|
150
|
+
sideEffects: false,
|
|
151
|
+
});
|
|
152
|
+
function textureNumSamplesCpu(_texture) {
|
|
153
|
+
throw new MissingCpuImplError('`textureNumSamples` relies on GPU resources and cannot be executed outside of a draw call');
|
|
154
|
+
}
|
|
155
|
+
export const textureNumSamples = dualImpl({
|
|
156
|
+
name: 'textureNumSamples',
|
|
157
|
+
normalImpl: textureNumSamplesCpu,
|
|
158
|
+
codegenImpl: (_ctx, [texture]) => stitch `textureNumSamples(${texture})`,
|
|
159
|
+
signature: (texture) => ({ argTypes: [texture], returnType: u32 }),
|
|
160
|
+
sideEffects: false,
|
|
161
|
+
});
|
|
132
162
|
export const textureGatherCpu = (..._args) => {
|
|
133
163
|
throw new Error('Texture gather relies on GPU resources and cannot be executed outside of a draw call');
|
|
134
164
|
};
|
|
@@ -162,6 +192,24 @@ export const textureGather = dualImpl({
|
|
|
162
192
|
},
|
|
163
193
|
sideEffects: false,
|
|
164
194
|
});
|
|
195
|
+
function textureGatherCompareCpu(_texture, _sampler, _coords, _depthRefOrArrayIndex, _depthRefOrOffset, _maybeOffset) {
|
|
196
|
+
throw new MissingCpuImplError('`textureGatherCompare` relies on GPU resources and cannot be executed outside of a draw call');
|
|
197
|
+
}
|
|
198
|
+
export const textureGatherCompare = dualImpl({
|
|
199
|
+
name: 'textureGatherCompare',
|
|
200
|
+
normalImpl: textureGatherCompareCpu,
|
|
201
|
+
codegenImpl: (_ctx, args) => stitch `textureGatherCompare(${args})`,
|
|
202
|
+
signature: (...args) => {
|
|
203
|
+
const texture = args[0];
|
|
204
|
+
const isArrayTexture = texture.type === 'texture_depth_2d_array' || texture.type === 'texture_depth_cube_array';
|
|
205
|
+
const [tex, sampler, coords, _arrayIndex, ...rest] = args;
|
|
206
|
+
return {
|
|
207
|
+
argTypes: isArrayTexture ? [tex, sampler, coords, [u32, i32], ...rest] : args,
|
|
208
|
+
returnType: vec4f,
|
|
209
|
+
};
|
|
210
|
+
},
|
|
211
|
+
sideEffects: false,
|
|
212
|
+
});
|
|
165
213
|
function textureSampleCompareCpu(_texture, _sampler, _coords, _depthRefOrArrayIndex, _depthRefOrOffset, _maybeOffset) {
|
|
166
214
|
throw new MissingCpuImplError('Texture comparison sampling relies on GPU resources and cannot be executed outside of a draw call');
|
|
167
215
|
}
|
package/tgpuUnstable.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { declare } from './core/declare/tgpuDeclare.ts';
|
|
2
|
+
export { immediateVar } from './core/immediate/immediateVar.ts';
|
|
2
3
|
export { rawCodeSnippet } from './core/rawCodeSnippet/tgpuRawCodeSnippet.ts';
|
|
3
4
|
export { namespace } from './core/resolve/namespace.ts';
|
|
4
5
|
export { simulate } from './core/simulate/tgpuSimulate.ts';
|
package/tgpuUnstable.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// NOTE: This is a barrel file, internal files should not import things from this file
|
|
2
2
|
export { declare } from "./core/declare/tgpuDeclare.js";
|
|
3
|
+
export { immediateVar } from "./core/immediate/immediateVar.js";
|
|
3
4
|
export { rawCodeSnippet } from "./core/rawCodeSnippet/tgpuRawCodeSnippet.js";
|
|
4
5
|
export { namespace } from "./core/resolve/namespace.js";
|
|
5
6
|
export { simulate } from "./core/simulate/tgpuSimulate.js";
|
package/tgsl/accessIndex.js
CHANGED
|
@@ -12,33 +12,31 @@ const indexableTypeToResult = {
|
|
|
12
12
|
mat3x3f: vec3f,
|
|
13
13
|
mat4x4f: vec4f,
|
|
14
14
|
};
|
|
15
|
+
function deriveIndexAccessOrigin(targetOrigin, indexOrigin) {
|
|
16
|
+
if (targetOrigin === 'constant-immutable-def') {
|
|
17
|
+
// Constant refs stay const unless the index forces runtime materialization
|
|
18
|
+
return indexOrigin === 'constant' || indexOrigin === 'constant-immutable-def'
|
|
19
|
+
? 'constant-immutable-def'
|
|
20
|
+
: 'runtime-immutable-def';
|
|
21
|
+
}
|
|
22
|
+
if (targetOrigin === 'constant') {
|
|
23
|
+
// Ephemeral constants indexed with constants stay constant, otherwise they become runtime-known
|
|
24
|
+
return indexOrigin === 'constant' || indexOrigin === 'constant-immutable-def'
|
|
25
|
+
? 'constant'
|
|
26
|
+
: 'runtime';
|
|
27
|
+
}
|
|
28
|
+
// Fallthrough
|
|
29
|
+
return targetOrigin;
|
|
30
|
+
}
|
|
15
31
|
export function accessIndex(target, indexArg) {
|
|
16
32
|
const index = typeof indexArg === 'number' ? coerceToSnippet(indexArg) : indexArg;
|
|
17
33
|
// array
|
|
18
34
|
if (isWgslArray(target.dataType) || isDisarray(target.dataType)) {
|
|
19
35
|
const elementType = target.dataType.elementType;
|
|
20
|
-
let origin;
|
|
21
|
-
if (target.origin === 'constant-immutable-def') {
|
|
22
|
-
// Constant refs stay const unless the element/index forces runtime materialization
|
|
23
|
-
origin =
|
|
24
|
-
index.origin === 'constant' || index.origin === 'constant-immutable-def'
|
|
25
|
-
? 'constant-immutable-def'
|
|
26
|
-
: 'runtime-immutable-def';
|
|
27
|
-
}
|
|
28
|
-
else if (target.origin === 'constant') {
|
|
29
|
-
// Ephemeral constants indexed with constants stay constant, otherwise they become runtime-known
|
|
30
|
-
origin =
|
|
31
|
-
index.origin === 'constant' || index.origin === 'constant-immutable-def'
|
|
32
|
-
? 'constant'
|
|
33
|
-
: 'runtime';
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
// Fallthrough
|
|
37
|
-
origin = target.origin;
|
|
38
|
-
}
|
|
39
36
|
if (target.value instanceof ArrayExpression && isKnownAtComptime(index)) {
|
|
40
37
|
return target.value.elements[index.value];
|
|
41
38
|
}
|
|
39
|
+
const origin = deriveIndexAccessOrigin(target.origin, index.origin);
|
|
42
40
|
return snip(isKnownAtComptime(target) && isKnownAtComptime(index)
|
|
43
41
|
? // oxlint-disable-next-line typescript/no-explicit-any -- it's fine, it's there
|
|
44
42
|
target.value[index.value]
|
|
@@ -50,8 +48,7 @@ export function accessIndex(target, indexArg) {
|
|
|
50
48
|
return snip(isKnownAtComptime(target) && isKnownAtComptime(index)
|
|
51
49
|
? // oxlint-disable-next-line typescript/no-explicit-any -- it's fine, it's there
|
|
52
50
|
target.value[index.value]
|
|
53
|
-
: stitch `${target}[${index}]`, target.dataType.primitive,
|
|
54
|
-
/* origin */ target.origin, target.possibleSideEffects || index.possibleSideEffects);
|
|
51
|
+
: stitch `${target}[${index}]`, target.dataType.primitive, deriveIndexAccessOrigin(target.origin, index.origin), target.possibleSideEffects || index.possibleSideEffects);
|
|
55
52
|
}
|
|
56
53
|
if (isPtr(target.dataType)) {
|
|
57
54
|
// Sometimes values that are typed as pointers aren't instances of `d.ref`, so we
|
|
@@ -61,8 +58,7 @@ export function accessIndex(target, indexArg) {
|
|
|
61
58
|
// matrix.columns
|
|
62
59
|
if (target.value instanceof MatrixColumnsAccess) {
|
|
63
60
|
const propType = indexableTypeToResult[target.value.matrix.dataType.type];
|
|
64
|
-
return snip(stitch `${target.value.matrix}[${index}]`, propType,
|
|
65
|
-
/* origin */ target.origin, target.possibleSideEffects || index.possibleSideEffects);
|
|
61
|
+
return snip(stitch `${target.value.matrix}[${index}]`, propType, deriveIndexAccessOrigin(target.origin, index.origin), target.possibleSideEffects || index.possibleSideEffects);
|
|
66
62
|
}
|
|
67
63
|
// matrix
|
|
68
64
|
if (target.dataType.type in indexableTypeToResult) {
|
package/tgsl/conversion.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export type ConversionResult = {
|
|
|
16
16
|
export declare function getBestConversion(types: BaseData[], targetTypes?: BaseData[]): ConversionResult | undefined;
|
|
17
17
|
/**
|
|
18
18
|
* Unifies input types to a common type.
|
|
19
|
+
* Ties between equally good `restrictTo` candidates go to the one listed first.
|
|
19
20
|
*/
|
|
20
21
|
export declare function unify<T extends (BaseData | UnknownData)[] | []>(inTypes: T, restrictTo?: BaseData[]): {
|
|
21
22
|
[K in keyof T]: BaseData;
|
|
@@ -23,6 +24,7 @@ export declare function unify<T extends (BaseData | UnknownData)[] | []>(inTypes
|
|
|
23
24
|
/**
|
|
24
25
|
* Unifies input types to a common type.
|
|
25
26
|
* Unlike `unify`, it does not allow implicit conversions.
|
|
27
|
+
* Ties between equally good `restrictTo` candidates go to the one listed first.
|
|
26
28
|
*/
|
|
27
29
|
export declare function unifyStrict<T extends (BaseData | UnknownData)[] | []>(inTypes: T, restrictTo?: BaseData[]): {
|
|
28
30
|
[K in keyof T]: BaseData;
|
package/tgsl/conversion.js
CHANGED
|
@@ -131,6 +131,7 @@ function findBestType(types, uniqueTypes, allowImplicit) {
|
|
|
131
131
|
destType = conversion.targetType;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
+
// Ties keep the earlier candidate, so callers order their target types by preference.
|
|
134
135
|
if (sum < (bestResult?.sum ?? Number.POSITIVE_INFINITY)) {
|
|
135
136
|
bestResult = { type: destType, details, sum };
|
|
136
137
|
}
|
|
@@ -209,6 +210,7 @@ function applyActionToSnippet(ctx, snippet, action, targetType) {
|
|
|
209
210
|
}
|
|
210
211
|
/**
|
|
211
212
|
* Unifies input types to a common type.
|
|
213
|
+
* Ties between equally good `restrictTo` candidates go to the one listed first.
|
|
212
214
|
*/
|
|
213
215
|
export function unify(inTypes, restrictTo) {
|
|
214
216
|
if (inTypes.some((type) => type === UnknownData)) {
|
|
@@ -223,6 +225,7 @@ export function unify(inTypes, restrictTo) {
|
|
|
223
225
|
/**
|
|
224
226
|
* Unifies input types to a common type.
|
|
225
227
|
* Unlike `unify`, it does not allow implicit conversions.
|
|
228
|
+
* Ties between equally good `restrictTo` candidates go to the one listed first.
|
|
226
229
|
*/
|
|
227
230
|
export function unifyStrict(inTypes, restrictTo) {
|
|
228
231
|
if (inTypes.some((type) => type === UnknownData)) {
|
package/tgsl/forOfUtils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UnknownData } from "../data/dataTypes.js";
|
|
2
|
-
import {
|
|
2
|
+
import { isAddressableOrigin, isStoredInMemory, snip } from "../data/snippet.js";
|
|
3
3
|
import { stitch } from "../core/resolve/stitch.js";
|
|
4
4
|
import * as wgsl from "../data/wgslTypes.js";
|
|
5
5
|
import { i32, u32 } from "../data/numeric.js";
|
|
@@ -31,10 +31,7 @@ export function getElementType(elementSnippet, iterableSnippet) {
|
|
|
31
31
|
throw new WgslTypeError(stitch `The elements in iterable ${iterableSnippet} are of unknown type`);
|
|
32
32
|
}
|
|
33
33
|
if (wgsl.isNaturallyEphemeral(elementSnippet.dataType) ||
|
|
34
|
-
elementSnippet.origin
|
|
35
|
-
elementSnippet.origin === 'constant' ||
|
|
36
|
-
elementSnippet.origin === 'constant-immutable-def' ||
|
|
37
|
-
elementSnippet.origin === 'runtime-immutable-def') {
|
|
34
|
+
!isAddressableOrigin(elementSnippet.origin)) {
|
|
38
35
|
return elementType;
|
|
39
36
|
}
|
|
40
37
|
if (!wgsl.isPtr(elementType)) {
|
|
@@ -56,7 +53,10 @@ export function getRangeSnippets(ctx, iterableSnippet, unroll = false) {
|
|
|
56
53
|
comparison: step < 0 ? '>' : '<',
|
|
57
54
|
};
|
|
58
55
|
}
|
|
59
|
-
if (
|
|
56
|
+
if (iterableSnippet.possibleSideEffects) {
|
|
57
|
+
throw new Error('`for ... of ...` loops do not support iterables with possible side effects. Store the iterable in a variable first.');
|
|
58
|
+
}
|
|
59
|
+
if (!unroll && !isStoredInMemory(iterableSnippet)) {
|
|
60
60
|
throw new Error(`\`for ... of ...\` loops only support std.range or iterables stored in variables.
|
|
61
61
|
-----
|
|
62
62
|
You can wrap iterable with \`tgpu.unroll(...)\`. If iterable is known at comptime, the loop will be unrolled.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { UnknownData } from "../data/dataTypes.js";
|
|
2
2
|
import { abstractFloat, abstractInt, bool, f32, i32 } from "../data/numeric.js";
|
|
3
3
|
import { isRef } from "../data/ref.js";
|
|
4
|
-
import {
|
|
4
|
+
import { isStoredInMemory, isSnippet, snip, withDataType } from "../data/snippet.js";
|
|
5
5
|
import { isMatInstance, isNaturallyEphemeral, isVecInstance, WORKAROUND_getSchema, } from "../data/wgslTypes.js";
|
|
6
6
|
import { getOwnSnippet } from "../types.js";
|
|
7
7
|
import { WgslTypeError } from "../errors.js";
|
|
@@ -81,7 +81,7 @@ export class ArrayExpression {
|
|
|
81
81
|
[$resolve](ctx) {
|
|
82
82
|
for (const elem of this.elements) {
|
|
83
83
|
// We check if there are no references among the elements
|
|
84
|
-
if (
|
|
84
|
+
if (isStoredInMemory(elem) && !isNaturallyEphemeral(elem.dataType)) {
|
|
85
85
|
const snippetStr = ctx.resolveSnippet(elem).value;
|
|
86
86
|
const snippetType = ctx.resolve(concretize(elem.dataType)).value;
|
|
87
87
|
throw new WgslTypeError(`'${snippetStr}' reference cannot be used in an array constructor.\n-----\nTry '${snippetType}(${snippetStr})' or 'arrayOf(${snippetType}, count)([...])' to copy the value instead.\n-----`);
|
|
@@ -17,7 +17,7 @@ export interface ConstantDefinitionOptions {
|
|
|
17
17
|
readonly init: Snippet;
|
|
18
18
|
}
|
|
19
19
|
export interface VariableDefinitionOptions {
|
|
20
|
-
readonly scope: VariableScope | BindableBufferUsage | 'handle';
|
|
20
|
+
readonly scope: VariableScope | BindableBufferUsage | 'handle' | 'immediate';
|
|
21
21
|
readonly id: string;
|
|
22
22
|
readonly dataType: BaseData;
|
|
23
23
|
readonly init: Snippet | undefined;
|
package/tgsl/wgslGenerator.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export declare class WgslGenerator implements ShaderGenerator {
|
|
|
19
19
|
*/
|
|
20
20
|
protected _emitVarDecl(keyword: 'var' | 'let' | 'const' | `#VAR_${number}#`, name: string, _dataType: wgsl.BaseData, rhsStr: string): string;
|
|
21
21
|
protected _identifier(id: string): Snippet;
|
|
22
|
+
protected _emitSwitchStatement(discriminantExpr: Snippet, groupedCaseExprs: [tests: Snippet[], consequent: ResolvedStatement[]][]): string;
|
|
22
23
|
protected _callShellless(callee: AnyFn, args: readonly Snippet[]): ResolvedSnippet | undefined;
|
|
23
24
|
/**
|
|
24
25
|
* A wrapper for `generateExpression` that updates `ctx.expectedType`
|
|
@@ -51,6 +52,10 @@ export declare class WgslGenerator implements ShaderGenerator {
|
|
|
51
52
|
*/
|
|
52
53
|
protected _aliasConstStatement(rawId: string, eqNode: tinyest.Expression, eq: Snippet): ResolvedStatement;
|
|
53
54
|
protected _statement(statement: tinyest.Statement): ResolvedStatement;
|
|
55
|
+
/**
|
|
56
|
+
* Resolves the key of an object property. Handles both computed and non-computed keys.
|
|
57
|
+
*/
|
|
58
|
+
protected _resolveObjectPropertyKey(property: tinyest.ObjectProperty): string;
|
|
54
59
|
/**
|
|
55
60
|
* Attempts a member access lookup to mark a variable as modified.
|
|
56
61
|
* @example
|