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
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export function origin3d([x = 0, y = 0, z = 0] = []) {
|
|
2
|
+
return { x, y, z };
|
|
3
|
+
}
|
|
4
|
+
export function mipLevelSize({ size, dimension }, mipLevel) {
|
|
5
|
+
const scale = (value = 1) => Math.max(1, value >> mipLevel);
|
|
6
|
+
return [scale(size[0]), scale(size[1]), dimension === '3d' ? scale(size[2]) : (size[2] ?? 1)];
|
|
7
|
+
}
|
|
8
|
+
/** The size of the written region: `size`, or the rest of the mip level past `origin` */
|
|
9
|
+
export function writeRegionSize(texture, options) {
|
|
10
|
+
const [mipWidth, mipHeight] = mipLevelSize(texture, options.mipLevel ?? 0);
|
|
11
|
+
const [x = 0, y = 0] = options.origin ?? [];
|
|
12
|
+
const [width = mipWidth - x, height = mipHeight - y] = options.size ?? [];
|
|
13
|
+
return [width, height];
|
|
14
|
+
}
|
|
15
|
+
function imageSize(source) {
|
|
16
|
+
const { videoWidth, videoHeight } = source;
|
|
17
|
+
if (videoWidth && videoHeight) {
|
|
18
|
+
return [videoWidth, videoHeight];
|
|
19
|
+
}
|
|
20
|
+
const { naturalWidth, naturalHeight } = source;
|
|
21
|
+
if (naturalWidth && naturalHeight) {
|
|
22
|
+
return [naturalWidth, naturalHeight];
|
|
23
|
+
}
|
|
24
|
+
const { codedWidth, codedHeight } = source;
|
|
25
|
+
if (codedWidth && codedHeight) {
|
|
26
|
+
return [codedWidth, codedHeight];
|
|
27
|
+
}
|
|
28
|
+
const { width, height } = source;
|
|
29
|
+
if (width && height) {
|
|
30
|
+
return [width, height];
|
|
31
|
+
}
|
|
32
|
+
throw new Error('Cannot determine dimensions of the provided image source.');
|
|
33
|
+
}
|
|
34
|
+
export function sameSize(a, b) {
|
|
35
|
+
return a[0] === b[0] && a[1] === b[1];
|
|
36
|
+
}
|
|
37
|
+
export function resolveImageWrite(texture, source, options, layer = options.origin?.[2] ?? 0) {
|
|
38
|
+
const [x = 0, y = 0] = options.origin ?? [];
|
|
39
|
+
const [sourceX = 0, sourceY = 0] = options.sourceOrigin ?? [];
|
|
40
|
+
const [imageWidth, imageHeight] = imageSize(source);
|
|
41
|
+
const [sourceWidth = imageWidth - sourceX, sourceHeight = imageHeight - sourceY] = options.sourceSize ?? [];
|
|
42
|
+
let sourceSize = [sourceWidth, sourceHeight];
|
|
43
|
+
let size = writeRegionSize(texture, options);
|
|
44
|
+
if (options.fit === 'clip') {
|
|
45
|
+
sourceSize = size = [Math.min(sourceSize[0], size[0]), Math.min(sourceSize[1], size[1])];
|
|
46
|
+
}
|
|
47
|
+
else if (options.fit !== 'stretch' && !sameSize(sourceSize, size)) {
|
|
48
|
+
throw new Error(`Texture write source size ${sourceSize.join('x')} does not match target size ${size.join('x')}. Pass fit: 'stretch' to scale the source or fit: 'clip' to copy the overlapping region.`);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
source,
|
|
52
|
+
sourceOrigin: { x: sourceX, y: sourceY },
|
|
53
|
+
sourceSize,
|
|
54
|
+
origin: { x, y, z: layer },
|
|
55
|
+
size,
|
|
56
|
+
mipLevel: options.mipLevel ?? 0,
|
|
57
|
+
options,
|
|
58
|
+
};
|
|
59
|
+
}
|
package/data/autoStruct.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare class AutoStruct implements BaseData, SelfResolvable {
|
|
|
12
12
|
[$internal]: Record<string, never>;
|
|
13
13
|
type: 'auto-struct';
|
|
14
14
|
readonly [$repr]: Record<string, unknown>;
|
|
15
|
-
constructor(validProps: Record<string, BaseData>, typeForExtraProps: BaseData | undefined, locations?: Record<string, number
|
|
15
|
+
constructor(validProps: Record<string, BaseData>, typeForExtraProps: BaseData | undefined, locations?: Record<string, number>, autoInterpolateIntegers?: boolean);
|
|
16
16
|
/**
|
|
17
17
|
* Used for accessing builtins, varying and attributes in code.
|
|
18
18
|
*/
|
package/data/autoStruct.js
CHANGED
|
@@ -22,11 +22,17 @@ export class AutoStruct {
|
|
|
22
22
|
#locations;
|
|
23
23
|
#cachedStruct;
|
|
24
24
|
#typeForExtraProps;
|
|
25
|
-
|
|
25
|
+
#autoInterpolateIntegers;
|
|
26
|
+
static {
|
|
27
|
+
AutoStruct.prototype[$internal] = {};
|
|
28
|
+
AutoStruct.prototype.type = 'auto-struct';
|
|
29
|
+
}
|
|
30
|
+
constructor(validProps, typeForExtraProps, locations, autoInterpolateIntegers = false) {
|
|
26
31
|
this.#validProps = validProps;
|
|
27
32
|
this.#typeForExtraProps = typeForExtraProps;
|
|
28
33
|
this.#allocated = {};
|
|
29
34
|
this.#locations = locations;
|
|
35
|
+
this.#autoInterpolateIntegers = autoInterpolateIntegers;
|
|
30
36
|
this.#usedWgslKeys = new Set();
|
|
31
37
|
}
|
|
32
38
|
/**
|
|
@@ -67,7 +73,7 @@ export class AutoStruct {
|
|
|
67
73
|
if (!this.#cachedStruct) {
|
|
68
74
|
this.#cachedStruct = createIoSchema(Object.fromEntries(Object.values(this.#allocated).map((alloc) => {
|
|
69
75
|
return [alloc.prop, alloc.type];
|
|
70
|
-
})), this.#locations);
|
|
76
|
+
})), this.#locations, this.#autoInterpolateIntegers);
|
|
71
77
|
const ownName = getName(this);
|
|
72
78
|
// Passing the given name forward
|
|
73
79
|
if (ownName) {
|
|
@@ -83,5 +89,3 @@ export class AutoStruct {
|
|
|
83
89
|
return `auto-struct:${getName(this) ?? '<unnamed>'}`;
|
|
84
90
|
}
|
|
85
91
|
}
|
|
86
|
-
AutoStruct.prototype[$internal] = {};
|
|
87
|
-
AutoStruct.prototype.type = 'auto-struct';
|
package/data/dataIO.d.ts
CHANGED
|
@@ -5,9 +5,9 @@ import { type BaseData } from './wgslTypes.ts';
|
|
|
5
5
|
import type { BufferWriteOptions } from '../core/buffer/buffer.ts';
|
|
6
6
|
export declare function writeData<TData extends wgsl.BaseData>(output: ISerialOutput, schema: TData, value: Infer<TData>): void;
|
|
7
7
|
export declare function readData<TData extends wgsl.BaseData>(input: ISerialInput, schema: TData): Infer<TData>;
|
|
8
|
-
export declare function calculateOffsets<T extends BaseData>(options: BufferWriteOptions | undefined, schema: T, data: InferInput<T> | ArrayBuffer): {
|
|
8
|
+
export declare function calculateOffsets<T extends BaseData>(options: BufferWriteOptions | undefined, schema: T, data: InferInput<T> | ArrayBuffer | ArrayBufferView): {
|
|
9
9
|
startOffset: number;
|
|
10
10
|
endOffset: number;
|
|
11
11
|
};
|
|
12
|
-
export declare function writeToArrayBuffer<T extends BaseData>(buffer: ArrayBuffer, schema: T, data: InferInput<T> | ArrayBuffer, options?: BufferWriteOptions): void;
|
|
12
|
+
export declare function writeToArrayBuffer<T extends BaseData>(buffer: ArrayBuffer, schema: T, data: InferInput<T> | ArrayBuffer | ArrayBufferView, options?: BufferWriteOptions): void;
|
|
13
13
|
export declare function readFromArrayBuffer<T extends BaseData>(buffer: ArrayBuffer, schema: T): Infer<T>;
|
package/data/deepEqual.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isDisarray, isLooseDecorated, isUnstruct } from "./dataTypes.js";
|
|
2
|
+
import { isWgslStorageTexture, isWgslTexture } from "./texture.js";
|
|
2
3
|
import { isAtomic, isDecorated, isPtr, isWgslArray, isWgslStruct } from "./wgslTypes.js";
|
|
3
4
|
/**
|
|
4
5
|
* Performs a deep comparison of two TypeGPU data schemas.
|
|
@@ -53,11 +54,20 @@ export function deepEqual(a, b) {
|
|
|
53
54
|
if (isPtr(a) && isPtr(b)) {
|
|
54
55
|
return (a.addressSpace === b.addressSpace &&
|
|
55
56
|
a.access === b.access &&
|
|
57
|
+
a.implicit === b.implicit &&
|
|
56
58
|
deepEqual(a.inner, b.inner));
|
|
57
59
|
}
|
|
58
60
|
if (isAtomic(a) && isAtomic(b)) {
|
|
59
61
|
return deepEqual(a.inner, b.inner);
|
|
60
62
|
}
|
|
63
|
+
if (isWgslTexture(a) && isWgslTexture(b)) {
|
|
64
|
+
// Dimension and multisampling are already encoded in the type
|
|
65
|
+
return deepEqual(a.sampleType, b.sampleType);
|
|
66
|
+
}
|
|
67
|
+
if (isWgslStorageTexture(a) && isWgslStorageTexture(b)) {
|
|
68
|
+
// Dimension is already encoded in the type
|
|
69
|
+
return a.format === b.format && a.access === b.access;
|
|
70
|
+
}
|
|
61
71
|
if ((isDecorated(a) && isDecorated(b)) || (isLooseDecorated(a) && isLooseDecorated(b))) {
|
|
62
72
|
if (!deepEqual(a.inner, b.inner)) {
|
|
63
73
|
return false;
|
|
@@ -65,18 +75,18 @@ export function deepEqual(a, b) {
|
|
|
65
75
|
if (a.attribs.length !== b.attribs.length) {
|
|
66
76
|
return false;
|
|
67
77
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (attrsA[i] !== attrsB[i]) {
|
|
78
|
+
for (let i = 0; i < a.attribs.length; i++) {
|
|
79
|
+
const attrA = a.attribs[i];
|
|
80
|
+
const attrB = b.attribs[i];
|
|
81
|
+
const paramsA = attrA.params ?? [];
|
|
82
|
+
const paramsB = attrB.params ?? [];
|
|
83
|
+
if (attrA.type !== attrB.type ||
|
|
84
|
+
paramsA.length !== paramsB.length ||
|
|
85
|
+
paramsA.some((param, idx) => param !== paramsB[idx])) {
|
|
77
86
|
return false;
|
|
78
87
|
}
|
|
79
88
|
}
|
|
89
|
+
return true;
|
|
80
90
|
}
|
|
81
91
|
// All other types have been checked for equality at the start
|
|
82
92
|
return true;
|
package/data/matrix.js
CHANGED
|
@@ -8,7 +8,7 @@ import { numericLiteralToSnippet } from "../tgsl/generationHelpers.js";
|
|
|
8
8
|
import { f32 } from "./numeric.js";
|
|
9
9
|
import {} from "./snippet.js";
|
|
10
10
|
import { vec2f, vec3f, vec4f } from "./vector.js";
|
|
11
|
-
import { isVec, } from "./wgslTypes.js";
|
|
11
|
+
import { isMat, isMatInstance, isVec, } from "./wgslTypes.js";
|
|
12
12
|
export class MatBase {
|
|
13
13
|
}
|
|
14
14
|
function createMatSchema(options) {
|
|
@@ -18,7 +18,14 @@ function createMatSchema(options) {
|
|
|
18
18
|
normalImpl: (...args) => {
|
|
19
19
|
const elements = [];
|
|
20
20
|
for (const arg of args) {
|
|
21
|
-
if (
|
|
21
|
+
if (isMatInstance(arg)) {
|
|
22
|
+
for (const column of arg.columns) {
|
|
23
|
+
for (const elem of column) {
|
|
24
|
+
elements.push(elem);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else if (typeof arg === 'number') {
|
|
22
29
|
elements.push(arg);
|
|
23
30
|
}
|
|
24
31
|
else {
|
|
@@ -35,7 +42,7 @@ function createMatSchema(options) {
|
|
|
35
42
|
}
|
|
36
43
|
return new options.MatImpl(...elements);
|
|
37
44
|
},
|
|
38
|
-
argTypes: (...args) => args.map((arg) => (isVec(arg) ? arg : f32)),
|
|
45
|
+
argTypes: (...args) => args.map((arg) => (isVec(arg) || isMat(arg) ? arg : f32)),
|
|
39
46
|
codegenImpl: (ctx, args) => ctx.gen.typeInstantiation(schema, args),
|
|
40
47
|
});
|
|
41
48
|
const schema = Object.assign(construct, {
|
package/data/partialIO.d.ts
CHANGED
|
@@ -4,10 +4,17 @@ import type { InferPatch } from '../shared/repr.ts';
|
|
|
4
4
|
export interface WriteInstruction {
|
|
5
5
|
data: Uint8Array<ArrayBuffer>;
|
|
6
6
|
gpuOffset: number;
|
|
7
|
+
/** How many bytes to upload. Can be larger than `data`, e.g. to cover trailing padding. */
|
|
8
|
+
uploadSize: number;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
11
|
* Converts `{idx, value}[]` sparse arrays into `Record<number, T>` format.
|
|
10
12
|
*/
|
|
11
13
|
export declare function convertPartialToPatch(schema: wgsl.BaseData, data: unknown): unknown;
|
|
12
|
-
|
|
14
|
+
/**
|
|
15
|
+
* @param validateRange Called for every byte range that is about to be written, before any data
|
|
16
|
+
* is written into `targetBuffer`. Returns how many bytes to upload for that range.
|
|
17
|
+
* Throwing from it leaves `targetBuffer` untouched.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getPatchInstructions<TData extends wgsl.BaseData>(schema: TData, data: unknown, targetBuffer?: ArrayBuffer, validateRange?: (start: number, end: number) => number): WriteInstruction[];
|
|
13
20
|
export declare function patchArrayBuffer<T extends BaseData>(buffer: ArrayBuffer, schema: T, data: InferPatch<T>): void;
|
package/data/partialIO.js
CHANGED
|
@@ -37,7 +37,12 @@ export function convertPartialToPatch(schema, data) {
|
|
|
37
37
|
return data;
|
|
38
38
|
}
|
|
39
39
|
const isLittleEndian = getSystemEndianness() === 'little';
|
|
40
|
-
|
|
40
|
+
/**
|
|
41
|
+
* @param validateRange Called for every byte range that is about to be written, before any data
|
|
42
|
+
* is written into `targetBuffer`. Returns how many bytes to upload for that range.
|
|
43
|
+
* Throwing from it leaves `targetBuffer` untouched.
|
|
44
|
+
*/
|
|
45
|
+
export function getPatchInstructions(schema, data, targetBuffer, validateRange) {
|
|
41
46
|
const totalSize = sizeOf(schema);
|
|
42
47
|
if (totalSize === 0 || data === undefined || data === null) {
|
|
43
48
|
return [];
|
|
@@ -46,6 +51,8 @@ export function getPatchInstructions(schema, data, targetBuffer) {
|
|
|
46
51
|
const writer = new BufferWriter(buf);
|
|
47
52
|
const compiledView = new DataView(buf);
|
|
48
53
|
const segments = [];
|
|
54
|
+
// Deferred until every range is validated
|
|
55
|
+
const pendingWrites = [];
|
|
49
56
|
function collect(node, value, offset, padding) {
|
|
50
57
|
if (value === undefined || value === null) {
|
|
51
58
|
return;
|
|
@@ -67,7 +74,9 @@ export function getPatchInstructions(schema, data, targetBuffer) {
|
|
|
67
74
|
const elementPadding = elementSize - sizeOf(arrSchema.elementType);
|
|
68
75
|
if (ArrayBuffer.isView(value)) {
|
|
69
76
|
const copyLen = Math.min(value.byteLength, arrSchema.elementCount * elementSize);
|
|
70
|
-
|
|
77
|
+
pendingWrites.push(() => {
|
|
78
|
+
new Uint8Array(buf, offset, copyLen).set(new Uint8Array(value.buffer, value.byteOffset, copyLen));
|
|
79
|
+
});
|
|
71
80
|
segments.push({ start: offset, end: offset + copyLen, padding });
|
|
72
81
|
return;
|
|
73
82
|
}
|
|
@@ -88,17 +97,19 @@ export function getPatchInstructions(schema, data, targetBuffer) {
|
|
|
88
97
|
}
|
|
89
98
|
const leafSize = sizeOf(node);
|
|
90
99
|
const compiledWriter = getCompiledWriter(node);
|
|
91
|
-
|
|
92
|
-
compiledWriter
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
pendingWrites.push(() => {
|
|
101
|
+
if (compiledWriter) {
|
|
102
|
+
compiledWriter(compiledView, offset, value, isLittleEndian, offset + leafSize);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
writer.seekTo(offset);
|
|
106
|
+
writeData(writer, node, value);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
98
109
|
segments.push({ start: offset, end: offset + leafSize, padding });
|
|
99
110
|
}
|
|
100
111
|
collect(schema, data, 0);
|
|
101
|
-
const
|
|
112
|
+
const runs = [];
|
|
102
113
|
let run = null;
|
|
103
114
|
for (const seg of segments) {
|
|
104
115
|
if (run && seg.start === run.end + (run.padding ?? 0)) {
|
|
@@ -106,21 +117,27 @@ export function getPatchInstructions(schema, data, targetBuffer) {
|
|
|
106
117
|
}
|
|
107
118
|
else {
|
|
108
119
|
if (run) {
|
|
109
|
-
|
|
110
|
-
gpuOffset: run.start,
|
|
111
|
-
data: new Uint8Array(buf, run.start, run.end - run.start).slice(),
|
|
112
|
-
});
|
|
120
|
+
runs.push(run);
|
|
113
121
|
}
|
|
114
122
|
run = seg;
|
|
115
123
|
}
|
|
116
124
|
}
|
|
117
125
|
if (run) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
126
|
+
runs.push(run);
|
|
127
|
+
}
|
|
128
|
+
const uploads = runs.map(({ start, end }) => ({
|
|
129
|
+
start,
|
|
130
|
+
end,
|
|
131
|
+
uploadSize: validateRange?.(start, end) ?? end - start,
|
|
132
|
+
}));
|
|
133
|
+
for (const write of pendingWrites) {
|
|
134
|
+
write();
|
|
122
135
|
}
|
|
123
|
-
return
|
|
136
|
+
return uploads.map(({ start, end, uploadSize }) => ({
|
|
137
|
+
gpuOffset: start,
|
|
138
|
+
data: new Uint8Array(buf, start, end - start).slice(),
|
|
139
|
+
uploadSize,
|
|
140
|
+
}));
|
|
124
141
|
}
|
|
125
142
|
export function patchArrayBuffer(buffer, schema, data) {
|
|
126
143
|
const instructions = getPatchInstructions(schema, data, buffer);
|
package/data/ref.js
CHANGED
|
@@ -4,7 +4,7 @@ import { setName } from "../shared/meta.js";
|
|
|
4
4
|
import { $gpuCallable, $internal, $ownSnippet, $resolve } from "../shared/symbols.js";
|
|
5
5
|
import { UnknownData } from "./dataTypes.js";
|
|
6
6
|
import { createPtrFromOrigin, explicitFrom } from "./ptr.js";
|
|
7
|
-
import {
|
|
7
|
+
import { isStoredInMemory, snip, withDataType, } from "./snippet.js";
|
|
8
8
|
import { isNaturallyEphemeral, isPtr } from "./wgslTypes.js";
|
|
9
9
|
export const _ref = (() => {
|
|
10
10
|
const impl = ((value) => INTERNAL_createRef(value));
|
|
@@ -23,7 +23,7 @@ export const _ref = (() => {
|
|
|
23
23
|
- Try 'd.ref(${typeStr}(${value}));' instead to create a new referencable value.
|
|
24
24
|
-----`);
|
|
25
25
|
}
|
|
26
|
-
if (
|
|
26
|
+
if (isStoredInMemory(value) && isNaturallyEphemeral(value.dataType)) {
|
|
27
27
|
const typeStr = ctx.resolve(value.dataType).value;
|
|
28
28
|
throw new WgslTypeError(stitch `d.ref(${value}) is illegal, cannot take a reference to a scalar value.
|
|
29
29
|
-----
|
package/data/snippet.d.ts
CHANGED
|
@@ -1,36 +1,41 @@
|
|
|
1
1
|
import type { UnknownData } from './dataTypes.ts';
|
|
2
2
|
import { type BaseData } from './wgslTypes.ts';
|
|
3
|
-
export type Origin = 'uniform' | 'readonly' | 'mutable' | 'workgroup' | 'private' | 'handle' | 'function' | 'local-def' | 'constant-immutable-def' | 'runtime-immutable-def' | 'argument' | 'runtime' | 'constant';
|
|
3
|
+
export type Origin = 'uniform' | 'readonly' | 'mutable' | 'workgroup' | 'private' | 'handle' | 'immediate' | 'function' | 'local-def' | 'constant-immutable-def' | 'runtime-immutable-def' | 'argument' | 'runtime' | 'constant';
|
|
4
4
|
/**
|
|
5
5
|
* What happens to a snippet's origin when it's deep copied in JS, and left as is in WGSL?
|
|
6
6
|
* e.g. `vec3f(vec3f(0, 1, 2))`
|
|
7
7
|
*/
|
|
8
8
|
export declare function fallthroughCopyOrigin(origin: Origin): Origin;
|
|
9
9
|
/**
|
|
10
|
-
* Whether a snippet
|
|
10
|
+
* Whether a snippet refers to a value already stored in memory.
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```ts
|
|
14
14
|
* function foo(a: number) {
|
|
15
|
+
* 'use gpu';
|
|
15
16
|
* const color = d.vec3f(1, 2, 3);
|
|
16
17
|
* return color * a;
|
|
17
18
|
* }
|
|
18
19
|
*
|
|
19
|
-
* //
|
|
20
|
+
* // Stored in memory:
|
|
20
21
|
* // - color
|
|
21
22
|
* // - a
|
|
22
23
|
* //
|
|
23
|
-
* //
|
|
24
|
+
* // Ephemeral values:
|
|
24
25
|
* // - d.vec3f(1, 2, 3)
|
|
25
26
|
* // - color * a
|
|
26
27
|
* ```
|
|
27
28
|
*/
|
|
28
|
-
export declare function
|
|
29
|
+
export declare function isStoredInMemory(snippet: Snippet): boolean;
|
|
29
30
|
export declare const originToPtrParams: {
|
|
30
31
|
readonly uniform: {
|
|
31
32
|
readonly space: "uniform";
|
|
32
33
|
readonly access: "read";
|
|
33
34
|
};
|
|
35
|
+
readonly immediate: {
|
|
36
|
+
readonly space: "immediate";
|
|
37
|
+
readonly access: "read";
|
|
38
|
+
};
|
|
34
39
|
readonly readonly: {
|
|
35
40
|
readonly space: "storage";
|
|
36
41
|
readonly access: "read";
|
|
@@ -57,6 +62,7 @@ export declare const originToPtrParams: {
|
|
|
57
62
|
};
|
|
58
63
|
};
|
|
59
64
|
export type OriginToPtrParams = typeof originToPtrParams;
|
|
65
|
+
export declare function isAddressableOrigin(origin: Origin): origin is keyof OriginToPtrParams;
|
|
60
66
|
export interface Snippet {
|
|
61
67
|
readonly value: unknown;
|
|
62
68
|
/**
|
package/data/snippet.js
CHANGED
|
@@ -16,29 +16,31 @@ export function fallthroughCopyOrigin(origin) {
|
|
|
16
16
|
return 'runtime';
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
|
-
* Whether a snippet
|
|
19
|
+
* Whether a snippet refers to a value already stored in memory.
|
|
20
20
|
*
|
|
21
21
|
* @example
|
|
22
22
|
* ```ts
|
|
23
23
|
* function foo(a: number) {
|
|
24
|
+
* 'use gpu';
|
|
24
25
|
* const color = d.vec3f(1, 2, 3);
|
|
25
26
|
* return color * a;
|
|
26
27
|
* }
|
|
27
28
|
*
|
|
28
|
-
* //
|
|
29
|
+
* // Stored in memory:
|
|
29
30
|
* // - color
|
|
30
31
|
* // - a
|
|
31
32
|
* //
|
|
32
|
-
* //
|
|
33
|
+
* // Ephemeral values:
|
|
33
34
|
* // - d.vec3f(1, 2, 3)
|
|
34
35
|
* // - color * a
|
|
35
36
|
* ```
|
|
36
37
|
*/
|
|
37
|
-
export function
|
|
38
|
+
export function isStoredInMemory(snippet) {
|
|
38
39
|
return !(snippet.origin === 'runtime' || snippet.origin === 'constant');
|
|
39
40
|
}
|
|
40
41
|
export const originToPtrParams = {
|
|
41
42
|
uniform: { space: 'uniform', access: 'read' },
|
|
43
|
+
immediate: { space: 'immediate', access: 'read' },
|
|
42
44
|
readonly: { space: 'storage', access: 'read' },
|
|
43
45
|
mutable: { space: 'storage', access: 'read-write' },
|
|
44
46
|
workgroup: { space: 'workgroup', access: 'read-write' },
|
|
@@ -47,6 +49,9 @@ export const originToPtrParams = {
|
|
|
47
49
|
// Local declarations are also in the `function` address space
|
|
48
50
|
'local-def': { space: 'function', access: 'read-write' },
|
|
49
51
|
};
|
|
52
|
+
export function isAddressableOrigin(origin) {
|
|
53
|
+
return origin in originToPtrParams;
|
|
54
|
+
}
|
|
50
55
|
class SnippetImpl {
|
|
51
56
|
value;
|
|
52
57
|
dataType;
|
package/data/wgslTypes.d.ts
CHANGED
|
@@ -709,6 +709,7 @@ export interface Mat2x2f extends BaseData {
|
|
|
709
709
|
readonly [$validUniformSchema]: true;
|
|
710
710
|
(...elements: [number, number, number, number]): m2x2f;
|
|
711
711
|
(...columns: [v2f, v2f]): m2x2f;
|
|
712
|
+
(other: m2x2f): m2x2f;
|
|
712
713
|
(): m2x2f;
|
|
713
714
|
identity(): m2x2f;
|
|
714
715
|
}
|
|
@@ -724,6 +725,7 @@ export interface Mat3x3f extends BaseData {
|
|
|
724
725
|
readonly [$validUniformSchema]: true;
|
|
725
726
|
(...elements: [number, number, number, number, number, number, number, number, number]): m3x3f;
|
|
726
727
|
(...columns: [v3f, v3f, v3f]): m3x3f;
|
|
728
|
+
(other: m3x3f): m3x3f;
|
|
727
729
|
(): m3x3f;
|
|
728
730
|
identity(): m3x3f;
|
|
729
731
|
}
|
|
@@ -739,6 +741,7 @@ export interface Mat4x4f extends BaseData {
|
|
|
739
741
|
readonly [$validUniformSchema]: true;
|
|
740
742
|
(...elements: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]): m4x4f;
|
|
741
743
|
(...columns: [v4f, v4f, v4f, v4f]): m4x4f;
|
|
744
|
+
(other: m4x4f): m4x4f;
|
|
742
745
|
(): m4x4f;
|
|
743
746
|
identity(): m4x4f;
|
|
744
747
|
translation(vec: v3f): m4x4f;
|
|
@@ -810,7 +813,7 @@ export interface WgslStruct<out TProps extends Record<string, BaseData> = Record
|
|
|
810
813
|
}
|
|
811
814
|
/** @deprecated Just use `WgslStruct` without any type parameters */
|
|
812
815
|
export type AnyWgslStruct = WgslStruct;
|
|
813
|
-
export type AddressSpace = 'uniform' | 'storage' | 'workgroup' | 'private' | 'function' | 'handle';
|
|
816
|
+
export type AddressSpace = 'uniform' | 'storage' | 'workgroup' | 'private' | 'function' | 'handle' | 'immediate';
|
|
814
817
|
export type Access = 'read' | 'write' | 'read-write';
|
|
815
818
|
export interface Ptr<TAddr extends AddressSpace = AddressSpace, TInner extends BaseData = BaseData, TAccess extends Access = Access> extends BaseData {
|
|
816
819
|
readonly type: 'ptr';
|
package/errors.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { TgpuSlot } from './core/slot/slotTypes.ts';
|
|
|
3
3
|
import type { TgpuVertexLayout } from './core/vertexLayout/vertexLayout.ts';
|
|
4
4
|
import type { BaseData } from './data/wgslTypes.ts';
|
|
5
5
|
import type { TgpuBindGroupLayout } from './tgpuBindGroupLayout.ts';
|
|
6
|
+
import type * as tinyest from 'tinyest';
|
|
6
7
|
/**
|
|
7
8
|
* Inspired by: https://github.com/alexreardon/tiny-invariant/blob/master/src/tiny-invariant.ts
|
|
8
9
|
*/
|
|
@@ -51,6 +52,9 @@ export declare class MissingBindGroupsError extends Error {
|
|
|
51
52
|
export declare class MissingVertexBuffersError extends Error {
|
|
52
53
|
constructor(layouts: Iterable<TgpuVertexLayout>);
|
|
53
54
|
}
|
|
55
|
+
export declare class MissingImmediatesError extends Error {
|
|
56
|
+
constructor(name: string | undefined);
|
|
57
|
+
}
|
|
54
58
|
export declare class IllegalVarAccessError extends Error {
|
|
55
59
|
constructor(msg: string);
|
|
56
60
|
}
|
|
@@ -60,6 +64,9 @@ export declare class IllegalBufferAccessError extends Error {
|
|
|
60
64
|
export declare class WgslTypeError extends Error {
|
|
61
65
|
constructor(msg: string);
|
|
62
66
|
}
|
|
67
|
+
export declare class WgslForbiddenStatementError extends Error {
|
|
68
|
+
constructor(node: tinyest.AnyNode);
|
|
69
|
+
}
|
|
63
70
|
export declare class SignatureNotSupportedError extends Error {
|
|
64
71
|
constructor(actual: BaseData[], candidates: BaseData[]);
|
|
65
72
|
}
|
package/errors.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getName, hasTinyestMetadata } from "./shared/meta.js";
|
|
2
2
|
import { DEV, TEST } from "./shared/env.js";
|
|
3
|
+
import { stringifyNode } from "./shared/tseynit.js";
|
|
3
4
|
const prefix = 'Invariant failed';
|
|
4
5
|
/**
|
|
5
6
|
* Inspired by: https://github.com/alexreardon/tiny-invariant/blob/master/src/tiny-invariant.ts
|
|
@@ -115,6 +116,13 @@ export class MissingVertexBuffersError extends Error {
|
|
|
115
116
|
Object.setPrototypeOf(this, MissingVertexBuffersError.prototype);
|
|
116
117
|
}
|
|
117
118
|
}
|
|
119
|
+
export class MissingImmediatesError extends Error {
|
|
120
|
+
constructor(name) {
|
|
121
|
+
super(`Missing value for immediate variable '${name ?? '<unnamed>'}'. Please provide it using pipeline.with(immediate, value), pass.setImmediates(immediate, value), or give the variable a default value`);
|
|
122
|
+
// Set the prototype explicitly.
|
|
123
|
+
Object.setPrototypeOf(this, MissingImmediatesError.prototype);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
118
126
|
export class IllegalVarAccessError extends Error {
|
|
119
127
|
constructor(msg) {
|
|
120
128
|
super(msg);
|
|
@@ -136,6 +144,13 @@ export class WgslTypeError extends Error {
|
|
|
136
144
|
Object.setPrototypeOf(this, WgslTypeError.prototype);
|
|
137
145
|
}
|
|
138
146
|
}
|
|
147
|
+
export class WgslForbiddenStatementError extends Error {
|
|
148
|
+
constructor(node) {
|
|
149
|
+
super(`Expression statements like '${stringifyNode(node)};' are forbidden in WGSL. Remove the statement, or use the result in code (for example, assign it to a variable).`);
|
|
150
|
+
// Set the prototype explicitly.
|
|
151
|
+
Object.setPrototypeOf(this, WgslForbiddenStatementError.prototype);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
139
154
|
export class SignatureNotSupportedError extends Error {
|
|
140
155
|
constructor(actual, candidates) {
|
|
141
156
|
super(`Unsupported data types: ${actual
|
package/indexNamedExports.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * as d from './data/index.ts';
|
|
2
2
|
export * as std from './std/index.ts';
|
|
3
3
|
export * as common from './common/index.ts';
|
|
4
|
-
export { MissingBindGroupsError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError, } from './errors.ts';
|
|
4
|
+
export { MissingBindGroupsError, MissingImmediatesError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError, } from './errors.ts';
|
|
5
5
|
export { isAccessor, isLazy, isMutableAccessor, isSlot } from './core/slot/slotTypes.ts';
|
|
6
6
|
export { isComparisonSampler, isSampler } from './core/sampler/sampler.ts';
|
|
7
7
|
export { isTexture } from './core/texture/texture.ts';
|
|
@@ -17,6 +17,7 @@ export { isComputePipeline, isPipeline, isRenderPipeline } from './core/pipeline
|
|
|
17
17
|
export { isQuerySet } from './core/querySet/querySet.ts';
|
|
18
18
|
export { isVariable } from './core/variable/tgpuVariable.ts';
|
|
19
19
|
export { isVertexLayout } from './core/vertexLayout/vertexLayout.ts';
|
|
20
|
+
export { isImmediateVar } from './core/immediate/immediateVar.ts';
|
|
20
21
|
export type {
|
|
21
22
|
/** @deprecated Import from 'typegpu/~internal' instead */ ShaderGenerator, } from './tgsl/shaderGenerator.ts';
|
|
22
23
|
export {
|
|
@@ -40,12 +41,14 @@ export type { TgpuBufferMutable, TgpuBufferReadonly, TgpuBufferUniform, } from '
|
|
|
40
41
|
export type { TgpuBufferBinding, TgpuMutable, TgpuReadonly, TgpuUniform, } from './core/buffer/bufferBinding.ts';
|
|
41
42
|
export type { Eventual, TgpuAccessor, TgpuLazy, TgpuMutableAccessor, TgpuSlot, } from './core/slot/slotTypes.ts';
|
|
42
43
|
export type { RawCodeSnippetOrigin, TgpuRawCodeSnippet, } from './core/rawCodeSnippet/tgpuRawCodeSnippet.ts';
|
|
43
|
-
export type {
|
|
44
|
+
export type { TgpuTexture, TgpuTextureView } from './core/texture/texture.ts';
|
|
45
|
+
export type { TextureBlobWriteOptions, TextureChannel, TextureCopyOptions, TextureRawWriteOptions, TextureWriteFit, TextureWriteOptions, } from './core/texture/textureWrite.ts';
|
|
44
46
|
export type { TextureProps } from './core/texture/textureProps.ts';
|
|
45
47
|
export type { RenderFlag, SampledFlag } from './core/texture/usageExtension.ts';
|
|
46
48
|
export type { InitFromDeviceOptions, InitOptions } from './core/root/init.ts';
|
|
47
49
|
export type { TgpuConst } from './core/constant/tgpuConstant.ts';
|
|
48
50
|
export type { TgpuVar, VariableScope } from './core/variable/tgpuVariable.ts';
|
|
51
|
+
export type { TgpuImmediateVar } from './core/immediate/immediateVar.ts';
|
|
49
52
|
export type { TgpuComparisonSampler, TgpuFixedComparisonSampler, TgpuFixedSampler, TgpuSampler, } from './core/sampler/sampler.ts';
|
|
50
53
|
export type { TgpuQuerySet } from './core/querySet/querySet.ts';
|
|
51
54
|
export type { ExtractBindGroupInputFromLayout, LayoutEntryToInput, TgpuBindGroup, TgpuBindGroupLayout, TgpuLayoutComparisonSampler, TgpuLayoutEntry, TgpuLayoutExternalTexture, TgpuLayoutSampler, TgpuLayoutStorage, TgpuLayoutTexture, TgpuLayoutUniform, } from './tgpuBindGroupLayout.ts';
|
package/indexNamedExports.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export * as d from "./data/index.js";
|
|
3
3
|
export * as std from "./std/index.js";
|
|
4
4
|
export * as common from "./common/index.js";
|
|
5
|
-
export { MissingBindGroupsError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError, } from "./errors.js";
|
|
5
|
+
export { MissingBindGroupsError, MissingImmediatesError, MissingSlotValueError, MissingVertexBuffersError, NotUniformError, ResolutionError, } from "./errors.js";
|
|
6
6
|
export { isAccessor, isLazy, isMutableAccessor, isSlot } from "./core/slot/slotTypes.js";
|
|
7
7
|
export { isComparisonSampler, isSampler } from "./core/sampler/sampler.js";
|
|
8
8
|
export { isTexture } from "./core/texture/texture.js";
|
|
@@ -18,6 +18,7 @@ export { isComputePipeline, isPipeline, isRenderPipeline } from "./core/pipeline
|
|
|
18
18
|
export { isQuerySet } from "./core/querySet/querySet.js";
|
|
19
19
|
export { isVariable } from "./core/variable/tgpuVariable.js";
|
|
20
20
|
export { isVertexLayout } from "./core/vertexLayout/vertexLayout.js";
|
|
21
|
+
export { isImmediateVar } from "./core/immediate/immediateVar.js";
|
|
21
22
|
export {
|
|
22
23
|
/** @deprecated Import from 'typegpu/~internal' instead */ WgslGenerator, } from "./tgsl/wgslGenerator.js";
|
|
23
24
|
export { readFromArrayBuffer, writeToArrayBuffer } from "./data/dataIO.js";
|
package/internal.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { UnknownData } from './data/dataTypes.ts';
|
|
|
5
5
|
export { getName, setName } from './shared/meta.ts';
|
|
6
6
|
export { WgslGenerator } from './tgsl/wgslGenerator.ts';
|
|
7
7
|
export { snip, withValue, withDataType, withSideEffects } from './data/snippet.ts';
|
|
8
|
-
export { stringifyNode } from './shared/tseynit.ts';
|
|
8
|
+
export { stringifyNode, stringifyObjectProperty } from './shared/tseynit.ts';
|
|
9
9
|
export { dualImpl } from './core/function/dualImpl.ts';
|
|
10
10
|
export { isNonTransferableResource, isTransferableResource, restoreResource, snapshotResource, } from './serial/registry.ts';
|
|
11
11
|
export type { TgpuResourceSnapshot, TransferableResourceType } from './serial/registry.ts';
|
|
@@ -13,4 +13,5 @@ export type { RestoreContext } from './serial/types.ts';
|
|
|
13
13
|
export { deserializeDataSchema, serializeDataSchema, type SerializedDataSchema, } from './serial/schema.ts';
|
|
14
14
|
export type { ResolutionCtx, FunctionArgument } from './types.ts';
|
|
15
15
|
export type { Snippet, ResolvedSnippet, Origin } from './data/snippet.ts';
|
|
16
|
+
export type { AutoStruct } from './data/autoStruct.ts';
|
|
16
17
|
export type { ShaderGenerator, ResolvedStatement, BinaryOperator, ShaderGeneratorClass, FunctionDefinitionOptions, ConstantDefinitionOptions, VariableDefinitionOptions, } from './tgsl/shaderGenerator.ts';
|
package/internal.js
CHANGED
|
@@ -6,7 +6,7 @@ export { UnknownData } from "./data/dataTypes.js";
|
|
|
6
6
|
export { getName, setName } from "./shared/meta.js";
|
|
7
7
|
export { WgslGenerator } from "./tgsl/wgslGenerator.js";
|
|
8
8
|
export { snip, withValue, withDataType, withSideEffects } from "./data/snippet.js";
|
|
9
|
-
export { stringifyNode } from "./shared/tseynit.js";
|
|
9
|
+
export { stringifyNode, stringifyObjectProperty } from "./shared/tseynit.js";
|
|
10
10
|
export { dualImpl } from "./core/function/dualImpl.js";
|
|
11
11
|
export { isNonTransferableResource, isTransferableResource, restoreResource, snapshotResource, } from "./serial/registry.js";
|
|
12
12
|
export { deserializeDataSchema, serializeDataSchema, } from "./serial/schema.js";
|
package/nameUtils.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
export declare const bannedTokens: Set<string>;
|
|
2
|
+
/**
|
|
3
|
+
* Predeclared enumerants that appear as template parameters, e.g. `var<storage, read_write>` or
|
|
4
|
+
* `texture_storage_2d<rgba8unorm, write>`. A module-scope or local declaration with one of these names
|
|
5
|
+
* would shadow the enumerant, so a template using it would refer to the declaration instead.
|
|
6
|
+
* Unlike `bannedTokens`, these remain valid as struct member names, which never shadow anything.
|
|
7
|
+
*/
|
|
8
|
+
export declare const templateEnumerants: Set<string>;
|
|
2
9
|
export declare const builtins: Set<string>;
|
|
3
10
|
/**
|
|
4
11
|
* Sanitizes the primer so that it is compliant with WGSL guidelines.
|