Variables
Storage and uniform variables
Section titled “Storage and uniform variables”When using TypeGPU for resolution, there is no need to ever define either var<uniform> or var<storage[, address_space]>, as such definitions are added automatically.
For example, in the code snippet below, the external counter is automatically included as a @group(0) @binding(0) var<storage, read_write> counter: vec3f.
In this case, the group and index match the automatically generated “catchall” bind group, used for fixed, “bindless” resources.
const const counter: TgpuMutable<d.Vec3f>
counter = const root: TgpuRoot
root.TgpuRoot.createMutable<d.Vec3f>(typeSchema: d.Vec3f, initial?: d.v3f | undefined): TgpuMutable<d.Vec3f> (+1 overload)
Allocates memory on the GPU, allows passing data between host and shader.
Can be mutated in-place on the GPU. For a general-purpose buffer,
use
TgpuRoot.createBuffer
.
createMutable(import d
d.const vec3f: d.Vec3fexport vec3f
Schema representing vec3f - a vector with 3 elements of type f32.
Also a constructor function for this vector value.
vec3f, import d
d.function vec3f(x: number, y: number, z: number): d.v3f (+5 overloads)export vec3f
Schema representing vec3f - a vector with 3 elements of type f32.
Also a constructor function for this vector value.
vec3f(0, 1, 0));
const const increment: TgpuComputeFn<{ num: d.BuiltinNumWorkgroups;}>
increment = const tgpu: { const: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/function/comptime").comptime; resolve: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/root/init").init; initFromDevice: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/root/init").initFromDevice; slot: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/slot/slot").slot; lazy: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/tgpuUnstable");}
tgpu.computeFn: <{ num: d.BuiltinNumWorkgroups;}>(options: { in: { num: d.BuiltinNumWorkgroups; }; workgroupSize: number[];}) => TgpuComputeFnShell<{ num: d.BuiltinNumWorkgroups;}> (+1 overload)
computeFn({ in: { num: d.BuiltinNumWorkgroups;}
in: { num: d.BuiltinNumWorkgroups
num: import d
d.const builtin: { readonly vertexIndex: d.BuiltinVertexIndex; readonly instanceIndex: d.BuiltinInstanceIndex; readonly clipDistances: d.BuiltinClipDistances; readonly position: d.BuiltinPosition; readonly frontFacing: d.BuiltinFrontFacing; readonly fragDepth: d.BuiltinFragDepth; readonly primitiveIndex: BuiltinPrimitiveIndex; readonly sampleIndex: d.BuiltinSampleIndex; readonly sampleMask: d.BuiltinSampleMask; readonly localInvocationId: d.BuiltinLocalInvocationId; readonly localInvocationIndex: d.BuiltinLocalInvocationIndex; ... 6 more ...; readonly numSubgroups: BuiltinNumSubgroups;}export builtin
builtin.numWorkgroups: d.BuiltinNumWorkgroups
numWorkgroups }, workgroupSize: number[]
workgroupSize: [1],})((input: { num: d.v3u;}
input) => { const const tmp: number
tmp = const counter: TgpuMutable<d.Vec3f>
counter.TgpuMutable<Vec3f>.$: d.v3f
$.v3f.x: number
x; const counter: TgpuMutable<d.Vec3f>
counter.TgpuMutable<Vec3f>.$: d.v3f
$.v3f.x: number
x = const counter: TgpuMutable<d.Vec3f>
counter.TgpuMutable<Vec3f>.$: d.v3f
$.v3f.y: number
y; const counter: TgpuMutable<d.Vec3f>
counter.TgpuMutable<Vec3f>.$: d.v3f
$.v3f.y: number
y += const tmp: number
tmp; const counter: TgpuMutable<d.Vec3f>
counter.TgpuMutable<Vec3f>.$: d.v3f
$.v3f.z: number
z += import d
d.function f32(v?: number | boolean): numberexport f32
A schema that represents a 32-bit float value. (equivalent to f32 in WGSL)
Can also be called to cast a value to an f32.
f32(input: { num: d.v3u;}
input.num: d.v3u
num.v3u.x: number
x);});
const const pipeline: TgpuComputePipeline
pipeline = const root: TgpuRoot
root.WithBinding.createComputePipeline<{ num: d.BuiltinNumWorkgroups;}>(descriptor: TgpuComputePipeline.Descriptor<{ num: d.BuiltinNumWorkgroups;}>): TgpuComputePipeline
createComputePipeline({ compute: TgpuComputeFn<{ num: d.BuiltinNumWorkgroups;}>
compute: const increment: TgpuComputeFn<{ num: d.BuiltinNumWorkgroups;}>
increment });
var console: Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
- A global
console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err);
myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err
console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout
See util.format() for more information.
log(const tgpu: { const: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/function/comptime").comptime; resolve: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/root/init").init; initFromDevice: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/root/init").initFromDevice; slot: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/slot/slot").slot; lazy: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/tgpuUnstable");}
tgpu.resolve: (items: ResolvableObject[], options?: TgpuResolveOptions) => string (+1 overload)
A shorthand for calling tgpu.resolveWithContext(...).code.
resolve([const pipeline: TgpuComputePipeline
pipeline]));// resolved WGSL@group(0) @binding(0) var<storage, read_write> counter: vec3f;
struct increment_Input { @builtin(num_workgroups) num: vec3u,}
@compute @workgroup_size(1) fn increment(input: increment_Input) { var tmp = counter.x; counter.x = counter.y; counter.y += tmp; counter.z += f32(input.num.x);}Private and workgroup variables
Section titled “Private and workgroup variables”For variables of private and workgroup address spaces, TypeGPU provides tgpu.privateVar() and tgpu.workgroupVar() constructor functions.
const const threadCounter: TgpuVar<"private", d.U32>
threadCounter = const tgpu: { const: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/function/comptime").comptime; resolve: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/root/init").init; initFromDevice: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/root/init").initFromDevice; slot: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/slot/slot").slot; lazy: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/tgpuUnstable");}
tgpu.privateVar: <d.U32>(dataType: d.U32, initialValue?: number | undefined) => TgpuVar<"private", d.U32>
Defines a variable scoped to each entry function (private).
privateVar(import d
d.const u32: d.U32export u32
A schema that represents an unsigned 32-bit integer value. (equivalent to u32 in WGSL)
Can also be called to cast a value to an u32 in accordance with WGSL casting rules.
u32, 0);
const const getNext: () => number
getNext = () => { 'use gpu'; const threadCounter: TgpuVar<"private", d.U32>
threadCounter.TgpuVar<"private", U32>.$: number
$ += 1; return [42, 418, 23][const threadCounter: TgpuVar<"private", d.U32>
threadCounter.TgpuVar<"private", U32>.$: number
$];};
const const myComputeFn: TgpuComputeFn<{}>
myComputeFn = const tgpu: { const: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/function/comptime").comptime; resolve: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/root/init").init; initFromDevice: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/root/init").initFromDevice; slot: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/slot/slot").slot; lazy: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/tgpuUnstable");}
tgpu.computeFn: (options: { workgroupSize: number[];}) => TgpuComputeFnShell<{}> (+1 overload)
computeFn({ workgroupSize: number[]
workgroupSize: [64],})(() => { const const a: number
a = const getNext: () => number
getNext(); const const b: number
b = const getNext: () => number
getNext(); const const c: number
c = const getNext: () => number
getNext(); // ...});Const variables
Section titled “Const variables”The meaning of const differs between JS and WGSL.
In JS, a const is a reference that cannot be reassigned, while in WGSL, it means a value known at shader-creation time.
Therefore, to use the WGSL const, TypeGPU provides tgpu.const(), an interface analogous to tgpu.privateVar() and tgpu.workgroupVar(), with the only difference being that the previously optional init value is now required.
const const Boid: d.WgslStruct<{ pos: d.Vec3f; vel: d.Vec3u;}>
Boid = import d
d.struct<{ pos: d.Vec3f; vel: d.Vec3u;}>(props: { pos: d.Vec3f; vel: d.Vec3u;}): d.WgslStruct<{ pos: d.Vec3f; vel: d.Vec3u;}>export struct
Creates a struct schema that can be used to construct GPU buffers.
Ensures proper alignment and padding of properties (as opposed to a d.unstruct schema).
The order of members matches the passed in properties object.
struct({ pos: d.Vec3f
pos: import d
d.const vec3f: d.Vec3fexport vec3f
Schema representing vec3f - a vector with 3 elements of type f32.
Also a constructor function for this vector value.
vec3f, vel: d.Vec3u
vel: import d
d.const vec3u: d.Vec3uexport vec3u
Schema representing vec3u - a vector with 3 elements of type u32.
Also a constructor function for this vector value.
vec3u,});
const const boid: TgpuConst<d.WgslStruct<{ pos: d.Vec3f; vel: d.Vec3u;}>>
boid = const tgpu: { const: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/constant/tgpuConstant").constant; fn: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/function/tgpuFn").fn; comptime: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/function/comptime").comptime; resolve: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/resolve/tgpuResolve").resolve; resolveWithContext: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/resolve/tgpuResolve").resolveWithContext; init: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/root/init").init; initFromDevice: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/root/init").initFromDevice; slot: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/slot/slot").slot; lazy: typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/core/slot/lazy").lazy; ... 10 more ...; '~unstable': typeof import("/home/runner/work/TypeGPU/TypeGPU/packages/typegpu/src/tgpuUnstable");}
tgpu.const: <d.WgslStruct<{ pos: d.Vec3f; vel: d.Vec3u;}>>(dataType: d.WgslStruct<{ pos: d.Vec3f; vel: d.Vec3u;}>, value: { pos: d.v3f; vel: d.v3u;}) => TgpuConst<d.WgslStruct<{ pos: d.Vec3f; vel: d.Vec3u;}>>
Creates a module constant with specified value.
const(const Boid: d.WgslStruct<{ pos: d.Vec3f; vel: d.Vec3u;}>
Boid, { pos: d.v3f
pos: import d
d.function vec3f(x: number, y: number, z: number): d.v3f (+5 overloads)export vec3f
Schema representing vec3f - a vector with 3 elements of type f32.
Also a constructor function for this vector value.
vec3f(1, 2, 3), vel: d.v3u
vel: import d
d.function vec3u(x: number, y: number, z: number): d.v3u (+5 overloads)export vec3u
Schema representing vec3u - a vector with 3 elements of type u32.
Also a constructor function for this vector value.
vec3u(4, 5, 6),});
const const func: () => void
func = () => { 'use gpu'; const const pos: { readonly pos: d.v3f; readonly vel: d.v3u;}
pos = const boid: TgpuConst<d.WgslStruct<{ pos: d.Vec3f; vel: d.Vec3u;}>>
boid.TgpuConst<WgslStruct<{ pos: Vec3f; vel: Vec3u; }>>.$: { readonly pos: d.v3f; readonly vel: d.v3u;}
$; const const vel: d.v3u
vel = const boid: TgpuConst<d.WgslStruct<{ pos: d.Vec3f; vel: d.Vec3u;}>>
boid.TgpuConst<WgslStruct<{ pos: Vec3f; vel: Vec3u; }>>.$: { readonly pos: d.v3f; readonly vel: d.v3u;}
$.vel: d.v3u
vel; const const velX: number
velX = const boid: TgpuConst<d.WgslStruct<{ pos: d.Vec3f; vel: d.Vec3u;}>>
boid.TgpuConst<WgslStruct<{ pos: Vec3f; vel: Vec3u; }>>.$: { readonly pos: d.v3f; readonly vel: d.v3u;}
$.vel: d.v3u
vel.v3u.x: number
x;};