typegpu 0.11.3 → 0.11.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/core/buffer/buffer.js +17 -53
- package/core/buffer/bufferUsage.js +2 -2
- package/core/constant/tgpuConstant.js +1 -1
- package/core/function/fnCore.js +12 -6
- package/core/function/tgpuFragmentFn.d.ts +1 -1
- package/core/pipeline/computePipeline.d.ts +1 -1
- package/core/pipeline/computePipeline.js +1 -1
- package/core/pipeline/renderPipeline.js +1 -1
- package/core/resolve/namespace.d.ts +2 -11
- package/core/resolve/namespace.js +7 -24
- package/core/resolve/resolveData.js +3 -2
- package/core/resolve/tgpuResolve.js +1 -1
- package/core/root/init.d.ts +1 -0
- package/core/root/init.js +6 -0
- package/core/root/rootTypes.d.ts +21 -15
- package/core/sampler/sampler.js +2 -2
- package/core/simulate/tgpuSimulate.js +1 -1
- package/core/slot/accessor.js +1 -1
- package/core/texture/externalTexture.js +1 -1
- package/core/texture/texture.js +2 -2
- package/core/variable/tgpuVariable.js +1 -1
- package/data/autoStruct.js +3 -2
- package/data/dataIO.d.ts +11 -0
- package/data/dataIO.js +45 -1
- package/data/dataTypes.d.ts +1 -1
- package/data/dataTypes.js +2 -11
- package/data/partialIO.d.ts +8 -0
- package/data/partialIO.js +6 -1
- package/data/struct.js +3 -2
- package/data/wgslTypes.d.ts +16 -16
- package/index.d.ts +3 -1
- package/index.js +3 -1
- package/indexNamedExports.d.ts +2 -0
- package/{nameRegistry.js → nameUtils.js} +46 -90
- package/package.js +1 -1
- package/package.json +1 -1
- package/resolutionCtx.js +64 -30
- package/shared/stringify.js +1 -0
- package/shared/tseynit.js +90 -0
- package/std/copy.d.ts +7 -0
- package/std/copy.js +27 -0
- package/std/index.d.ts +3 -2
- package/std/index.js +3 -1
- package/tgpuUnstable.js +1 -1
- package/tgsl/accessIndex.js +2 -1
- package/tgsl/consoleLog/deserializers.js +1 -1
- package/tgsl/consoleLog/logGenerator.js +1 -6
- package/tgsl/consoleLog/types.d.ts +4 -5
- package/tgsl/conversion.js +4 -1
- package/tgsl/generationHelpers.d.ts +2 -1
- package/tgsl/jsPolyfills.d.ts +25 -0
- package/tgsl/jsPolyfills.js +44 -0
- package/tgsl/wgslGenerator.d.ts +20 -2
- package/tgsl/wgslGenerator.js +114 -57
- package/types.d.ts +29 -2
- package/nameRegistry.d.ts +0 -30
- package/tgsl/consoleLog/types.js +0 -12
- package/tgsl/math.js +0 -45
package/README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
<picture>
|
|
4
|
+
<source srcset="https://typegpu.com/typegpu-logo-dark.svg" media="(prefers-color-scheme: dark)" />
|
|
5
|
+
<img src="https://typegpu.com/typegpu-logo-light.svg" />
|
|
6
|
+
</picture>
|
|
5
7
|
|
|
6
8
|
[Website](https://docs.swmansion.com/TypeGPU) —
|
|
7
9
|
[Documentation](https://docs.swmansion.com/TypeGPU/getting-started)
|
package/core/buffer/buffer.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { $internal } from "../../shared/symbols.js";
|
|
2
2
|
import { getName, setName } from "../../shared/meta.js";
|
|
3
|
-
import {
|
|
3
|
+
import { isWgslData } from "../../data/wgslTypes.js";
|
|
4
4
|
import { isGPUBuffer } from "../../types.js";
|
|
5
|
-
import { alignmentOf } from "../../data/alignmentOf.js";
|
|
6
|
-
import { roundUp } from "../../mathUtils.js";
|
|
7
5
|
import { sizeOf } from "../../data/sizeOf.js";
|
|
8
6
|
import { getCompiledWriter } from "../../data/compiledIO.js";
|
|
9
|
-
import {
|
|
10
|
-
import { convertPartialToPatch, getPatchInstructions } from "../../data/partialIO.js";
|
|
7
|
+
import { calculateOffsets, readFromArrayBuffer, writeToArrayBuffer } from "../../data/dataIO.js";
|
|
8
|
+
import { convertPartialToPatch, getPatchInstructions, patchArrayBuffer } from "../../data/partialIO.js";
|
|
11
9
|
import { mutable, readonly, uniform } from "./bufferUsage.js";
|
|
12
|
-
import { BufferReader, BufferWriter, getSystemEndianness } from "typed-binary";
|
|
13
10
|
|
|
14
11
|
//#region src/core/buffer/buffer.ts
|
|
15
12
|
const usageToUsageConstructor = {
|
|
@@ -27,7 +24,6 @@ function isBuffer(value) {
|
|
|
27
24
|
function isUsableAsVertex(buffer) {
|
|
28
25
|
return !!buffer.usableAsVertex;
|
|
29
26
|
}
|
|
30
|
-
const endianness = getSystemEndianness();
|
|
31
27
|
var TgpuBufferImpl = class {
|
|
32
28
|
[$internal] = true;
|
|
33
29
|
resourceType = "buffer";
|
|
@@ -74,7 +70,7 @@ var TgpuBufferImpl = class {
|
|
|
74
70
|
});
|
|
75
71
|
if (this.initial || this.#initialCallback) {
|
|
76
72
|
if (this.#initialCallback) this.#initialCallback(this);
|
|
77
|
-
else if (this.initial)
|
|
73
|
+
else if (this.initial) writeToArrayBuffer(this.#getMappedRange(), this.dataType, this.initial);
|
|
78
74
|
this.#unmapBuffer();
|
|
79
75
|
}
|
|
80
76
|
}
|
|
@@ -134,62 +130,30 @@ var TgpuBufferImpl = class {
|
|
|
134
130
|
compileWriter() {
|
|
135
131
|
getCompiledWriter(this.dataType);
|
|
136
132
|
}
|
|
137
|
-
#writeToTarget(target, data, options) {
|
|
138
|
-
const startOffset = options?.startOffset ?? 0;
|
|
139
|
-
const endOffset = options?.endOffset ?? target.byteLength;
|
|
140
|
-
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
|
141
|
-
const src = data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
142
|
-
const regionSize = endOffset - startOffset;
|
|
143
|
-
if (src.byteLength !== regionSize) console.warn(`Buffer size mismatch: expected ${regionSize} bytes, got ${src.byteLength}. ` + (src.byteLength < regionSize ? "Data truncated." : "Excess ignored."));
|
|
144
|
-
const copyLen = Math.min(src.byteLength, regionSize);
|
|
145
|
-
new Uint8Array(target).set(src.subarray(0, copyLen), startOffset);
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
const dataView = new DataView(target);
|
|
149
|
-
const isLittleEndian = endianness === "little";
|
|
150
|
-
const compiledWriter = getCompiledWriter(this.dataType);
|
|
151
|
-
if (compiledWriter) try {
|
|
152
|
-
compiledWriter(dataView, startOffset, data, isLittleEndian, endOffset);
|
|
153
|
-
return;
|
|
154
|
-
} catch (error) {
|
|
155
|
-
console.error(`Error when using compiled writer for buffer ${getName(this) ?? "<unnamed>"} - this is likely a bug, please submit an issue at https://github.com/software-mansion/TypeGPU/issues\nUsing fallback writer instead.`, error);
|
|
156
|
-
}
|
|
157
|
-
const writer = new BufferWriter(target);
|
|
158
|
-
writer.seekTo(startOffset);
|
|
159
|
-
writeData(writer, this.dataType, data);
|
|
160
|
-
}
|
|
161
133
|
write(data, options) {
|
|
162
134
|
const gpuBuffer = this.buffer;
|
|
163
|
-
const bufferSize = sizeOf(this.dataType);
|
|
164
|
-
const startOffset = options?.startOffset ?? 0;
|
|
165
|
-
let naturalSize = void 0;
|
|
166
|
-
if (isWgslArray(this.dataType) && Array.isArray(data)) naturalSize = data.length * roundUp(sizeOf(this.dataType.elementType), alignmentOf(this.dataType.elementType));
|
|
167
|
-
else if (ArrayBuffer.isView(data) || data instanceof ArrayBuffer) naturalSize = data.byteLength;
|
|
168
|
-
const naturalEndOffset = naturalSize !== void 0 ? Math.min(startOffset + naturalSize, bufferSize) : void 0;
|
|
169
|
-
const size = (options?.endOffset ?? naturalEndOffset ?? bufferSize) - startOffset;
|
|
170
135
|
if (gpuBuffer.mapState === "mapped") {
|
|
171
136
|
const mapped = this.#getMappedRange();
|
|
172
137
|
if (data instanceof ArrayBuffer && data === mapped) return;
|
|
173
|
-
|
|
138
|
+
writeToArrayBuffer(mapped, this.dataType, data, options);
|
|
174
139
|
return;
|
|
175
140
|
}
|
|
176
|
-
if (!(data instanceof ArrayBuffer && data === this.#hostBuffer))
|
|
141
|
+
if (!(data instanceof ArrayBuffer && data === this.#hostBuffer)) writeToArrayBuffer(this.#hostBuffer, this.dataType, data, options);
|
|
142
|
+
const { startOffset, endOffset } = calculateOffsets(options, this.dataType, data);
|
|
143
|
+
const size = endOffset - startOffset;
|
|
177
144
|
this.#device.queue.writeBuffer(gpuBuffer, startOffset, this.#hostBuffer, startOffset, size);
|
|
178
145
|
}
|
|
179
146
|
/** @deprecated Use {@link patch} instead. */
|
|
180
147
|
writePartial(data) {
|
|
181
|
-
this
|
|
148
|
+
this.patch(convertPartialToPatch(this.dataType, data));
|
|
182
149
|
}
|
|
183
150
|
patch(data) {
|
|
184
|
-
this.#applyInstructions(getPatchInstructions(this.dataType, data, this.#hostBuffer));
|
|
185
|
-
}
|
|
186
|
-
#applyInstructions(instructions) {
|
|
187
151
|
const gpuBuffer = this.buffer;
|
|
188
|
-
if (gpuBuffer.mapState === "mapped")
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
for (const { data, gpuOffset } of instructions)
|
|
192
|
-
}
|
|
152
|
+
if (gpuBuffer.mapState === "mapped") patchArrayBuffer(this.#getMappedRange(), this.dataType, data);
|
|
153
|
+
else {
|
|
154
|
+
const instructions = getPatchInstructions(this.dataType, data, this.#hostBuffer);
|
|
155
|
+
for (const { data: data$1, gpuOffset } of instructions) this.#device.queue.writeBuffer(gpuBuffer, gpuOffset, data$1);
|
|
156
|
+
}
|
|
193
157
|
}
|
|
194
158
|
clear() {
|
|
195
159
|
const gpuBuffer = this.buffer;
|
|
@@ -210,10 +174,10 @@ var TgpuBufferImpl = class {
|
|
|
210
174
|
}
|
|
211
175
|
async read() {
|
|
212
176
|
const gpuBuffer = this.buffer;
|
|
213
|
-
if (gpuBuffer.mapState === "mapped") return
|
|
177
|
+
if (gpuBuffer.mapState === "mapped") return readFromArrayBuffer(this.#getMappedRange(), this.dataType);
|
|
214
178
|
if (gpuBuffer.usage & GPUBufferUsage.MAP_READ) {
|
|
215
179
|
await gpuBuffer.mapAsync(GPUMapMode.READ);
|
|
216
|
-
const res$1 =
|
|
180
|
+
const res$1 = readFromArrayBuffer(this.#getMappedRange(), this.dataType);
|
|
217
181
|
this.#unmapBuffer();
|
|
218
182
|
return res$1;
|
|
219
183
|
}
|
|
@@ -225,7 +189,7 @@ var TgpuBufferImpl = class {
|
|
|
225
189
|
commandEncoder.copyBufferToBuffer(gpuBuffer, 0, stagingBuffer, 0, sizeOf(this.dataType));
|
|
226
190
|
this.#device.queue.submit([commandEncoder.finish()]);
|
|
227
191
|
await stagingBuffer.mapAsync(GPUMapMode.READ, 0, sizeOf(this.dataType));
|
|
228
|
-
const res =
|
|
192
|
+
const res = readFromArrayBuffer(stagingBuffer.getMappedRange(), this.dataType);
|
|
229
193
|
stagingBuffer.unmap();
|
|
230
194
|
stagingBuffer.destroy();
|
|
231
195
|
return res;
|
|
@@ -36,7 +36,7 @@ var TgpuFixedBufferImpl = class {
|
|
|
36
36
|
}
|
|
37
37
|
[$resolve](ctx) {
|
|
38
38
|
const dataType = this.buffer.dataType;
|
|
39
|
-
const id = ctx.
|
|
39
|
+
const id = ctx.makeUniqueIdentifier(getName(this), "global");
|
|
40
40
|
const { group, binding } = ctx.allocateFixedEntry(this.usage === "uniform" ? { uniform: dataType } : {
|
|
41
41
|
storage: dataType,
|
|
42
42
|
access: this.usage
|
|
@@ -103,7 +103,7 @@ var TgpuLaidOutBufferImpl = class {
|
|
|
103
103
|
setName(this, membership.key);
|
|
104
104
|
}
|
|
105
105
|
[$resolve](ctx) {
|
|
106
|
-
const id = ctx.
|
|
106
|
+
const id = ctx.makeUniqueIdentifier(getName(this), "global");
|
|
107
107
|
const group = ctx.allocateLayoutEntry(this.#membership.layout);
|
|
108
108
|
const usage = usageToVarTemplateMap[this.usage];
|
|
109
109
|
ctx.addDeclaration(`@group(${group}) @binding(${this.#membership.idx}) var<${usage}> ${id}: ${ctx.resolve(this.dataType).value};`);
|
|
@@ -37,7 +37,7 @@ var TgpuConstImpl = class {
|
|
|
37
37
|
return this;
|
|
38
38
|
}
|
|
39
39
|
[$resolve](ctx) {
|
|
40
|
-
const id = ctx.
|
|
40
|
+
const id = ctx.makeUniqueIdentifier(getName(this), "global");
|
|
41
41
|
const resolvedDataType = ctx.resolve(this.dataType).value;
|
|
42
42
|
const resolvedValue = ctx.resolve(this.#value, this.dataType).value;
|
|
43
43
|
ctx.addDeclaration(`const ${id}: ${resolvedDataType} = ${resolvedValue};`);
|
package/core/function/fnCore.js
CHANGED
|
@@ -5,6 +5,7 @@ import { undecorate } from "../../data/dataTypes.js";
|
|
|
5
5
|
import { snip } from "../../data/snippet.js";
|
|
6
6
|
import { MissingLinksError } from "../../errors.js";
|
|
7
7
|
import { getAttributesString } from "../../data/attributes.js";
|
|
8
|
+
import { validateIdentifier } from "../../nameUtils.js";
|
|
8
9
|
import { applyExternals, replaceExternalsInWgsl } from "../resolve/externals.js";
|
|
9
10
|
import { extractArgs } from "./extractArgs.js";
|
|
10
11
|
|
|
@@ -29,21 +30,26 @@ function createFnCore(implementation, functionType, workgroupSize) {
|
|
|
29
30
|
else if (functionType === "vertex") attributes = `@vertex `;
|
|
30
31
|
else if (functionType === "fragment") attributes = `@fragment `;
|
|
31
32
|
for (const externals of externalsToApply) applyExternals(externalMap, externals);
|
|
32
|
-
const id = ctx.
|
|
33
|
+
const id = ctx.makeUniqueIdentifier(getName(this), "global");
|
|
33
34
|
if (typeof implementation === "string") {
|
|
34
35
|
if (!returnType) throw new Error("Explicit return type is required for string implementation");
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
if (entryInput) {
|
|
37
|
+
for (const arg of entryInput.positionalArgs) {
|
|
38
|
+
const result = /* @__PURE__ */ validateIdentifier(arg.schemaKey);
|
|
39
|
+
if (!result.success) throw new Error(`Invalid argument name "${arg.schemaKey}"${result.error ? `: ${result.error}` : ""}`);
|
|
40
|
+
}
|
|
41
|
+
applyExternals(externalMap, { in: Object.fromEntries(entryInput.positionalArgs.map((a) => [a.schemaKey, a.schemaKey])) });
|
|
42
|
+
}
|
|
37
43
|
const replacedImpl = replaceExternalsInWgsl(ctx, externalMap, implementation);
|
|
38
44
|
let header = "";
|
|
39
45
|
let body = "";
|
|
40
|
-
if (functionType !== "normal" && entryInput
|
|
46
|
+
if (functionType !== "normal" && entryInput) {
|
|
41
47
|
const { dataSchema, positionalArgs } = entryInput;
|
|
42
48
|
const parts = [];
|
|
43
49
|
if (dataSchema && isArgUsedInBody("in", replacedImpl)) parts.push(`in: ${ctx.resolve(dataSchema).value}`);
|
|
44
50
|
for (const a of positionalArgs) {
|
|
45
|
-
const argName =
|
|
46
|
-
if (
|
|
51
|
+
const argName = a.schemaKey;
|
|
52
|
+
if (isArgUsedInBody(argName, replacedImpl)) parts.push(`${getAttributesString(a.type)}${argName}: ${ctx.resolve(a.type).value}`);
|
|
47
53
|
}
|
|
48
54
|
const input = `(${parts.join(", ")})`;
|
|
49
55
|
const attributes$1 = isWgslData(returnType) ? getAttributesString(returnType) : "";
|
|
@@ -2,9 +2,9 @@ import { TgpuNamable } from "../../shared/meta.js";
|
|
|
2
2
|
import { $internal } from "../../shared/symbols.js";
|
|
3
3
|
import { Prettify } from "../../shared/utilityTypes.js";
|
|
4
4
|
import { AnyFragmentInputBuiltin, AnyFragmentOutputBuiltin, OmitBuiltins } from "../../builtin.js";
|
|
5
|
+
import { InstanceToSchema } from "../../data/instanceToSchema.js";
|
|
5
6
|
import { BaseIOData, IOLayout, IORecord, InferIO } from "./fnTypes.js";
|
|
6
7
|
import { AnyAutoCustoms, AutoFragmentIn, AutoFragmentOut } from "./autoIO.js";
|
|
7
|
-
import { InstanceToSchema } from "../../data/instanceToSchema.js";
|
|
8
8
|
import { IOLayoutToSchema } from "./ioSchema.js";
|
|
9
9
|
import { BaseData, Decorated, Interpolate, Location, Vec4f, Vec4i, Vec4u, WgslStruct } from "../../data/wgslTypes.js";
|
|
10
10
|
import { UndecorateRecord } from "../../data/dataTypes.js";
|
|
@@ -3,8 +3,8 @@ import { $internal } from "../../shared/symbols.js";
|
|
|
3
3
|
import { AnyComputeBuiltin } from "../../builtin.js";
|
|
4
4
|
import "../querySet/querySet.js";
|
|
5
5
|
import "../../data/snippet.js";
|
|
6
|
-
import "../../tgsl/consoleLog/types.js";
|
|
7
6
|
import { IORecord } from "../function/fnTypes.js";
|
|
7
|
+
import "../../tgsl/consoleLog/types.js";
|
|
8
8
|
import { TgpuComputeFn } from "../function/tgpuComputeFn.js";
|
|
9
9
|
import "../slot/slotTypes.js";
|
|
10
10
|
import { PrimitiveOffsetInfo } from "../../data/offsetUtils.js";
|
|
@@ -3,10 +3,10 @@ import { PERF, getName, setName } from "../../shared/meta.js";
|
|
|
3
3
|
import { Void } from "../../data/wgslTypes.js";
|
|
4
4
|
import { snip } from "../../data/snippet.js";
|
|
5
5
|
import { isGPUBuffer } from "../../types.js";
|
|
6
|
-
import { namespace } from "../resolve/namespace.js";
|
|
7
6
|
import { isBindGroup } from "../../tgpuBindGroupLayout.js";
|
|
8
7
|
import { resolve } from "../../resolutionCtx.js";
|
|
9
8
|
import { isGPUCommandEncoder, isGPUComputePassEncoder } from "./typeGuards.js";
|
|
9
|
+
import { namespace } from "../resolve/namespace.js";
|
|
10
10
|
import { applyBindGroups } from "./applyPipelineState.js";
|
|
11
11
|
import { logDataFromGPU } from "../../tgsl/consoleLog/deserializers.js";
|
|
12
12
|
import { wgslExtensionToFeatureName, wgslExtensions } from "../../wgslExtensions.js";
|
|
@@ -7,12 +7,12 @@ import { isGPUBuffer } from "../../types.js";
|
|
|
7
7
|
import { formatToWGSLType } from "../../data/vertexFormatData.js";
|
|
8
8
|
import { sizeOf } from "../../data/sizeOf.js";
|
|
9
9
|
import { isBuiltin } from "../../data/attributes.js";
|
|
10
|
-
import { namespace } from "../resolve/namespace.js";
|
|
11
10
|
import { isTexture, isTextureView } from "../texture/texture.js";
|
|
12
11
|
import { isBindGroup, isBindGroupLayout } from "../../tgpuBindGroupLayout.js";
|
|
13
12
|
import { connectAttributesToShader } from "../vertexLayout/connectAttributesToShader.js";
|
|
14
13
|
import { resolve } from "../../resolutionCtx.js";
|
|
15
14
|
import { isGPUCommandEncoder, isGPURenderBundleEncoder, isGPURenderPassEncoder } from "./typeGuards.js";
|
|
15
|
+
import { namespace } from "../resolve/namespace.js";
|
|
16
16
|
import { applyBindGroups, applyVertexBuffers } from "./applyPipelineState.js";
|
|
17
17
|
import { logDataFromGPU } from "../../tgsl/consoleLog/deserializers.js";
|
|
18
18
|
import { wgslExtensionToFeatureName, wgslExtensions } from "../../wgslExtensions.js";
|
|
@@ -2,13 +2,13 @@ import { $internal } from "../../shared/symbols.js";
|
|
|
2
2
|
import { ResolvedSnippet } from "../../data/snippet.js";
|
|
3
3
|
import { ShelllessRepository } from "../../tgsl/shellless.js";
|
|
4
4
|
import { TgpuLazy, TgpuSlot } from "../slot/slotTypes.js";
|
|
5
|
-
import { NameRegistry } from "../../nameRegistry.js";
|
|
6
5
|
|
|
7
6
|
//#region src/core/resolve/namespace.d.ts
|
|
8
7
|
type SlotToValueMap = Map<TgpuSlot<unknown>, unknown>;
|
|
9
8
|
interface NamespaceInternal {
|
|
10
|
-
readonly
|
|
9
|
+
readonly takenGlobalIdentifiers: Set<string>;
|
|
11
10
|
readonly shelllessRepo: ShelllessRepository;
|
|
11
|
+
readonly strategy: 'random' | 'strict';
|
|
12
12
|
memoizedResolves: WeakMap<object, {
|
|
13
13
|
slotToValueMap: SlotToValueMap;
|
|
14
14
|
result: ResolvedSnippet;
|
|
@@ -17,18 +17,9 @@ interface NamespaceInternal {
|
|
|
17
17
|
slotToValueMap: SlotToValueMap;
|
|
18
18
|
result: unknown;
|
|
19
19
|
}[]>;
|
|
20
|
-
listeners: { [K in keyof NamespaceEventMap]: Set<(event: NamespaceEventMap[K]) => void> };
|
|
21
20
|
}
|
|
22
|
-
type NamespaceEventMap = {
|
|
23
|
-
name: {
|
|
24
|
-
target: object;
|
|
25
|
-
name: string;
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
type DetachListener = () => void;
|
|
29
21
|
interface Namespace {
|
|
30
22
|
readonly [$internal]: NamespaceInternal;
|
|
31
|
-
on<TEvent extends keyof NamespaceEventMap>(event: TEvent, listener: (event: NamespaceEventMap[TEvent]) => void): DetachListener;
|
|
32
23
|
}
|
|
33
24
|
interface NamespaceOptions {
|
|
34
25
|
names?: 'random' | 'strict' | undefined;
|
|
@@ -1,41 +1,24 @@
|
|
|
1
1
|
import { $internal } from "../../shared/symbols.js";
|
|
2
|
-
import {
|
|
3
|
-
import { RandomNameRegistry, StrictNameRegistry } from "../../nameRegistry.js";
|
|
2
|
+
import { bannedTokens, builtins } from "../../nameUtils.js";
|
|
4
3
|
import { ShelllessRepository } from "../../tgsl/shellless.js";
|
|
5
4
|
|
|
6
5
|
//#region src/core/resolve/namespace.ts
|
|
7
6
|
var NamespaceImpl = class {
|
|
8
7
|
[$internal];
|
|
9
|
-
constructor(
|
|
8
|
+
constructor(strategy) {
|
|
10
9
|
this[$internal] = {
|
|
11
|
-
|
|
10
|
+
strategy,
|
|
11
|
+
takenGlobalIdentifiers: new Set([...bannedTokens, ...builtins]),
|
|
12
12
|
shelllessRepo: new ShelllessRepository(),
|
|
13
13
|
memoizedResolves: /* @__PURE__ */ new WeakMap(),
|
|
14
|
-
memoizedLazy: /* @__PURE__ */ new WeakMap()
|
|
15
|
-
listeners: { name: /* @__PURE__ */ new Set() }
|
|
14
|
+
memoizedLazy: /* @__PURE__ */ new WeakMap()
|
|
16
15
|
};
|
|
17
16
|
}
|
|
18
|
-
on(event, listener) {
|
|
19
|
-
if (event === "name") {
|
|
20
|
-
const listeners = this[$internal].listeners.name;
|
|
21
|
-
listeners.add(listener);
|
|
22
|
-
return () => listeners.delete(listener);
|
|
23
|
-
}
|
|
24
|
-
throw new Error(`Unsupported event: ${event}`);
|
|
25
|
-
}
|
|
26
17
|
};
|
|
27
|
-
function getUniqueName(namespace$1, resource) {
|
|
28
|
-
const name = namespace$1.nameRegistry.makeUnique(getName(resource), true);
|
|
29
|
-
for (const listener of namespace$1.listeners.name) listener({
|
|
30
|
-
target: resource,
|
|
31
|
-
name
|
|
32
|
-
});
|
|
33
|
-
return name;
|
|
34
|
-
}
|
|
35
18
|
function namespace(options) {
|
|
36
19
|
const { names = "strict" } = options ?? {};
|
|
37
|
-
return new NamespaceImpl(names
|
|
20
|
+
return new NamespaceImpl(names);
|
|
38
21
|
}
|
|
39
22
|
|
|
40
23
|
//#endregion
|
|
41
|
-
export {
|
|
24
|
+
export { namespace };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { $internal } from "../../shared/symbols.js";
|
|
2
|
+
import { getName } from "../../shared/meta.js";
|
|
2
3
|
import { isLooseData } from "../../data/dataTypes.js";
|
|
3
4
|
import { assertExhaustive } from "../../shared/utilityTypes.js";
|
|
4
5
|
import { formatToWGSLType } from "../../data/vertexFormatData.js";
|
|
@@ -61,7 +62,7 @@ function resolveStructProperty(ctx, [key, property]) {
|
|
|
61
62
|
*/
|
|
62
63
|
function resolveStruct(ctx, struct) {
|
|
63
64
|
if (struct[$internal].isAbstruct) throw new Error("Cannot resolve abstract struct types to WGSL.");
|
|
64
|
-
const id = ctx.
|
|
65
|
+
const id = ctx.makeUniqueIdentifier(getName(struct), "global");
|
|
65
66
|
ctx.addDeclaration(`\
|
|
66
67
|
struct ${id} {
|
|
67
68
|
${Object.entries(struct.propTypes).map((prop) => resolveStructProperty(ctx, prop)).join("")}\
|
|
@@ -84,7 +85,7 @@ ${Object.entries(struct.propTypes).map((prop) => resolveStructProperty(ctx, prop
|
|
|
84
85
|
* ```
|
|
85
86
|
*/
|
|
86
87
|
function resolveUnstruct(ctx, unstruct) {
|
|
87
|
-
const id = ctx.
|
|
88
|
+
const id = ctx.makeUniqueIdentifier(getName(unstruct), "global");
|
|
88
89
|
ctx.addDeclaration(`\
|
|
89
90
|
struct ${id} {
|
|
90
91
|
${Object.entries(unstruct.propTypes).map((prop) => isAttribute(prop[1]) ? resolveStructProperty(ctx, [prop[0], formatToWGSLType[prop[1].format]]) : resolveStructProperty(ctx, prop)).join("")}
|
|
@@ -2,10 +2,10 @@ import { $internal, $resolve } from "../../shared/symbols.js";
|
|
|
2
2
|
import { Void } from "../../data/wgslTypes.js";
|
|
3
3
|
import { snip } from "../../data/snippet.js";
|
|
4
4
|
import { applyExternals, replaceExternalsInWgsl } from "./externals.js";
|
|
5
|
-
import { namespace } from "./namespace.js";
|
|
6
5
|
import { isBindGroupLayout } from "../../tgpuBindGroupLayout.js";
|
|
7
6
|
import { resolve } from "../../resolutionCtx.js";
|
|
8
7
|
import { isPipeline } from "../pipeline/typeGuards.js";
|
|
8
|
+
import { namespace } from "./namespace.js";
|
|
9
9
|
|
|
10
10
|
//#region src/core/resolve/tgpuResolve.ts
|
|
11
11
|
function resolveWithContext(arg0, options) {
|
package/core/root/init.d.ts
CHANGED
package/core/root/init.js
CHANGED
|
@@ -54,6 +54,12 @@ var TgpuGuardedComputePipelineImpl = class TgpuGuardedComputePipelineImpl {
|
|
|
54
54
|
with(bindGroupOrEncoder) {
|
|
55
55
|
return new TgpuGuardedComputePipelineImpl(this.#root, this.#pipeline.with(bindGroupOrEncoder), this.#sizeUniform, this.#workgroupSize);
|
|
56
56
|
}
|
|
57
|
+
withPerformanceCallback(callback) {
|
|
58
|
+
return new TgpuGuardedComputePipelineImpl(this.#root, this.#pipeline.withPerformanceCallback(callback), this.#sizeUniform, this.#workgroupSize);
|
|
59
|
+
}
|
|
60
|
+
withTimestampWrites(options) {
|
|
61
|
+
return new TgpuGuardedComputePipelineImpl(this.#root, this.#pipeline.withTimestampWrites(options), this.#sizeUniform, this.#workgroupSize);
|
|
62
|
+
}
|
|
57
63
|
dispatchThreads(...threads) {
|
|
58
64
|
const sanitizedSize = toVec3(threads);
|
|
59
65
|
const workgroupCount = ceil(vec3f(sanitizedSize).div(vec3f(this.#workgroupSize)));
|
package/core/root/rootTypes.d.ts
CHANGED
|
@@ -4,14 +4,14 @@ import { Assume, Mutable, OmitProps, Prettify } from "../../shared/utilityTypes.
|
|
|
4
4
|
import { WgslComparisonSamplerProps, WgslSamplerProps } from "../../data/sampler.js";
|
|
5
5
|
import { AnyComputeBuiltin, AnyFragmentInputBuiltin, OmitBuiltins } from "../../builtin.js";
|
|
6
6
|
import { TgpuQuerySet } from "../querySet/querySet.js";
|
|
7
|
+
import { InstanceToSchema } from "../../data/instanceToSchema.js";
|
|
7
8
|
import { TgpuMutable, TgpuReadonly, TgpuUniform } from "../buffer/bufferShorthand.js";
|
|
8
|
-
import { LogGeneratorOptions } from "../../tgsl/consoleLog/types.js";
|
|
9
9
|
import { IORecord } from "../function/fnTypes.js";
|
|
10
|
+
import { LogGeneratorOptions } from "../../tgsl/consoleLog/types.js";
|
|
10
11
|
import { TgpuComputeFn } from "../function/tgpuComputeFn.js";
|
|
11
12
|
import { Eventual, TgpuAccessor, TgpuMutableAccessor, TgpuSlot } from "../slot/slotTypes.js";
|
|
12
13
|
import { TgpuComputePipeline } from "../pipeline/computePipeline.js";
|
|
13
14
|
import { AnyAutoCustoms, AutoFragmentIn, AutoFragmentOut, AutoVertexIn, AutoVertexOut } from "../function/autoIO.js";
|
|
14
|
-
import { InstanceToSchema } from "../../data/instanceToSchema.js";
|
|
15
15
|
import { FragmentInConstrained, FragmentOutConstrained, TgpuFragmentFn, VertexOutToVarying } from "../function/tgpuFragmentFn.js";
|
|
16
16
|
import { TgpuVertexFn } from "../function/tgpuVertexFn.js";
|
|
17
17
|
import { AttribRecordToDefaultDataTypes, LayoutToAllowedAttribs } from "../vertexLayout/vertexAttribute.js";
|
|
@@ -40,6 +40,20 @@ interface TgpuGuardedComputePipeline<TArgs extends number[] = number[]> extends
|
|
|
40
40
|
* Analogous to `TgpuComputePipeline.with(encoder)`.
|
|
41
41
|
*/
|
|
42
42
|
with(encoder: GPUCommandEncoder): TgpuGuardedComputePipeline<TArgs>;
|
|
43
|
+
/**
|
|
44
|
+
* Returns a pipeline wrapper with the given performance callback attached.
|
|
45
|
+
* Analogous to `TgpuComputePipeline.withPerformanceCallback(callback)`.
|
|
46
|
+
*/
|
|
47
|
+
withPerformanceCallback(callback: (start: bigint, end: bigint) => void | Promise<void>): TgpuGuardedComputePipeline<TArgs>;
|
|
48
|
+
/**
|
|
49
|
+
* Returns a pipeline wrapper with the given timestamp writes configuration.
|
|
50
|
+
* Analogous to `TgpuComputePipeline.withTimestampWrites(options)`.
|
|
51
|
+
*/
|
|
52
|
+
withTimestampWrites(options: {
|
|
53
|
+
querySet: TgpuQuerySet<'timestamp'> | GPUQuerySet;
|
|
54
|
+
beginningOfPassWriteIndex?: number;
|
|
55
|
+
endOfPassWriteIndex?: number;
|
|
56
|
+
}): TgpuGuardedComputePipeline<TArgs>;
|
|
43
57
|
/**
|
|
44
58
|
* Dispatches the pipeline.
|
|
45
59
|
* Unlike `TgpuComputePipeline.dispatchWorkgroups()`, this method takes in the
|
|
@@ -166,7 +180,7 @@ interface WithBinding extends Withable<WithBinding> {
|
|
|
166
180
|
})): TgpuRenderPipeline<NormalizeOutput<TFragmentOut>> | TgpuRenderPipeline<Void>;
|
|
167
181
|
/**
|
|
168
182
|
* Creates a compute pipeline that executes the given callback in an exact number of threads.
|
|
169
|
-
* This is different from `
|
|
183
|
+
* This is different from `createComputePipeline()` in that it does a bounds check on the
|
|
170
184
|
* thread id, where as regular pipelines do not and work in units of workgroups.
|
|
171
185
|
*
|
|
172
186
|
* @param callback A function converted to WGSL and executed on the GPU.
|
|
@@ -473,10 +487,8 @@ interface TgpuRoot extends Unwrapper, WithBinding {
|
|
|
473
487
|
* Typed wrapper around a GPUBuffer.
|
|
474
488
|
*
|
|
475
489
|
* @param typeSchema The type of data that this buffer will hold.
|
|
476
|
-
* @param initial
|
|
490
|
+
* @param initial Either initial value of the buffer, or an initializer to execute on the mapped buffer. (optional)
|
|
477
491
|
*/
|
|
478
|
-
createBuffer<TData extends AnyData>(typeSchema: ValidateBufferSchema<TData>, initializer: (buffer: TgpuBuffer<NoInfer<TData>>) => void): TgpuBuffer<TData>;
|
|
479
|
-
createBuffer<TData extends AnyData>(typeSchema: ValidateBufferSchema<TData>, initial?: InferInput<NoInfer<TData>>): TgpuBuffer<TData>;
|
|
480
492
|
createBuffer<TData extends AnyData>(typeSchema: ValidateBufferSchema<TData>, initial?: ((buffer: TgpuBuffer<NoInfer<TData>>) => void) | InferInput<NoInfer<TData>>): TgpuBuffer<TData>;
|
|
481
493
|
/**
|
|
482
494
|
* Allocates memory on the GPU, allows passing data between host and shader.
|
|
@@ -494,10 +506,8 @@ interface TgpuRoot extends Unwrapper, WithBinding {
|
|
|
494
506
|
* use {@link TgpuRoot.createBuffer}.
|
|
495
507
|
*
|
|
496
508
|
* @param typeSchema The type of data that this buffer will hold.
|
|
497
|
-
* @param initial
|
|
509
|
+
* @param initial Either initial value of the buffer, or an initializer to execute on the mapped buffer. (optional)
|
|
498
510
|
*/
|
|
499
|
-
createUniform<TData extends AnyWgslData>(typeSchema: ValidateUniformSchema<TData>, initializer: (buffer: TgpuBuffer<NoInfer<TData>>) => void): TgpuUniform<TData>;
|
|
500
|
-
createUniform<TData extends AnyWgslData>(typeSchema: ValidateUniformSchema<TData>, initial?: InferInput<NoInfer<TData>>): TgpuUniform<TData>;
|
|
501
511
|
createUniform<TData extends AnyWgslData>(typeSchema: ValidateUniformSchema<TData>, initial?: ((buffer: TgpuBuffer<NoInfer<TData>>) => void) | InferInput<NoInfer<TData>>): TgpuUniform<TData>;
|
|
502
512
|
/**
|
|
503
513
|
* Allocates memory on the GPU, allows passing data between host and shader.
|
|
@@ -514,10 +524,8 @@ interface TgpuRoot extends Unwrapper, WithBinding {
|
|
|
514
524
|
* use {@link TgpuRoot.createBuffer}.
|
|
515
525
|
*
|
|
516
526
|
* @param typeSchema The type of data that this buffer will hold.
|
|
517
|
-
* @param initial
|
|
527
|
+
* @param initial Either initial value of the buffer, or an initializer to execute on the mapped buffer. (optional)
|
|
518
528
|
*/
|
|
519
|
-
createMutable<TData extends AnyWgslData>(typeSchema: ValidateStorageSchema<TData>, initializer: (buffer: TgpuBuffer<NoInfer<TData>>) => void): TgpuMutable<TData>;
|
|
520
|
-
createMutable<TData extends AnyWgslData>(typeSchema: ValidateStorageSchema<TData>, initial?: InferInput<NoInfer<TData>>): TgpuMutable<TData>;
|
|
521
529
|
createMutable<TData extends AnyWgslData>(typeSchema: ValidateStorageSchema<TData>, initial?: ((buffer: TgpuBuffer<NoInfer<TData>>) => void) | InferInput<NoInfer<TData>>): TgpuMutable<TData>;
|
|
522
530
|
/**
|
|
523
531
|
* Allocates memory on the GPU, allows passing data between host and shader.
|
|
@@ -534,10 +542,8 @@ interface TgpuRoot extends Unwrapper, WithBinding {
|
|
|
534
542
|
* use {@link TgpuRoot.createBuffer}.
|
|
535
543
|
*
|
|
536
544
|
* @param typeSchema The type of data that this buffer will hold.
|
|
537
|
-
* @param initial
|
|
545
|
+
* @param initial Either initial value of the buffer, or an initializer to execute on the mapped buffer. (optional)
|
|
538
546
|
*/
|
|
539
|
-
createReadonly<TData extends AnyWgslData>(typeSchema: ValidateStorageSchema<TData>, initializer: (buffer: TgpuBuffer<NoInfer<TData>>) => void): TgpuReadonly<TData>;
|
|
540
|
-
createReadonly<TData extends AnyWgslData>(typeSchema: ValidateStorageSchema<TData>, initial?: InferInput<NoInfer<TData>>): TgpuReadonly<TData>;
|
|
541
547
|
createReadonly<TData extends AnyWgslData>(typeSchema: ValidateStorageSchema<TData>, initial?: ((buffer: TgpuBuffer<NoInfer<TData>>) => void) | InferInput<NoInfer<TData>>): TgpuReadonly<TData>;
|
|
542
548
|
/**
|
|
543
549
|
* Allocates memory on the GPU, allows passing data between host and shader.
|
package/core/sampler/sampler.js
CHANGED
|
@@ -32,7 +32,7 @@ var TgpuLaidOutSamplerImpl = class {
|
|
|
32
32
|
setName(this, membership.key);
|
|
33
33
|
}
|
|
34
34
|
[$resolve](ctx) {
|
|
35
|
-
const id = ctx.
|
|
35
|
+
const id = ctx.makeUniqueIdentifier(getName(this), "global");
|
|
36
36
|
const group = ctx.allocateLayoutEntry(this.#membership.layout);
|
|
37
37
|
ctx.addDeclaration(`@group(${group}) @binding(${this.#membership.idx}) var ${id}: ${ctx.resolve(this.schema).value};`);
|
|
38
38
|
return snip(id, this.schema, "handle");
|
|
@@ -82,7 +82,7 @@ var TgpuFixedSamplerImpl = class {
|
|
|
82
82
|
this.#filtering = props.minFilter === "linear" || props.magFilter === "linear" || props.mipmapFilter === "linear";
|
|
83
83
|
}
|
|
84
84
|
[$resolve](ctx) {
|
|
85
|
-
const id = ctx.
|
|
85
|
+
const id = ctx.makeUniqueIdentifier(getName(this), "global");
|
|
86
86
|
const { group, binding } = ctx.allocateFixedEntry(this.schema.type === "sampler_comparison" ? { sampler: "comparison" } : { sampler: this.#filtering ? "filtering" : "non-filtering" }, this);
|
|
87
87
|
ctx.addDeclaration(`@group(${group}) @binding(${binding}) var ${id}: ${ctx.resolve(this.schema).value};`);
|
|
88
88
|
return snip(id, this.schema, "handle");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { SimulationState } from "../../types.js";
|
|
2
2
|
import { getResolutionCtx, provideCtx } from "../../execMode.js";
|
|
3
|
-
import { namespace } from "../resolve/namespace.js";
|
|
4
3
|
import wgslGenerator_default from "../../tgsl/wgslGenerator.js";
|
|
5
4
|
import { ResolutionCtxImpl } from "../../resolutionCtx.js";
|
|
5
|
+
import { namespace } from "../resolve/namespace.js";
|
|
6
6
|
|
|
7
7
|
//#region src/core/simulate/tgpuSimulate.ts
|
|
8
8
|
/**
|
package/core/slot/accessor.js
CHANGED
|
@@ -25,7 +25,7 @@ var AccessorBase = class {
|
|
|
25
25
|
constructor(schemaOrConstructor, defaultValue = void 0) {
|
|
26
26
|
this.schema = isData(schemaOrConstructor) ? schemaOrConstructor : schemaOrConstructor(0);
|
|
27
27
|
this.defaultValue = defaultValue;
|
|
28
|
-
this.slot = slot(defaultValue);
|
|
28
|
+
this.slot = (() => slot(defaultValue))();
|
|
29
29
|
this[$getNameForward] = this.slot;
|
|
30
30
|
}
|
|
31
31
|
get [$gpuValueOf]() {
|
|
@@ -17,7 +17,7 @@ var TgpuExternalTextureImpl = class {
|
|
|
17
17
|
setName(this, membership.key);
|
|
18
18
|
}
|
|
19
19
|
[$resolve](ctx) {
|
|
20
|
-
const id = ctx.
|
|
20
|
+
const id = ctx.makeUniqueIdentifier(getName(this), "global");
|
|
21
21
|
const group = ctx.allocateLayoutEntry(this.#membership.layout);
|
|
22
22
|
ctx.addDeclaration(`@group(${group}) @binding(${this.#membership.idx}) var ${id}: ${ctx.resolve(this.schema).value};`);
|
|
23
23
|
return snip(id, textureExternal(), "handle");
|
package/core/texture/texture.js
CHANGED
|
@@ -246,7 +246,7 @@ var TgpuFixedTextureViewImpl = class {
|
|
|
246
246
|
return `textureView:${getName(this) ?? "<unnamed>"}`;
|
|
247
247
|
}
|
|
248
248
|
[$resolve](ctx) {
|
|
249
|
-
const id = ctx.
|
|
249
|
+
const id = ctx.makeUniqueIdentifier(getName(this), "global");
|
|
250
250
|
const { group, binding } = ctx.allocateFixedEntry(isWgslStorageTexture(this.schema) ? { storageTexture: this.schema } : {
|
|
251
251
|
texture: this.schema,
|
|
252
252
|
sampleType: this.#descriptor?.sampleType ?? this.schema.bindingSampleType[0]
|
|
@@ -269,7 +269,7 @@ var TgpuLaidOutTextureViewImpl = class {
|
|
|
269
269
|
return `textureView:${getName(this) ?? "<unnamed>"}`;
|
|
270
270
|
}
|
|
271
271
|
[$resolve](ctx) {
|
|
272
|
-
const id = ctx.
|
|
272
|
+
const id = ctx.makeUniqueIdentifier(getName(this), "global");
|
|
273
273
|
const group = ctx.allocateLayoutEntry(this.#membership.layout);
|
|
274
274
|
ctx.addDeclaration(`@group(${group}) @binding(${this.#membership.idx}) var ${id}: ${ctx.resolve(this.schema).value};`);
|
|
275
275
|
return snip(id, this.schema, "handle");
|
|
@@ -42,7 +42,7 @@ var TgpuVarImpl = class {
|
|
|
42
42
|
this.#initialValue = initialValue;
|
|
43
43
|
}
|
|
44
44
|
[$resolve](ctx) {
|
|
45
|
-
const id = ctx.
|
|
45
|
+
const id = ctx.makeUniqueIdentifier(getName(this), "global");
|
|
46
46
|
const pre = `var<${this.#scope}> ${id}: ${ctx.resolve(this.#dataType).value}`;
|
|
47
47
|
if (this.#initialValue) ctx.addDeclaration(`${pre} = ${ctx.resolve(this.#initialValue, this.#dataType).value};`);
|
|
48
48
|
else ctx.addDeclaration(`${pre};`);
|
package/data/autoStruct.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { $internal, $resolve } from "../shared/symbols.js";
|
|
2
2
|
import { getName, setName } from "../shared/meta.js";
|
|
3
|
-
import {
|
|
3
|
+
import { validateProp } from "../nameUtils.js";
|
|
4
4
|
import { createIoSchema } from "../core/function/ioSchema.js";
|
|
5
5
|
|
|
6
6
|
//#region src/data/autoStruct.ts
|
|
@@ -49,7 +49,8 @@ var AutoStruct = class {
|
|
|
49
49
|
if (!alloc) {
|
|
50
50
|
const wgslKey = key.replaceAll("$", "");
|
|
51
51
|
if (this.#usedWgslKeys.has(wgslKey)) throw new Error(`Property name '${wgslKey}' causes naming clashes. Choose a different name.`);
|
|
52
|
-
|
|
52
|
+
const result = /* @__PURE__ */ validateProp(wgslKey);
|
|
53
|
+
if (!result.success) throw new Error(`Invalid property key '${key}'${result.error ? `: ${result.error}` : ""}`);
|
|
53
54
|
this.#usedWgslKeys.add(wgslKey);
|
|
54
55
|
alloc = {
|
|
55
56
|
prop: wgslKey,
|
package/data/dataIO.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BufferWriteOptions } from "../core/buffer/buffer.js";
|
|
2
|
+
import { BaseData } from "./wgslTypes.js";
|
|
3
|
+
import { Infer, InferInput } from "../shared/repr.js";
|
|
4
|
+
import "typed-binary";
|
|
5
|
+
|
|
6
|
+
//#region src/data/dataIO.d.ts
|
|
7
|
+
|
|
8
|
+
declare function writeToArrayBuffer<T extends BaseData>(buffer: ArrayBuffer, schema: T, data: InferInput<T> | ArrayBuffer, options?: BufferWriteOptions): void;
|
|
9
|
+
declare function readFromArrayBuffer<T extends BaseData>(buffer: ArrayBuffer, schema: T): Infer<T>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { readFromArrayBuffer, writeToArrayBuffer };
|