From 8d4457c2085e30c7f57b03f81bb9f785a0991570 Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Mon, 16 Feb 2026 09:12:53 +0100 Subject: [PATCH 1/2] feat: Stabilize pipelines and entry functions --- README.md | 4 +- .../content/docs/ecosystem/typegpu-noise.mdx | 19 ++- .../content/docs/ecosystem/typegpu-sdf.mdx | 2 +- .../src/content/docs/fundamentals/buffers.mdx | 4 +- .../docs/fundamentals/enabling-features.mdx | 2 +- .../docs/fundamentals/functions/index.mdx | 28 ++-- .../content/docs/fundamentals/pipelines.mdx | 60 ++++---- .../src/content/docs/fundamentals/resolve.mdx | 6 +- .../src/content/docs/fundamentals/slots.mdx | 14 +- .../docs/fundamentals/timestamp-queries.mdx | 17 +-- .../src/content/docs/fundamentals/utils.mdx | 38 +---- .../content/docs/fundamentals/variables.mdx | 6 +- .../docs/integration/react-native/index.mdx | 45 +++--- .../algorithms/jump-flood-distance/index.ts | 68 ++++----- .../jump-flood-distance/visualization.ts | 2 +- .../algorithms/jump-flood-voronoi/index.ts | 81 +++++----- .../algorithms/matrix-next/computeShared.ts | 2 +- .../algorithms/matrix-next/computeSimple.ts | 2 +- .../examples/algorithms/matrix-next/index.ts | 4 +- .../algorithms/mnist-inference/index.ts | 8 +- .../algorithms/probability/executor.ts | 6 +- .../src/examples/geometry/circles/index.ts | 15 +- .../geometry/lines-combinations/index.ts | 84 +++++------ .../image-processing/ascii-filter/index.ts | 2 +- .../background-segmentation/index.ts | 20 +-- .../background-segmentation/shaders.ts | 2 +- .../examples/image-processing/blur/index.ts | 10 +- .../camera-thresholding/index.ts | 11 +- .../image-processing/chroma-keying/index.ts | 11 +- .../image-processing/image-tuning/index.ts | 11 +- .../src/examples/rendering/3d-fish/index.ts | 7 +- .../src/examples/rendering/3d-fish/render.ts | 4 +- .../rendering/box-raytracing/index.ts | 6 +- .../src/examples/rendering/caustics/index.ts | 6 +- .../src/examples/rendering/clouds/index.ts | 11 +- .../rendering/cubemap-reflection/icosphere.ts | 6 +- .../rendering/cubemap-reflection/index.ts | 12 +- .../src/examples/rendering/disco/index.ts | 2 +- .../rendering/disco/shaders/fragment.ts | 14 +- .../rendering/disco/shaders/vertex.ts | 2 +- .../rendering/function-visualizer/index.ts | 38 ++--- .../examples/rendering/jelly-slider/index.ts | 26 ++-- .../examples/rendering/jelly-slider/slider.ts | 2 +- .../examples/rendering/jelly-slider/taa.ts | 6 +- .../examples/rendering/jelly-switch/index.ts | 22 +-- .../examples/rendering/jelly-switch/taa.ts | 7 +- .../examples/rendering/perlin-noise/index.ts | 2 +- .../rendering/phong-reflection/index.ts | 6 +- .../rendering/point-light-shadow/index.ts | 90 ++++++------ .../examples/rendering/ray-marching/index.ts | 6 +- .../examples/rendering/simple-shadow/index.ts | 10 +- .../rendering/smoky-triangle/index.ts | 2 +- .../src/examples/rendering/two-boxes/index.ts | 6 +- .../rendering/xor-dev-centrifuge-2/index.ts | 6 +- .../rendering/xor-dev-runner/index.ts | 6 +- .../examples/simple/gradient-tiles/index.ts | 11 +- .../src/examples/simple/increment/index.ts | 2 +- .../src/examples/simple/liquid-glass/index.ts | 4 +- .../src/examples/simple/oklab/index.ts | 6 +- .../examples/simple/ripple-cube/background.ts | 2 +- .../src/examples/simple/ripple-cube/index.ts | 4 +- .../src/examples/simple/ripple-cube/pbr.ts | 4 +- .../simple/ripple-cube/post-processing.ts | 14 +- .../examples/simple/ripple-cube/sdf-scene.ts | 4 +- .../src/examples/simple/square/index.ts | 17 +-- .../src/examples/simple/stencil/index.ts | 42 +++--- .../examples/simple/triangle-next/index.ts | 2 +- .../src/examples/simple/triangle/index.ts | 15 +- .../src/examples/simple/vaporrave/index.ts | 8 +- .../src/examples/simulation/boids/index.ts | 26 ++-- .../src/examples/simulation/confetti/index.ts | 12 +- .../fluid-double-buffering/index.ts | 12 +- .../simulation/fluid-with-atomics/index.ts | 10 +- .../examples/simulation/game-of-life/index.ts | 23 +-- .../game-of-life/shaders/fragment.ts | 2 +- .../simulation/game-of-life/shaders/vertex.ts | 2 +- .../examples/simulation/gravity/compute.ts | 4 +- .../src/examples/simulation/gravity/index.ts | 8 +- .../src/examples/simulation/gravity/render.ts | 8 +- .../simulation/slime-mold-3d/index.ts | 16 +- .../examples/simulation/slime-mold/index.ts | 28 ++-- .../examples/simulation/stable-fluid/index.ts | 6 +- .../simulation/stable-fluid/render.ts | 8 +- .../simulation/stable-fluid/simulation.ts | 18 +-- .../src/examples/simulation/wind-map/index.ts | 21 ++- .../src/examples/tests/dispatch/index.ts | 18 +-- .../src/examples/tests/log-test/index.ts | 32 ++-- .../src/examples/tests/texture-test/index.ts | 11 +- .../examples/tests/tgsl-parsing-test/index.ts | 4 +- .../src/examples/tests/uniformity/index.ts | 28 ++-- .../examples/tests/wgsl-resolution/index.ts | 6 +- .../typegpu-geometry/src/lines/constants.ts | 2 +- .../src/perlin-2d/dynamic-cache.ts | 8 +- .../src/perlin-2d/static-cache.ts | 7 +- .../src/perlin-3d/dynamic-cache.ts | 7 +- .../src/perlin-3d/static-cache.ts | 7 +- packages/typegpu-sdf/README.md | 2 +- packages/typegpu/README.md | 2 +- .../typegpu/src/common/fullScreenTriangle.ts | 10 +- packages/typegpu/src/core/root/init.ts | 2 +- packages/typegpu/src/core/root/rootTypes.ts | 71 ++++++++- packages/typegpu/src/tgpu.ts | 3 + packages/typegpu/src/tgpuUnstable.ts | 15 +- .../typegpu/tests/computePipeline.test.ts | 38 ++--- .../typegpu/tests/entryFnBuiltinArgs.test.ts | 32 ++-- .../typegpu/tests/entryFnHeaderGen.test.ts | 10 +- packages/typegpu/tests/function.test.ts | 10 +- packages/typegpu/tests/functionTagged.test.ts | 12 +- packages/typegpu/tests/indent.test.ts | 2 +- .../typegpu/tests/pipeline-resolution.test.ts | 6 +- packages/typegpu/tests/rawFn.test.ts | 8 +- packages/typegpu/tests/renderPipeline.test.ts | 138 +++++++++--------- packages/typegpu/tests/resolve.test.ts | 4 +- packages/typegpu/tests/root.test.ts | 6 +- packages/typegpu/tests/texture.test.ts | 6 +- packages/typegpu/tests/tgpuGenericFn.test.ts | 16 +- .../typegpu/tests/tgsl/consoleLog.test.ts | 40 +++-- .../tests/tgsl/ternaryOperator.test.ts | 2 +- .../typegpu/tests/tgsl/wgslGenerator.test.ts | 2 +- packages/typegpu/tests/tgslFn.test.ts | 32 ++-- .../typegpu/tests/unplugin/autoname.test.ts | 17 +-- .../unplugin-typegpu/test/auto-naming.test.ts | 25 ++-- 122 files changed, 942 insertions(+), 927 deletions(-) diff --git a/README.md b/README.md index a36d402301..f35a4ff3cd 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,7 @@ const wgsl = tgpu.resolve([main]); // // #3) Executed on the GPU (generates WGSL underneath) // -root['~unstable'] - .createGuardedComputePipeline(main) - .dispatchThreads(); +root.createGuardedComputePipeline(main).dispatchThreads(); ```
diff --git a/apps/typegpu-docs/src/content/docs/ecosystem/typegpu-noise.mdx b/apps/typegpu-docs/src/content/docs/ecosystem/typegpu-noise.mdx index 250fb788d4..58b14520fb 100644 --- a/apps/typegpu-docs/src/content/docs/ecosystem/typegpu-noise.mdx +++ b/apps/typegpu-docs/src/content/docs/ecosystem/typegpu-noise.mdx @@ -84,7 +84,7 @@ using a set of `randf.seedN` functions, where `N` is the number of components ou import tgpu, { d } from 'typegpu'; import { randf } from '@typegpu/noise'; -const main = tgpu['~unstable'].fragmentFn({ +const main = tgpu.fragmentFn({ in: { pos: d.builtin.position }, out: d.vec4f, })(({ pos }) => { @@ -148,7 +148,7 @@ import tgpu, { d } from 'typegpu'; // ---cut--- import { perlin2d } from '@typegpu/noise'; -const main = tgpu['~unstable'].fragmentFn({ +const main = tgpu.fragmentFn({ in: { pos: d.builtin.position }, out: d.vec4f, })(({ pos }) => { @@ -169,7 +169,7 @@ import tgpu, { d } from 'typegpu'; const root = await tgpu.init(); import { perlin3d } from '@typegpu/noise'; -const main = tgpu['~unstable'].computeFn({ workgroupSize: [1] })(() => { +const main = tgpu.computeFn({ workgroupSize: [1] })(() => { const value = perlin3d.sample(d.vec3f(0.5, 0, 0)); const wrappedValue = perlin3d.sample(d.vec3f(10.5, 0, 0)); // the same as `value`! }); @@ -177,7 +177,7 @@ const main = tgpu['~unstable'].computeFn({ workgroupSize: [1] })(() => { // ---cut--- const cache = perlin3d.staticCache({ root, size: d.vec3u(10, 10, 1) }); -const pipeline = root['~unstable'] +const pipeline = root // Plugging the cache into the pipeline .pipe(cache.inject()) // ... @@ -224,7 +224,7 @@ complex setup. import tgpu, { d } from 'typegpu'; import { perlin3d } from '@typegpu/noise'; -const main = tgpu['~unstable'].computeFn({ workgroupSize: [1] })(() => { +const main = tgpu.computeFn({ workgroupSize: [1] })(() => { const value = perlin3d.sample(d.vec3f(0.5, 0, 0)); const wrappedValue = perlin3d.sample(d.vec3f(10.5, 0, 0)); // the same as `value`! }); @@ -235,7 +235,7 @@ const cacheConfig = perlin3d.dynamicCacheConfig(); // Holds all resources the perlin cache needs access to const dynamicLayout = tgpu.bindGroupLayout({ ...cacheConfig.layout }); -const pipeline = root['~unstable'] +const pipeline = root // Plugging the cache into the pipeline .pipe(cacheConfig.inject(dynamicLayout.$)) // ... @@ -272,7 +272,7 @@ import { randf } from '@typegpu/noise'; const root = await tgpu.init(); const b = root.createMutable(d.f32); -const f = tgpu['~unstable'].computeFn({ workgroupSize: [1] })(() => { +const f = tgpu.computeFn({ workgroupSize: [1] })(() => { b.$ = randf.sample(); }); // ---cut--- @@ -304,8 +304,7 @@ const LCG: StatefulGenerator = (() => { }; })(); -const pipeline = root['~unstable'] +const pipeline = root .with(randomGeneratorSlot, LCG) - .withCompute(f) - .createPipeline(); + .createComputePipeline({ compute: f }); ``` diff --git a/apps/typegpu-docs/src/content/docs/ecosystem/typegpu-sdf.mdx b/apps/typegpu-docs/src/content/docs/ecosystem/typegpu-sdf.mdx index fb7ff4376a..700e5a1a2c 100644 --- a/apps/typegpu-docs/src/content/docs/ecosystem/typegpu-sdf.mdx +++ b/apps/typegpu-docs/src/content/docs/ecosystem/typegpu-sdf.mdx @@ -25,7 +25,7 @@ Here is an example of a fragment shader that draws a disk of radius 0.25 on the import tgpu, { d } from 'typegpu'; import * as sdf from '@typegpu/sdf'; -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { diff --git a/apps/typegpu-docs/src/content/docs/fundamentals/buffers.mdx b/apps/typegpu-docs/src/content/docs/fundamentals/buffers.mdx index 07b6ed5fe2..e4cc924e73 100644 --- a/apps/typegpu-docs/src/content/docs/fundamentals/buffers.mdx +++ b/apps/typegpu-docs/src/content/docs/fundamentals/buffers.mdx @@ -338,7 +338,7 @@ const layout = tgpu.bindGroupLayout({ points: { storage: d.arrayOf(d.vec2i), access: 'mutable' }, }); -const pipeline = root['~unstable'].createGuardedComputePipeline((x) => { +const pipeline = root.createGuardedComputePipeline((x) => { 'use gpu'; // Access and modify the bound buffer via the layout layout.$.points[x] = d.vec2i(1, 2); @@ -374,7 +374,7 @@ const root = await tgpu.init(); // ---cut--- const pointsMutable = root.createMutable(d.arrayOf(d.vec2i, 100)); -const pipeline = root['~unstable'].createGuardedComputePipeline((x) => { +const pipeline = root.createGuardedComputePipeline((x) => { 'use gpu'; // Access and modify the fixed buffer directly pointsMutable.$[x] = d.vec2i(); diff --git a/apps/typegpu-docs/src/content/docs/fundamentals/enabling-features.mdx b/apps/typegpu-docs/src/content/docs/fundamentals/enabling-features.mdx index 3eb8da8a68..945da33a9c 100644 --- a/apps/typegpu-docs/src/content/docs/fundamentals/enabling-features.mdx +++ b/apps/typegpu-docs/src/content/docs/fundamentals/enabling-features.mdx @@ -31,7 +31,7 @@ const root = await tgpu.init({ }, // …other TypeGPU options… }); -```` +``` * **`requiredFeatures: GPUFeatureName[]`** All listed features must be supported by the GPU; otherwise `requestDevice()` rejects. diff --git a/apps/typegpu-docs/src/content/docs/fundamentals/functions/index.mdx b/apps/typegpu-docs/src/content/docs/fundamentals/functions/index.mdx index 8110547e67..1cfaea38f4 100644 --- a/apps/typegpu-docs/src/content/docs/fundamentals/functions/index.mdx +++ b/apps/typegpu-docs/src/content/docs/fundamentals/functions/index.mdx @@ -63,10 +63,8 @@ const wgsl = tgpu.resolve([main]); // ^? // #3) Executed on the GPU (generates WGSL underneath) -root['~unstable'] - .createGuardedComputePipeline(main) - .dispatchThreads(); -```` +root.createGuardedComputePipeline(main).dispatchThreads(); +``` The contents of the `wgsl` variable would contain the following: @@ -81,7 +79,7 @@ fn main() -> vec2f { } // ... -```` +``` You can already notice a few things about TypeGPU functions: - Using operators like `+`, `-`, `*`, `/`, etc. is perfectly valid on numbers. @@ -257,7 +255,7 @@ const settings = { speed: 1, }; -const pipeline = root['~unstable'].createGuardedComputePipeline(() => { +const pipeline = root.createGuardedComputePipeline(() => { 'use gpu'; const speed = settings.speed; // ^ generates: var speed = 1; @@ -456,9 +454,9 @@ Entry functions are an *unstable* feature. The API may be subject to change in t Instead of annotating a `TgpuFn` with attributes, entry functions are defined using dedicated shell constructors: -- `tgpu['~unstable'].computeFn`, -- `tgpu['~unstable'].vertexFn`, -- `tgpu['~unstable'].fragmentFn`. +- `tgpu.computeFn`, +- `tgpu.vertexFn`, +- `tgpu.fragmentFn`. ### Entry point function I/O @@ -510,7 +508,7 @@ const deltaTime = root.createUniform(d.f32); const time = root.createMutable(d.f32); const particleDataStorage = particleDataBuffer.as('mutable'); // ---cut--- -const mainCompute = tgpu['~unstable'].computeFn({ +const mainCompute = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [1], }) /* wgsl */`{ @@ -561,7 +559,7 @@ import tgpu, { d } from 'typegpu'; const getGradientColor = tgpu.fn([d.f32], d.vec4f)``; // ---cut--- -const mainVertex = tgpu['~unstable'].vertexFn({ +const mainVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { outPos: d.builtin.position, uv: d.vec2f }, }) /* wgsl */`{ @@ -580,7 +578,7 @@ const mainVertex = tgpu['~unstable'].vertexFn({ return Out(vec4f(pos[in.vertexIndex], 0.0, 1.0), uv[in.vertexIndex]); }`; -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, }) /* wgsl */`{ @@ -646,17 +644,17 @@ const root = await tgpu.init(); const getGradientColor = tgpu.fn([d.f32], d.vec4f)/* wgsl */``; -const mainVertex = tgpu['~unstable'].vertexFn({ +const mainVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { outPos: d.builtin.position, uv: d.vec2f }, })``; -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })``; // ---cut--- -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ vertex: mainVertex, fragment: mainFragment, targets: { format: presentationFormat }, diff --git a/apps/typegpu-docs/src/content/docs/fundamentals/pipelines.mdx b/apps/typegpu-docs/src/content/docs/fundamentals/pipelines.mdx index ed0670420a..90bcebedd5 100644 --- a/apps/typegpu-docs/src/content/docs/fundamentals/pipelines.mdx +++ b/apps/typegpu-docs/src/content/docs/fundamentals/pipelines.mdx @@ -31,7 +31,7 @@ const root = await tgpu.init(); const presentationFormat = 'rgba8unorm'; -const mainVertex = tgpu['~unstable'].vertexFn({ +const mainVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { pos: d.builtin.position }, })((input) => { @@ -42,27 +42,25 @@ const mainVertex = tgpu['~unstable'].vertexFn({ }; }); -const mainFragment = tgpu['~unstable'] - .fragmentFn({ out: d.vec4f })(() => d.vec4f(1, 0, 0, 1)); +const mainFragment = tgpu.fragmentFn({ out: d.vec4f })(() => d.vec4f(1, 0, 0, 1)); -const mainCompute = tgpu['~unstable'].computeFn({ workgroupSize: [1] })(() => {}); +const mainCompute = tgpu.computeFn({ workgroupSize: [1] })(() => {}); // ---cut--- -const renderPipeline = root['~unstable'].createRenderPipeline({ +const renderPipeline = root.createRenderPipeline({ vertex: mainVertex, fragment: mainFragment, targets: { format: presentationFormat }, }); -const computePipeline1 = root['~unstable'].createComputePipeline({ +const computePipeline1 = root.createComputePipeline({ compute: mainCompute, }); -const computePipeline2 = root['~unstable'] - .createGuardedComputePipeline((x, y, z) => { - 'use gpu'; - // ... - }); +const computePipeline2 = root.createGuardedComputePipeline((x, y, z) => { + 'use gpu'; + // ... +}); ``` ### createRenderPipeline @@ -84,7 +82,7 @@ import tgpu, { d } from 'typegpu'; const root = await tgpu.init(); const presentationFormat = 'rgba8unorm'; -const mainVertex = tgpu['~unstable'].vertexFn({ +const mainVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex, pos: d.vec2f }, out: { pos: d.builtin.position }, })((input) => { @@ -95,12 +93,11 @@ const mainVertex = tgpu['~unstable'].vertexFn({ }; }); -const mainFragment = tgpu['~unstable'] - .fragmentFn({ out: d.vec4f })(() => d.vec4f(1, 0, 0, 1)); +const mainFragment = tgpu.fragmentFn({ out: d.vec4f })(() => d.vec4f(1, 0, 0, 1)); // ---cut--- const vertexLayout = tgpu.vertexLayout(d.arrayOf(d.vec2f)); -const renderPipeline = root['~unstable'].createRenderPipeline({ +const renderPipeline = root.createRenderPipeline({ attribs: { pos: vertexLayout.attrib }, vertex: mainVertex, fragment: mainFragment, @@ -132,10 +129,10 @@ as long as there is no conflict between vertex and fragment location values. ```ts twoslash import tgpu, { d } from 'typegpu'; -const vertex = tgpu['~unstable'].vertexFn({ +const vertex = tgpu.vertexFn({ out: { pos: d.builtin.position }, })`(...)`; -const fragment = tgpu['~unstable'].fragmentFn({ +const fragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })`(...)`; @@ -143,7 +140,7 @@ const fragment = tgpu['~unstable'].fragmentFn({ const root = await tgpu.init(); // @errors: 2769 -root['~unstable'].createRenderPipeline({ +root.createRenderPipeline({ vertex, fragment, targets: { format: 'bgra8unorm' }, @@ -163,10 +160,10 @@ import tgpu, { d } from 'typegpu'; const root = await tgpu.init(); -const mainCompute = tgpu['~unstable'].computeFn({ workgroupSize: [1] })(() => {}); +const mainCompute = tgpu.computeFn({ workgroupSize: [1] })(() => {}); // ---cut--- -const computePipeline = root['~unstable'].createComputePipeline({ +const computePipeline = root.createComputePipeline({ compute: mainCompute, }); ``` @@ -188,11 +185,10 @@ const root = await tgpu.init(); // ---cut--- const data = root.createMutable(d.arrayOf(d.u32, 8), [0, 1, 2, 3, 4, 5, 6, 7]); -const doubleUpPipeline = root['~unstable'] - .createGuardedComputePipeline((x) => { - 'use gpu'; - data.$[x] *= 2; - }); +const doubleUpPipeline = root.createGuardedComputePipeline((x) => { + 'use gpu'; + data.$[x] *= 2; +}); doubleUpPipeline.dispatchThreads(8); doubleUpPipeline.dispatchThreads(8); @@ -229,7 +225,7 @@ const waterLevelMutable = root.createMutable( d.arrayOf(d.arrayOf(d.f32, 512), 1024), ); -root['~unstable'].createGuardedComputePipeline((x, y) => { +root.createGuardedComputePipeline((x, y) => { 'use gpu'; randf.seed2(d.vec2f(x, y).div(1024)); waterLevelMutable.$[x][y] = 10 + randf.sample(); @@ -368,7 +364,7 @@ const colorBuffer = root ]) .$usage('vertex'); -const vertex = tgpu['~unstable'].vertexFn({ +const vertex = tgpu.vertexFn({ in: { idx: d.builtin.vertexIndex, color: d.vec4f, @@ -385,7 +381,7 @@ const vertex = tgpu['~unstable'].vertexFn({ }); const vertexLayout = tgpu.vertexLayout(d.arrayOf(d.vec4f)); -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { color: d.vec4f, }, @@ -396,7 +392,7 @@ const indexBuffer = root .createBuffer(d.arrayOf(d.u16, 6), [0, 2, 1, 0, 3, 2]) .$usage('index'); -const pipeline = root['~unstable'] +const pipeline = root .createRenderPipeline({ attribs: { color: vertexLayout.attrib }, vertex, @@ -440,11 +436,11 @@ import tgpu, { d } from 'typegpu'; const root = await tgpu.init(); -const mainVertex = tgpu['~unstable'].vertexFn({ out: { pos: d.builtin.position } })`...`; -const mainFragment = tgpu['~unstable'].fragmentFn({ out: d.vec4f })`...`; +const mainVertex = tgpu.vertexFn({ out: { pos: d.builtin.position } })`...`; +const mainFragment = tgpu.fragmentFn({ out: d.vec4f })`...`; // ---cut--- -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ vertex: mainVertex, fragment: mainFragment, targets: { format: 'rg8unorm' }, diff --git a/apps/typegpu-docs/src/content/docs/fundamentals/resolve.mdx b/apps/typegpu-docs/src/content/docs/fundamentals/resolve.mdx index 047a58472a..ec848c0e29 100644 --- a/apps/typegpu-docs/src/content/docs/fundamentals/resolve.mdx +++ b/apps/typegpu-docs/src/content/docs/fundamentals/resolve.mdx @@ -64,7 +64,7 @@ const root = await tgpu.init(); const dataMutable = root .createMutable(d.arrayOf(d.u32, 8), [1, 2, 3, 4, 5, 6, 7, 8]); -const computeMain = tgpu['~unstable'].computeFn({ +const computeMain = tgpu.computeFn({ workgroupSize: [1], in: { gid: d.builtin.globalInvocationId }, })((input) => { @@ -72,9 +72,7 @@ const computeMain = tgpu['~unstable'].computeFn({ dataMutable.$[index] *= 2; }); -const multiplyPipeline = root['~unstable'] - .withCompute(computeMain) - .createPipeline(); +const multiplyPipeline = root.createComputePipeline({ compute: computeMain }); const resolved = tgpu.resolve([multiplyPipeline]); ``` diff --git a/apps/typegpu-docs/src/content/docs/fundamentals/slots.mdx b/apps/typegpu-docs/src/content/docs/fundamentals/slots.mdx index 62bb03cc48..b77c468b10 100644 --- a/apps/typegpu-docs/src/content/docs/fundamentals/slots.mdx +++ b/apps/typegpu-docs/src/content/docs/fundamentals/slots.mdx @@ -98,15 +98,13 @@ const root = await tgpu.init(); const resultBuffer = root.createMutable(d.i32, 0); const multiplierSlot = tgpu.slot(); -const computeMultiply = tgpu['~unstable'] - .computeFn({ workgroupSize: [1] })(() => { - resultBuffer.$ = resultBuffer.$ * multiplierSlot.$; - }); +const computeMultiply = tgpu.computeFn({ workgroupSize: [1] })(() => { + resultBuffer.$ = resultBuffer.$ * multiplierSlot.$; +}); -const pipeline = root['~unstable'] +const pipeline = root .with(multiplierSlot, 3) - .withCompute(computeMultiply) - .createPipeline(); + .createComputePipeline({ compute: computeMultiply }); ``` The pipeline above resolves to the following WGSL: @@ -174,7 +172,7 @@ const gravityTowardsCenter = tgpu.fn([vec2f], vec2f)((pos) => { const stepPhysicsCustomized = stepPhysics .with(gravitySlot, gravityTowardsCenter); -const main = tgpu['~unstable'].computeFn()(() => { +const main = tgpu.computeFn()(() => { stepPhysicsCustomized(); // <- Will use altered gravity. }); ``` diff --git a/apps/typegpu-docs/src/content/docs/fundamentals/timestamp-queries.mdx b/apps/typegpu-docs/src/content/docs/fundamentals/timestamp-queries.mdx index a0e8a1fd69..e5f46afaf5 100644 --- a/apps/typegpu-docs/src/content/docs/fundamentals/timestamp-queries.mdx +++ b/apps/typegpu-docs/src/content/docs/fundamentals/timestamp-queries.mdx @@ -23,14 +23,13 @@ TypeGPU offers two ways to employ timestamp queries: Rather than managing query sets yourself, you can measure shader dispatch times easily by chaining `.withPerformanceCallback()` onto a compute or render pipeline: ```ts -const pipeline = root['~unstable'] - .withCompute(computeShader) - .createPipeline() +const pipeline = root + .createComputePipeline({ compute: computeShader }) .withPerformanceCallback((start, end) => { const durationNs = Number(end - start); console.log(`Pipeline execution time: ${durationNs} ns`); }); -```` +``` * **Callback signature** @@ -56,9 +55,8 @@ For finer control, create and manage your own `TgpuQuerySet`. You can attach it // Create a query set with two timestamp slots const querySet = root.createQuerySet('timestamp', 2); -const pipeline = root['~unstable'] - .withCompute(computeShader) - .createPipeline() +const pipeline = root + .createComputePipeline({ compute: computeShader }) .withTimestampWrites({ querySet: querySet, beginningOfPassWriteIndex: 0, // Write start time at index 0 @@ -137,9 +135,8 @@ You can use a custom query set and still attach a performance callback. TypeGPU ```ts const querySet = root.createQuerySet('timestamp', 36); -const pipeline = root['~unstable'] - .withCompute(computeShader) - .createPipeline() +const pipeline = root + .createComputePipeline({ compute: computeShader }) .withTimestampWrites({ querySet: querySet, beginningOfPassWriteIndex: 3, // start at slot 3 diff --git a/apps/typegpu-docs/src/content/docs/fundamentals/utils.mdx b/apps/typegpu-docs/src/content/docs/fundamentals/utils.mdx index a62cb0da96..82716f3d60 100644 --- a/apps/typegpu-docs/src/content/docs/fundamentals/utils.mdx +++ b/apps/typegpu-docs/src/content/docs/fundamentals/utils.mdx @@ -3,40 +3,6 @@ title: Utilities description: A list of various utilities provided by TypeGPU. --- -## *tgpu.comptime* - -`tgpu['~unstable'].comptime(func)` creates a version of `func` that instead of being transpiled to WGSL, will be called during the WGSL code generation. -This can be used to precompute and inject a value into the final shader code. - -```ts twoslash -import tgpu, { d } from 'typegpu'; - -// ---cut--- -const color = tgpu['~unstable'] - .comptime((int: number) => { - const r = (int >> 16) & 0xff; - const g = (int >> 8) & 0xff; - const b = int & 0xff; - return d.vec3f(r / 255, g / 255, b / 255); - }); - -const material = tgpu.fn([d.vec3f], d.vec3f)((diffuse) => { - 'use gpu'; - const albedo = color(0xff00ff); - return albedo.mul(diffuse); -}); - -const shader = tgpu.resolve([material]); -// fn material(diffuse: vec3f) -> vec3f { -// var albedo = vec3f(1, 0, 1); -// return (albedo * diffuse); -// } -``` - -Note how the function passed into `comptime` doesn't have to be marked with -`'use gpu'` and can use `Math`. That's because the function doesn't execute on the GPU, it gets -executed before the shader code gets sent to the GPU. - ## *tgpu.rawCodeSnippet* When working on top of some existing shader code, sometimes you may know for certain that some variable will be already defined and should be accessible in the code. @@ -232,7 +198,7 @@ import tgpu, { d } from 'typegpu'; const root = await tgpu.init(); // ---cut--- const callCountMutable = root.createMutable(d.u32, 0); -const compute = root['~unstable'].createGuardedComputePipeline(() => { +const compute = root.createGuardedComputePipeline(() => { 'use gpu'; callCountMutable.$ += 1; console.log('Call number', callCountMutable.$); @@ -269,7 +235,7 @@ const root = await tgpu.init({ /* vertex shader */ -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { pos: d.builtin.position }, out: d.vec4f, })(({ pos }) => { diff --git a/apps/typegpu-docs/src/content/docs/fundamentals/variables.mdx b/apps/typegpu-docs/src/content/docs/fundamentals/variables.mdx index 9f21530861..835339e216 100644 --- a/apps/typegpu-docs/src/content/docs/fundamentals/variables.mdx +++ b/apps/typegpu-docs/src/content/docs/fundamentals/variables.mdx @@ -17,7 +17,7 @@ const root = await tgpu.init(); // ---cut--- const counter = root.createMutable(d.vec3f, d.vec3f(0, 1, 0)); -const increment = tgpu['~unstable'].computeFn({ +const increment = tgpu.computeFn({ in: { num: d.builtin.numWorkgroups }, workgroupSize: [1], })((input) => { @@ -27,7 +27,7 @@ const increment = tgpu['~unstable'].computeFn({ counter.$.z += d.f32(input.num.x); }); -const pipeline = root['~unstable'].withCompute(increment).createPipeline(); +const pipeline = root.createComputePipeline({ compute: increment }); console.log(tgpu.resolve([pipeline])); ``` @@ -65,7 +65,7 @@ const getNext = () => { return [42, 418, 23][threadCounter.$]; }; -const myComputeFn = tgpu['~unstable'].computeFn({ +const myComputeFn = tgpu.computeFn({ workgroupSize: [64], })(() => { const a = getNext(); diff --git a/apps/typegpu-docs/src/content/docs/integration/react-native/index.mdx b/apps/typegpu-docs/src/content/docs/integration/react-native/index.mdx index 8d951e5f37..1d454ed75b 100644 --- a/apps/typegpu-docs/src/content/docs/integration/react-native/index.mdx +++ b/apps/typegpu-docs/src/content/docs/integration/react-native/index.mdx @@ -115,20 +115,17 @@ import { useEffect } from 'react'; import { Canvas, useDevice, useGPUContext } from 'react-native-wgpu'; import tgpu, { d } from 'typegpu'; -const mainVertex = tgpu['~unstable'].vertexFn({ - in: { vertexIndex: d.builtin.vertexIndex }, - out: { outPos: d.builtin.position, uv: d.vec2f }, -})/* wgsl */ `{ - var pos = array(vec2(0.0, 0.5), vec2(-0.5, -0.5), vec2(0.5, -0.5)); - var uv = array(vec2(0.5, 1.0), vec2(0.0, 0.0), vec2(1.0, 0.0)); - return Out(vec4f(pos[in.vertexIndex], 0.0, 1.0), uv[in.vertexIndex]); -}`; - -const blue = d.vec4f(0.114, 0.447, 0.941, 1); -const mainFragment = tgpu['~unstable'].fragmentFn({ - in: { uv: d.vec2f }, - out: d.vec4f, -})`{ return blue; }`.$uses({ blue }); +const positions = tgpu.const(d.arrayOf(d.vec2f, 3), [ + d.vec2f(0.0, 0.5), + d.vec2f(-0.5, -0.5), + d.vec2f(0.5, -0.5), +]); + +const uvs = tgpu.const(d.arrayOf(d.vec2f, 3), [ + d.vec2f(0.5, 1.0), + d.vec2f(0.0, 0.0), + d.vec2f(1.0, 0.0), +]); export function Triangle() { const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); @@ -147,10 +144,22 @@ export function Triangle() { alphaMode: 'premultiplied', }); - root['~unstable'] - .withVertex(mainVertex, {}) - .withFragment(mainFragment, { format: presentationFormat }) - .createPipeline() + const pipeline = root.createRenderPipeline({ + vertex: ({ $vertexIndex: vid }) => { + 'use gpu'; + return { + $position: d.vec4f(positions.$[vid], 0, 1), + uv: uvs.$[vid], + }; + }, + fragment: () => { + 'use gpu'; + return d.vec4f(0.114, 0.447, 0.941, 1); + }, + targets: { format: presentationFormat }, + }); + + pipeline .withColorAttachment({ view: context.getCurrentTexture().createView(), clearValue: [0, 0, 0, 0], diff --git a/apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/index.ts b/apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/index.ts index 4fb89b5277..68ed8df8ab 100644 --- a/apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/index.ts +++ b/apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/index.ts @@ -151,7 +151,7 @@ const sampleWithOffset = ( }); }; -const initFromMask = root['~unstable'].createGuardedComputePipeline((x, y) => { +const initFromMask = root.createGuardedComputePipeline((x, y) => { 'use gpu'; const size = std.textureDimensions(initFromMaskLayout.$.writeView); const pos = d.vec2f(x, y); @@ -175,7 +175,7 @@ const initFromMask = root['~unstable'].createGuardedComputePipeline((x, y) => { ); }); -const jumpFlood = root['~unstable'].createGuardedComputePipeline((x, y) => { +const jumpFlood = root.createGuardedComputePipeline((x, y) => { 'use gpu'; const offset = offsetUniform.$; const size = std.textureDimensions(pingPongLayout.$.readView); @@ -225,7 +225,7 @@ const jumpFlood = root['~unstable'].createGuardedComputePipeline((x, y) => { ); }); -const drawSeed = root['~unstable'].createGuardedComputePipeline((x, y) => { +const drawSeed = root.createGuardedComputePipeline((x, y) => { 'use gpu'; const brushParams = brushUniform.$; const pos = d.vec2f(x, y); @@ -242,45 +242,45 @@ const drawSeed = root['~unstable'].createGuardedComputePipeline((x, y) => { ); }); -const createDistanceField = root['~unstable'].createGuardedComputePipeline( - (x, y) => { - 'use gpu'; - const pos = d.vec2f(x, y); - const size = std.textureDimensions(pingPongLayout.$.readView); - const texel = std.textureLoad( - pingPongLayout.$.readView, - d.vec2i(x, y), - ); +const createDistanceField = root.createGuardedComputePipeline((x, y) => { + 'use gpu'; + const pos = d.vec2f(x, y); + const size = std.textureDimensions(pingPongLayout.$.readView); + const texel = std.textureLoad( + pingPongLayout.$.readView, + d.vec2i(x, y), + ); - const insideCoord = texel.xy; - const outsideCoord = texel.zw; + const insideCoord = texel.xy; + const outsideCoord = texel.zw; - let insideDist = 1e20; - let outsideDist = 1e20; + let insideDist = 1e20; + let outsideDist = 1e20; - if (insideCoord.x >= 0) { - insideDist = std.distance(pos, insideCoord.mul(d.vec2f(size))); - } + if (insideCoord.x >= 0) { + insideDist = std.distance(pos, insideCoord.mul(d.vec2f(size))); + } - if (outsideCoord.x >= 0) { - outsideDist = std.distance(pos, outsideCoord.mul(d.vec2f(size))); - } + if (outsideCoord.x >= 0) { + outsideDist = std.distance(pos, outsideCoord.mul(d.vec2f(size))); + } - const signedDist = insideDist - outsideDist; + const signedDist = insideDist - outsideDist; - std.textureStore( - distWriteLayout.$.distTexture, - d.vec2i(x, y), - d.vec4f(signedDist, 0, 0, 0), - ); - }, -); + std.textureStore( + distWriteLayout.$.distTexture, + d.vec2i(x, y), + d.vec4f(signedDist, 0, 0, 0), + ); +}); -const distancePipeline = root['~unstable'] +const distancePipeline = root .with(paramsAccess, paramsUniform) - .withVertex(common.fullScreenTriangle) - .withFragment(distanceFrag, { format: presentationFormat }) - .createPipeline(); + .createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: distanceFrag, + targets: { format: presentationFormat }, + }); function swap() { sourceIdx ^= 1; diff --git a/apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/visualization.ts b/apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/visualization.ts index 1ec41eb461..69115ea1fe 100644 --- a/apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/visualization.ts +++ b/apps/typegpu-docs/src/examples/algorithms/jump-flood-distance/visualization.ts @@ -17,7 +17,7 @@ const insideGradient = tgpu.const(d.arrayOf(d.vec3f, 5), [ d.vec3f(0.9, 1.0, 0.95), ]); -export const distanceFrag = tgpu['~unstable'].fragmentFn({ +export const distanceFrag = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { diff --git a/apps/typegpu-docs/src/examples/algorithms/jump-flood-voronoi/index.ts b/apps/typegpu-docs/src/examples/algorithms/jump-flood-voronoi/index.ts index ae8046c8a5..4dc902f70e 100644 --- a/apps/typegpu-docs/src/examples/algorithms/jump-flood-voronoi/index.ts +++ b/apps/typegpu-docs/src/examples/algorithms/jump-flood-voronoi/index.ts @@ -98,42 +98,40 @@ function createResources() { let resources = createResources(); -const initializeRandom = root['~unstable'].createGuardedComputePipeline( - (x, y) => { - 'use gpu'; - const size = std.textureDimensions(initLayout.$.writeView); - randf.seed2(d.vec2f(x, y).div(d.vec2f(size)).add(timeUniform.$)); - - const randomVal = randf.sample(); - const isSeed = randomVal >= seedThresholdUniform.$; - - const paletteColor = palette.$[d.u32(std.floor(randf.sample() * 4))]; - const variation = d.vec3f( - randf.sample() - 0.5, - randf.sample() - 0.5, - randf.sample() - 0.5, - ).mul(0.15); - - const color = std.select( - d.vec4f(), - d.vec4f(std.saturate(paletteColor.add(variation)), 1), - isSeed, - ); - const coord = std.select( - d.vec2f(-1), - d.vec2f(x, y).div(d.vec2f(size)), - isSeed, - ); +const initializeRandom = root.createGuardedComputePipeline((x, y) => { + 'use gpu'; + const size = std.textureDimensions(initLayout.$.writeView); + randf.seed2(d.vec2f(x, y).div(d.vec2f(size)).add(timeUniform.$)); + + const randomVal = randf.sample(); + const isSeed = randomVal >= seedThresholdUniform.$; + + const paletteColor = palette.$[d.u32(std.floor(randf.sample() * 4))]; + const variation = d.vec3f( + randf.sample() - 0.5, + randf.sample() - 0.5, + randf.sample() - 0.5, + ).mul(0.15); + + const color = std.select( + d.vec4f(), + d.vec4f(std.saturate(paletteColor.add(variation)), 1), + isSeed, + ); + const coord = std.select( + d.vec2f(-1), + d.vec2f(x, y).div(d.vec2f(size)), + isSeed, + ); - std.textureStore(initLayout.$.writeView, d.vec2i(x, y), 0, color); - std.textureStore( - initLayout.$.writeView, - d.vec2i(x, y), - 1, - d.vec4f(coord, 0, 0), - ); - }, -); + std.textureStore(initLayout.$.writeView, d.vec2i(x, y), 0, color); + std.textureStore( + initLayout.$.writeView, + d.vec2i(x, y), + 1, + d.vec4f(coord, 0, 0), + ); +}); const sampleWithOffset = ( tex: d.textureStorage2dArray<'rgba16float', 'read-only'>, @@ -159,7 +157,7 @@ const sampleWithOffset = ( }); }; -const jumpFlood = root['~unstable'].createGuardedComputePipeline((x, y) => { +const jumpFlood = root.createGuardedComputePipeline((x, y) => { 'use gpu'; const offset = offsetUniform.$; const size = std.textureDimensions(pingPongLayout.$.readView); @@ -201,7 +199,7 @@ const jumpFlood = root['~unstable'].createGuardedComputePipeline((x, y) => { ); }); -const voronoiFrag = tgpu['~unstable'].fragmentFn({ +const voronoiFrag = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => @@ -212,10 +210,11 @@ const voronoiFrag = tgpu['~unstable'].fragmentFn({ ) ); -const voronoiPipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle, {}) - .withFragment(voronoiFrag, { format: presentationFormat }) - .createPipeline(); +const voronoiPipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: voronoiFrag, + targets: { format: presentationFormat }, +}); const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/apps/typegpu-docs/src/examples/algorithms/matrix-next/computeShared.ts b/apps/typegpu-docs/src/examples/algorithms/matrix-next/computeShared.ts index 6e0c94953b..b611003b0e 100644 --- a/apps/typegpu-docs/src/examples/algorithms/matrix-next/computeShared.ts +++ b/apps/typegpu-docs/src/examples/algorithms/matrix-next/computeShared.ts @@ -15,7 +15,7 @@ const getTileIndex = tgpu.fn([d.u32, d.u32], d.u32)((row, col) => { return col + row * TILE_SIZE; }); -export const computeSharedMemory = tgpu['~unstable'].computeFn({ +export const computeSharedMemory = tgpu.computeFn({ workgroupSize: WORKGROUP_SIZE, in: { gid: d.builtin.globalInvocationId, diff --git a/apps/typegpu-docs/src/examples/algorithms/matrix-next/computeSimple.ts b/apps/typegpu-docs/src/examples/algorithms/matrix-next/computeSimple.ts index 80d05a33df..4aefc9266e 100644 --- a/apps/typegpu-docs/src/examples/algorithms/matrix-next/computeSimple.ts +++ b/apps/typegpu-docs/src/examples/algorithms/matrix-next/computeSimple.ts @@ -3,7 +3,7 @@ import { getIndex } from './computeShared.ts'; import { WORKGROUP_SIZE } from './params.ts'; import { computeLayout } from './types.ts'; -export const computeSimple = tgpu['~unstable'].computeFn({ +export const computeSimple = tgpu.computeFn({ workgroupSize: WORKGROUP_SIZE, in: { gid: d.builtin.globalInvocationId, diff --git a/apps/typegpu-docs/src/examples/algorithms/matrix-next/index.ts b/apps/typegpu-docs/src/examples/algorithms/matrix-next/index.ts index c0f3fa4556..5c6f67237e 100644 --- a/apps/typegpu-docs/src/examples/algorithms/matrix-next/index.ts +++ b/apps/typegpu-docs/src/examples/algorithms/matrix-next/index.ts @@ -61,10 +61,10 @@ function createPipelines() { state.gpuTime = Number(end - start) / 1_000_000; }; - const optimized = root['~unstable'].createComputePipeline({ + const optimized = root.createComputePipeline({ compute: computeSharedMemory, }); - const simple = root['~unstable'].createComputePipeline({ + const simple = root.createComputePipeline({ compute: computeSimple, }); diff --git a/apps/typegpu-docs/src/examples/algorithms/mnist-inference/index.ts b/apps/typegpu-docs/src/examples/algorithms/mnist-inference/index.ts index 49dfd54ac0..525cfe12d2 100644 --- a/apps/typegpu-docs/src/examples/algorithms/mnist-inference/index.ts +++ b/apps/typegpu-docs/src/examples/algorithms/mnist-inference/index.ts @@ -25,7 +25,7 @@ const canvasData = Array.from({ length: (SIZE ** 2) }, () => 0); const relu = tgpu.fn([d.f32], d.f32)((x) => std.max(0, x)); -const defaultCompute = tgpu['~unstable'].computeFn({ +const defaultCompute = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId, }, @@ -50,7 +50,7 @@ const defaultCompute = tgpu['~unstable'].computeFn({ }); const workgroupSize = tgpu.const(d.u32, 128); -const subgroupCompute = tgpu['~unstable'].computeFn({ +const subgroupCompute = tgpu.computeFn({ in: { lid: d.builtin.localInvocationId, wid: d.builtin.workgroupId, @@ -91,9 +91,9 @@ const subgroupCompute = tgpu['~unstable'].computeFn({ }); const pipelines = { - default: root['~unstable'].createComputePipeline({ compute: defaultCompute }), + default: root.createComputePipeline({ compute: defaultCompute }), subgroup: root.enabledFeatures.has('subgroups') - ? root['~unstable'].createComputePipeline({ compute: subgroupCompute }) + ? root.createComputePipeline({ compute: subgroupCompute }) : null, }; diff --git a/apps/typegpu-docs/src/examples/algorithms/probability/executor.ts b/apps/typegpu-docs/src/examples/algorithms/probability/executor.ts index d775052c81..c2d1999af2 100644 --- a/apps/typegpu-docs/src/examples/algorithms/probability/executor.ts +++ b/apps/typegpu-docs/src/examples/algorithms/probability/executor.ts @@ -51,7 +51,7 @@ export class Executor { }); this.#bindGroupLayout = bindGroupLayoutTempAlias; - this.#dataMoreWorkersFunc = tgpu['~unstable'].computeFn({ + this.#dataMoreWorkersFunc = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [64], })((input) => { @@ -98,7 +98,7 @@ export class Executor { } if (!this.#pipelineCache.has(distribution)) { - const pipeline = this.#root['~unstable'] + const pipeline = this.#root .with(this.#distributionSlot, distribution) .createComputePipeline({ compute: this.#dataMoreWorkersFunc }); this.#pipelineCache.set(distribution, pipeline); @@ -113,7 +113,7 @@ export class Executor { ): Promise { let pipeline = this.#pipelineCache.get(distribution); if (!pipeline) { - pipeline = this.#root['~unstable'] + pipeline = this.#root .with(this.#distributionSlot, distribution) .createComputePipeline({ compute: this.#dataMoreWorkersFunc }); this.#pipelineCache.set(distribution, pipeline); diff --git a/apps/typegpu-docs/src/examples/geometry/circles/index.ts b/apps/typegpu-docs/src/examples/geometry/circles/index.ts index f3755b716a..1cc781bbb2 100644 --- a/apps/typegpu-docs/src/examples/geometry/circles/index.ts +++ b/apps/typegpu-docs/src/examples/geometry/circles/index.ts @@ -86,7 +86,7 @@ const uniformsBindGroup = root.createBindGroup(bindGroupLayout, { circles, }); -const mainVertexMaxArea = tgpu['~unstable'].vertexFn({ +const mainVertexMaxArea = tgpu.vertexFn({ in: { instanceIndex: d.builtin.instanceIndex, vertexIndex: d.builtin.vertexIndex, @@ -107,7 +107,7 @@ const mainVertexMaxArea = tgpu['~unstable'].vertexFn({ }; }); -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f, instanceIndex: d.interpolate('flat', d.u32), @@ -126,11 +126,12 @@ const mainFragment = tgpu['~unstable'].fragmentFn({ ); }); -const pipeline = root['~unstable'] - .withVertex(mainVertexMaxArea, {}) - .withFragment(mainFragment, { format: presentationFormat }) - .withMultisample({ count: multisample ? 4 : 1 }) - .createPipeline(); +const pipeline = root.createRenderPipeline({ + vertex: mainVertexMaxArea, + fragment: mainFragment, + targets: { format: presentationFormat }, + multisample: { count: multisample ? 4 : 1 }, +}); setTimeout(() => { pipeline diff --git a/apps/typegpu-docs/src/examples/geometry/lines-combinations/index.ts b/apps/typegpu-docs/src/examples/geometry/lines-combinations/index.ts index 26113600fa..f6e7c3e499 100644 --- a/apps/typegpu-docs/src/examples/geometry/lines-combinations/index.ts +++ b/apps/typegpu-docs/src/examples/geometry/lines-combinations/index.ts @@ -101,7 +101,7 @@ const outlineIndexBuffer = root const testCaseSlot = tgpu.slot(testCases.arms); -const mainVertex = tgpu['~unstable'].vertexFn({ +const mainVertex = tgpu.vertexFn({ in: { instanceIndex: builtin.instanceIndex, vertexIndex: builtin.vertexIndex, @@ -149,7 +149,7 @@ const mainVertex = tgpu['~unstable'].vertexFn({ console.log(tgpu.resolve({ externals: { lineSegmentVariableWidth } })); -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { instanceIndex: interpolate('flat', u32), vertexIndex: interpolate('flat', u32), @@ -218,7 +218,7 @@ const mainFragment = tgpu['~unstable'].fragmentFn({ }, ); -const centerlineVertex = tgpu['~unstable'].vertexFn({ +const centerlineVertex = tgpu.vertexFn({ in: { vertexIndex: builtin.vertexIndex, }, @@ -238,7 +238,7 @@ const centerlineVertex = tgpu['~unstable'].vertexFn({ }; }); -const outlineFragment = tgpu['~unstable'].fragmentFn({ +const outlineFragment = tgpu.fragmentFn({ in: { _unused: builtin.frontFacing, }, @@ -261,7 +261,7 @@ const CIRCLE_MIN_STEP = (2 * Math.PI) / CIRCLE_SEGMENT_COUNT; const CIRCLE_MAX_STEP = Math.PI / 8; const CIRCLE_DASH_LEN = 0.0025 * Math.PI; -const circlesVertex = tgpu['~unstable'].vertexFn({ +const circlesVertex = tgpu.vertexFn({ in: { instanceIndex: builtin.instanceIndex, vertexIndex: builtin.vertexIndex, @@ -295,61 +295,57 @@ let startCap = lineCaps.round; let endCap = lineCaps.round; function createPipelines() { - const fill = root['~unstable'] + const fill = root .with(joinSlot, join) .with(startCapSlot, startCap) .with(endCapSlot, endCap) .with(testCaseSlot, testCase) - .withVertex(mainVertex, {}) - .withFragment(mainFragment, { - format: presentationFormat, - blend: alphaBlend, + .createRenderPipeline({ + vertex: mainVertex, + fragment: mainFragment, + targets: { format: presentationFormat, blend: alphaBlend }, + // primitive: { + // cullMode: 'back', + // }, }) - .withPrimitive({ - // cullMode: 'back', - }) - .createPipeline() .withIndexBuffer(indexBuffer); - const outline = root['~unstable'] + const outline = root .with(joinSlot, join) .with(startCapSlot, startCap) .with(endCapSlot, endCap) .with(testCaseSlot, testCase) - .withVertex(mainVertex, {}) - .withFragment(outlineFragment, { - format: presentationFormat, - blend: alphaBlend, - }) - .withPrimitive({ - topology: 'line-list', + .createRenderPipeline({ + vertex: mainVertex, + fragment: outlineFragment, + targets: { format: presentationFormat, blend: alphaBlend }, + primitive: { + topology: 'line-list', + }, }) - .createPipeline() .withIndexBuffer(outlineIndexBuffer); - const centerline = root['~unstable'] + const centerline = root .with(testCaseSlot, testCase) - .withVertex(centerlineVertex, {}) - .withFragment(outlineFragment, { - format: presentationFormat, - blend: alphaBlend, - }) - .withPrimitive({ - topology: 'line-strip', - }) - .createPipeline(); - - const circles = root['~unstable'] + .createRenderPipeline({ + vertex: centerlineVertex, + fragment: outlineFragment, + targets: { format: presentationFormat, blend: alphaBlend }, + primitive: { + topology: 'line-strip', + }, + }); + + const circles = root .with(testCaseSlot, testCase) - .withVertex(circlesVertex, {}) - .withFragment(outlineFragment, { - format: presentationFormat, - blend: alphaBlend, - }) - .withPrimitive({ - topology: 'line-list', - }) - .createPipeline(); + .createRenderPipeline({ + vertex: circlesVertex, + fragment: outlineFragment, + targets: { format: presentationFormat, blend: alphaBlend }, + primitive: { + topology: 'line-list', + }, + }); return { fill, diff --git a/apps/typegpu-docs/src/examples/image-processing/ascii-filter/index.ts b/apps/typegpu-docs/src/examples/image-processing/ascii-filter/index.ts index e414658922..ac3e2f527e 100644 --- a/apps/typegpu-docs/src/examples/image-processing/ascii-filter/index.ts +++ b/apps/typegpu-docs/src/examples/image-processing/ascii-filter/index.ts @@ -51,7 +51,7 @@ const context = root.configureContext({ canvas, alphaMode: 'premultiplied' }); const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); canvas.parentElement?.appendChild(video); -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ vertex: common.fullScreenTriangle, /** * Adapted from the original Shadertoy implementation by movAX13h: diff --git a/apps/typegpu-docs/src/examples/image-processing/background-segmentation/index.ts b/apps/typegpu-docs/src/examples/image-processing/background-segmentation/index.ts index 847e1893bd..d67cf1da98 100644 --- a/apps/typegpu-docs/src/examples/image-processing/background-segmentation/index.ts +++ b/apps/typegpu-docs/src/examples/image-processing/background-segmentation/index.ts @@ -120,11 +120,9 @@ let blurBindGroups: TgpuBindGroup[]; // pipelines -const prepareModelInputPipeline = root['~unstable'] +const prepareModelInputPipeline = root .with(paramsAccess, paramsUniform) - .createGuardedComputePipeline( - prepareModelInput, - ); + .createGuardedComputePipeline(prepareModelInput); let currentModelIndex = 0; let session = await prepareSession( @@ -149,19 +147,17 @@ async function switchModel(modelIndex: number) { isLoadingModel = false; } -const generateMaskFromOutputPipeline = root['~unstable'] - .createGuardedComputePipeline( - generateMaskFromOutput, - ); +const generateMaskFromOutputPipeline = root.createGuardedComputePipeline( + generateMaskFromOutput, +); const blurPipelines = [false, true].map((flip) => - root['~unstable'] + root .with(flipAccess, flip) - .withCompute(computeFn) - .createPipeline() + .createComputePipeline({ compute: computeFn }) ); -const drawWithMaskPipeline = root['~unstable'] +const drawWithMaskPipeline = root .with(paramsAccess, paramsUniform) .createRenderPipeline({ vertex: common.fullScreenTriangle, diff --git a/apps/typegpu-docs/src/examples/image-processing/background-segmentation/shaders.ts b/apps/typegpu-docs/src/examples/image-processing/background-segmentation/shaders.ts index 6cf1bed62b..3569da6019 100644 --- a/apps/typegpu-docs/src/examples/image-processing/background-segmentation/shaders.ts +++ b/apps/typegpu-docs/src/examples/image-processing/background-segmentation/shaders.ts @@ -45,7 +45,7 @@ export const generateMaskFromOutput = (x: number, y: number) => { }; const tileData = tgpu.workgroupVar(d.arrayOf(d.arrayOf(d.vec3f, 128), 4)); -export const computeFn = tgpu['~unstable'].computeFn({ +export const computeFn = tgpu.computeFn({ in: { wid: d.builtin.workgroupId, lid: d.builtin.localInvocationId }, workgroupSize: [32, 1, 1], })(({ wid, lid }) => { diff --git a/apps/typegpu-docs/src/examples/image-processing/blur/index.ts b/apps/typegpu-docs/src/examples/image-processing/blur/index.ts index 94a8956dd1..86b959f33d 100644 --- a/apps/typegpu-docs/src/examples/image-processing/blur/index.ts +++ b/apps/typegpu-docs/src/examples/image-processing/blur/index.ts @@ -60,7 +60,7 @@ const ioLayout = tgpu.bindGroupLayout({ const tileData = tgpu.workgroupVar(d.arrayOf(d.arrayOf(d.vec3f, 128), 4)); -const computeFn = tgpu['~unstable'].computeFn({ +const computeFn = tgpu.computeFn({ in: { wid: d.builtin.workgroupId, lid: d.builtin.localInvocationId, @@ -118,7 +118,7 @@ const computeFn = tgpu['~unstable'].computeFn({ } }); -const renderFragment = tgpu['~unstable'].fragmentFn({ +const renderFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => @@ -150,11 +150,9 @@ const ioBindGroups = [ }), ]; -const computePipeline = root['~unstable'].createComputePipeline({ - compute: computeFn, -}); +const computePipeline = root.createComputePipeline({ compute: computeFn }); -const renderPipeline = root['~unstable'].createRenderPipeline({ +const renderPipeline = root.createRenderPipeline({ vertex: common.fullScreenTriangle, fragment: renderFragment, targets: { format: presentationFormat }, diff --git a/apps/typegpu-docs/src/examples/image-processing/camera-thresholding/index.ts b/apps/typegpu-docs/src/examples/image-processing/camera-thresholding/index.ts index 78f798c6f0..ea2b8f59bb 100644 --- a/apps/typegpu-docs/src/examples/image-processing/camera-thresholding/index.ts +++ b/apps/typegpu-docs/src/examples/image-processing/camera-thresholding/index.ts @@ -6,7 +6,7 @@ const textureLayout = tgpu.bindGroupLayout({ inputTexture: { externalTexture: d.textureExternal() }, }); -const mainFrag = tgpu['~unstable'].fragmentFn({ +const mainFrag = tgpu.fragmentFn({ in: { uv: d.location(0, d.vec2f) }, out: d.vec4f, })((input) => { @@ -62,10 +62,11 @@ const sampler = root['~unstable'].createSampler({ minFilter: 'linear', }); -const renderPipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle, {}) - .withFragment(mainFrag, { format: presentationFormat }) - .createPipeline(); +const renderPipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: mainFrag, + targets: { format: presentationFormat }, +}); function onVideoChange(size: { width: number; height: number }) { const aspectRatio = size.width / size.height; diff --git a/apps/typegpu-docs/src/examples/image-processing/chroma-keying/index.ts b/apps/typegpu-docs/src/examples/image-processing/chroma-keying/index.ts index a0b0989842..97a4ea5f9c 100644 --- a/apps/typegpu-docs/src/examples/image-processing/chroma-keying/index.ts +++ b/apps/typegpu-docs/src/examples/image-processing/chroma-keying/index.ts @@ -18,7 +18,7 @@ const layout = tgpu.bindGroupLayout({ inputTexture: { externalTexture: d.textureExternal() }, }); -const fragment = tgpu['~unstable'].fragmentFn({ +const fragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -61,10 +61,11 @@ if (navigator.mediaDevices.getUserMedia) { const context = root.configureContext({ canvas, alphaMode: 'premultiplied' }); const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); -const renderPipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle) - .withFragment(fragment, { format: presentationFormat }) - .createPipeline(); +const renderPipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment, + targets: { format: presentationFormat }, +}); function onVideoChange(size: { width: number; height: number }) { const aspectRatio = size.width / size.height; diff --git a/apps/typegpu-docs/src/examples/image-processing/image-tuning/index.ts b/apps/typegpu-docs/src/examples/image-processing/image-tuning/index.ts index 9dd6b55616..e4d2a173af 100644 --- a/apps/typegpu-docs/src/examples/image-processing/image-tuning/index.ts +++ b/apps/typegpu-docs/src/examples/image-processing/image-tuning/index.ts @@ -75,7 +75,7 @@ const imageSampler = root['~unstable'].createSampler({ minFilter: 'linear', }); -const fragment = tgpu['~unstable'].fragmentFn({ +const fragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -167,10 +167,11 @@ const fragment = tgpu['~unstable'].fragmentFn({ return d.vec4f(finalColor, 1); }); -const renderPipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle) - .withFragment(fragment, { format: presentationFormat }) - .createPipeline(); +const renderPipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment, + targets: { format: presentationFormat }, +}); function render() { if (!defaultLUTTexture) { diff --git a/apps/typegpu-docs/src/examples/rendering/3d-fish/index.ts b/apps/typegpu-docs/src/examples/rendering/3d-fish/index.ts index 650e454345..8b3700d9a5 100644 --- a/apps/typegpu-docs/src/examples/rendering/3d-fish/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/3d-fish/index.ts @@ -90,7 +90,7 @@ function enqueuePresetChanges() { const buffer0mutable = fishDataBuffers[0].as('mutable'); const buffer1mutable = fishDataBuffers[1].as('mutable'); const seedUniform = root.createUniform(d.f32); -const randomizeFishPositionsPipeline = root['~unstable'] +const randomizeFishPositionsPipeline = root .createGuardedComputePipeline((x) => { 'use gpu'; randf.seed2(d.vec2f(x, seedUniform.$)); @@ -166,7 +166,7 @@ randomizeFishPositions(); // pipelines -const renderPipeline = root['~unstable'].createRenderPipeline({ +const renderPipeline = root.createRenderPipeline({ attribs: modelVertexLayout.attrib, vertex: vertexShader, fragment: fragmentShader, @@ -185,8 +185,7 @@ let depthTexture = root.device.createTexture({ usage: GPUTextureUsage.RENDER_ATTACHMENT, }); -const simulatePipeline = root['~unstable'] - .createGuardedComputePipeline(simulate); +const simulatePipeline = root.createGuardedComputePipeline(simulate); // bind groups diff --git a/apps/typegpu-docs/src/examples/rendering/3d-fish/render.ts b/apps/typegpu-docs/src/examples/rendering/3d-fish/render.ts index a3f687a7e8..c619569fa7 100644 --- a/apps/typegpu-docs/src/examples/rendering/3d-fish/render.ts +++ b/apps/typegpu-docs/src/examples/rendering/3d-fish/render.ts @@ -8,7 +8,7 @@ import { } from './schemas.ts'; import { applySinWave, PosAndNormal } from './tgsl-helpers.ts'; -export const vertexShader = tgpu['~unstable'].vertexFn({ +export const vertexShader = tgpu.vertexFn({ in: { ...ModelVertexInput, instanceIndex: d.builtin.instanceIndex }, out: ModelVertexOutput, })((input) => { @@ -80,7 +80,7 @@ export const vertexShader = tgpu['~unstable'].vertexFn({ }; }); -export const fragmentShader = tgpu['~unstable'].fragmentFn({ +export const fragmentShader = tgpu.fragmentFn({ in: ModelVertexOutput, out: d.vec4f, })((input) => { diff --git a/apps/typegpu-docs/src/examples/rendering/box-raytracing/index.ts b/apps/typegpu-docs/src/examples/rendering/box-raytracing/index.ts index ab5c151ebc..f8a124bd88 100644 --- a/apps/typegpu-docs/src/examples/rendering/box-raytracing/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/box-raytracing/index.ts @@ -153,7 +153,7 @@ const Varying = { rayWorldOrigin: d.vec3f, }; -const mainVertex = tgpu['~unstable'].vertexFn({ +const mainVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { pos: d.builtin.position, ...Varying }, })((input) => { @@ -168,7 +168,7 @@ const mainVertex = tgpu['~unstable'].vertexFn({ return { pos: d.vec4f(pos[input.vertexIndex], 0.0, 1.0), rayWorldOrigin }; }); -const fragmentFunction = tgpu['~unstable'].fragmentFn({ +const fragmentFunction = tgpu.fragmentFn({ in: { position: d.builtin.position, ...Varying }, out: d.vec4f, })((input) => { @@ -256,7 +256,7 @@ const fragmentFunction = tgpu['~unstable'].fragmentFn({ // pipeline -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ primitive: { topology: 'triangle-strip', }, diff --git a/apps/typegpu-docs/src/examples/rendering/caustics/index.ts b/apps/typegpu-docs/src/examples/rendering/caustics/index.ts index fc15bd20b6..b679d745f5 100644 --- a/apps/typegpu-docs/src/examples/rendering/caustics/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/caustics/index.ts @@ -2,7 +2,7 @@ import { perlin3d } from '@typegpu/noise'; import tgpu, { d, std } from 'typegpu'; import { defineControls } from '../../common/defineControls.ts'; -const mainVertex = tgpu['~unstable'].vertexFn({ +const mainVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { pos: d.builtin.position, uv: d.vec2f }, })(({ vertexIndex }) => { @@ -61,7 +61,7 @@ const fogColor = d.vec3f(0.05, 0.2, 0.7); /** The ambient light color */ const ambientColor = d.vec3f(0.2, 0.5, 1); -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -132,7 +132,7 @@ const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); const canvas = document.querySelector('canvas') as HTMLCanvasElement; const context = root.configureContext({ canvas, alphaMode: 'premultiplied' }); -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ vertex: mainVertex, fragment: mainFragment, targets: { format: presentationFormat }, diff --git a/apps/typegpu-docs/src/examples/rendering/clouds/index.ts b/apps/typegpu-docs/src/examples/rendering/clouds/index.ts index b50bd0b614..fc4ea28e67 100644 --- a/apps/typegpu-docs/src/examples/rendering/clouds/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/clouds/index.ts @@ -55,7 +55,7 @@ const bindGroup = root.createBindGroup(cloudsLayout, { sampler, }); -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -93,10 +93,11 @@ const mainFragment = tgpu['~unstable'].fragmentFn({ return d.vec4f(finalCol, 1.0); }); -const pipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle) - .withFragment(mainFragment, { format: presentationFormat }) - .createPipeline(); +const pipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: mainFragment, + targets: { format: presentationFormat }, +}); const resizeObserver = new ResizeObserver(() => { resolutionUniform.write(d.vec2f(canvas.width, canvas.height)); diff --git a/apps/typegpu-docs/src/examples/rendering/cubemap-reflection/icosphere.ts b/apps/typegpu-docs/src/examples/rendering/cubemap-reflection/icosphere.ts index e607f5461f..f81d3fbf6e 100644 --- a/apps/typegpu-docs/src/examples/rendering/cubemap-reflection/icosphere.ts +++ b/apps/typegpu-docs/src/examples/rendering/cubemap-reflection/icosphere.ts @@ -127,7 +127,7 @@ export class IcosphereGenerator { ) { this.smoothBuffer = this.root.createBuffer(d.u32).$usage('uniform'); - const computeFn = tgpu['~unstable'].computeFn({ + const computeFn = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [WORKGROUP_SIZE, 1, 1], })((input) => { @@ -191,9 +191,7 @@ export class IcosphereGenerator { } }); - this.pipeline = this.root['~unstable'].createComputePipeline({ - compute: computeFn, - }); + this.pipeline = this.root.createComputePipeline({ compute: computeFn }); } createIcosphere(subdivisions: number, smooth: boolean): IcosphereBuffer { diff --git a/apps/typegpu-docs/src/examples/rendering/cubemap-reflection/index.ts b/apps/typegpu-docs/src/examples/rendering/cubemap-reflection/index.ts index 489bd9547a..65718d0b21 100644 --- a/apps/typegpu-docs/src/examples/rendering/cubemap-reflection/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/cubemap-reflection/index.ts @@ -138,7 +138,7 @@ const cubeVertexLayout = tgpu.vertexLayout((n: number) => // Shader Functions -const vertexFn = tgpu['~unstable'].vertexFn({ +const vertexFn = tgpu.vertexFn({ in: { position: d.vec4f, normal: d.vec4f, @@ -157,7 +157,7 @@ const vertexFn = tgpu['~unstable'].vertexFn({ worldPos: input.position, })); -const fragmentFn = tgpu['~unstable'].fragmentFn({ +const fragmentFn = tgpu.fragmentFn({ in: { normal: d.vec4f, worldPos: d.vec4f, @@ -217,7 +217,7 @@ const fragmentFn = tgpu['~unstable'].fragmentFn({ return d.vec4f(finalColor, 1.0); }); -const cubeVertexFn = tgpu['~unstable'].vertexFn({ +const cubeVertexFn = tgpu.vertexFn({ in: { position: d.vec3f, uv: d.vec2f, @@ -236,7 +236,7 @@ const cubeVertexFn = tgpu['~unstable'].vertexFn({ }; }); -const cubeFragmentFn = tgpu['~unstable'].fragmentFn({ +const cubeFragmentFn = tgpu.fragmentFn({ in: { texCoord: d.vec3f }, out: d.vec4f, })((input) => { @@ -249,7 +249,7 @@ const cubeFragmentFn = tgpu['~unstable'].fragmentFn({ // Pipeline Setup -const cubePipeline = root['~unstable'].createRenderPipeline({ +const cubePipeline = root.createRenderPipeline({ attribs: cubeVertexLayout.attrib, vertex: cubeVertexFn, fragment: cubeFragmentFn, @@ -257,7 +257,7 @@ const cubePipeline = root['~unstable'].createRenderPipeline({ primitive: { cullMode: 'front' }, }); -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ attribs: vertexLayout.attrib, vertex: vertexFn, fragment: fragmentFn, diff --git a/apps/typegpu-docs/src/examples/rendering/disco/index.ts b/apps/typegpu-docs/src/examples/rendering/disco/index.ts index 8538e953ab..1ffc24af52 100644 --- a/apps/typegpu-docs/src/examples/rendering/disco/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/disco/index.ts @@ -35,7 +35,7 @@ const fragmentShaders = [ ]; const pipelines = fragmentShaders.map((fragment) => - root['~unstable'] + root .with(timeAccess, time) .with(resolutionAccess, resolutionUniform) .createRenderPipeline({ diff --git a/apps/typegpu-docs/src/examples/rendering/disco/shaders/fragment.ts b/apps/typegpu-docs/src/examples/rendering/disco/shaders/fragment.ts index 849e434d0e..a85778f1b7 100644 --- a/apps/typegpu-docs/src/examples/rendering/disco/shaders/fragment.ts +++ b/apps/typegpu-docs/src/examples/rendering/disco/shaders/fragment.ts @@ -20,7 +20,7 @@ const accumulate = tgpu.fn( )((acc, col, weight) => acc.add(col.mul(weight))); // Variation1 -export const mainFragment1 = tgpu['~unstable'].fragmentFn({ +export const mainFragment1 = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -48,7 +48,7 @@ export const mainFragment1 = tgpu['~unstable'].fragmentFn({ }); // Variation2 -export const mainFragment2 = tgpu['~unstable'].fragmentFn({ +export const mainFragment2 = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -75,7 +75,7 @@ export const mainFragment2 = tgpu['~unstable'].fragmentFn({ }); // Variation3 -export const mainFragment3 = tgpu['~unstable'].fragmentFn({ +export const mainFragment3 = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -118,7 +118,7 @@ export const mainFragment3 = tgpu['~unstable'].fragmentFn({ }); // Variation4 -export const mainFragment4 = tgpu['~unstable'].fragmentFn({ +export const mainFragment4 = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -165,7 +165,7 @@ export const mainFragment4 = tgpu['~unstable'].fragmentFn({ }); // Variation5 -export const mainFragment5 = tgpu['~unstable'].fragmentFn({ +export const mainFragment5 = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -201,7 +201,7 @@ export const mainFragment5 = tgpu['~unstable'].fragmentFn({ }); // Variation6 -export const mainFragment6 = tgpu['~unstable'].fragmentFn({ +export const mainFragment6 = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -239,7 +239,7 @@ export const mainFragment6 = tgpu['~unstable'].fragmentFn({ }); // Variation7 -export const mainFragment7 = tgpu['~unstable'].fragmentFn({ +export const mainFragment7 = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { diff --git a/apps/typegpu-docs/src/examples/rendering/disco/shaders/vertex.ts b/apps/typegpu-docs/src/examples/rendering/disco/shaders/vertex.ts index a0f545176f..4648a86853 100644 --- a/apps/typegpu-docs/src/examples/rendering/disco/shaders/vertex.ts +++ b/apps/typegpu-docs/src/examples/rendering/disco/shaders/vertex.ts @@ -1,6 +1,6 @@ import tgpu, { d } from 'typegpu'; -export const mainVertex = tgpu['~unstable'].vertexFn({ +export const mainVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { outPos: d.builtin.position, uv: d.vec2f }, })(({ vertexIndex }) => { diff --git a/apps/typegpu-docs/src/examples/rendering/function-visualizer/index.ts b/apps/typegpu-docs/src/examples/rendering/function-visualizer/index.ts index c82c7e9106..e51c39641d 100644 --- a/apps/typegpu-docs/src/examples/rendering/function-visualizer/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/function-visualizer/index.ts @@ -90,7 +90,7 @@ const computePointsFn = (x: number) => { }; const createComputePipeline = (exprCode: string) => { - return root['~unstable'] + return root .with( functionExprSlot, tgpu['~unstable'].rawCodeSnippet(exprCode, d.f32, 'runtime'), @@ -103,7 +103,7 @@ const computePipelines: Array = initialFunctions // Render background shader -const backgroundVertex = tgpu['~unstable'].vertexFn({ +const backgroundVertex = tgpu.vertexFn({ in: { vid: d.builtin.vertexIndex, iid: d.builtin.instanceIndex }, out: { pos: d.builtin.position }, })(({ vid, iid }) => { @@ -135,18 +135,17 @@ const backgroundVertex = tgpu['~unstable'].vertexFn({ }; }); -const backgroundFragment = tgpu['~unstable'].fragmentFn({ out: d.vec4f })( +const backgroundFragment = tgpu.fragmentFn({ out: d.vec4f })( () => d.vec4f(0.9, 0.9, 0.9, 1), ); -const renderBackgroundPipeline = root['~unstable'] - .withVertex(backgroundVertex) - .withFragment(backgroundFragment, { format: presentationFormat }) - .withPrimitive({ - topology: 'triangle-strip', - }) - .withMultisample({ count: 4 }) - .createPipeline(); +const renderBackgroundPipeline = root.createRenderPipeline({ + vertex: backgroundVertex, + fragment: backgroundFragment, + targets: { format: presentationFormat }, + primitive: { topology: 'triangle-strip' }, + multisample: { count: 4 }, +}); let msTexture = device.createTexture({ size: [canvas.width, canvas.height], @@ -189,7 +188,7 @@ const orthonormalForVertex = (index: number): d.v2f => { return std.normalize(avg); }; -const vertex = tgpu['~unstable'].vertexFn({ +const vertex = tgpu.vertexFn({ in: { vid: d.builtin.vertexIndex }, out: { pos: d.builtin.position }, })(({ vid }) => { @@ -212,16 +211,17 @@ const vertex = tgpu['~unstable'].vertexFn({ }; }); -const fragment = tgpu['~unstable'].fragmentFn({ out: d.vec4f })(() => { +const fragment = tgpu.fragmentFn({ out: d.vec4f })(() => { return renderLayout.$.color; }); -const renderPipeline = root['~unstable'] - .withVertex(vertex) - .withFragment(fragment, { format: presentationFormat }) - .withPrimitive({ topology: 'triangle-strip' }) - .withMultisample({ count: 4 }) - .createPipeline(); +const renderPipeline = root.createRenderPipeline({ + vertex, + fragment, + targets: { format: presentationFormat }, + primitive: { topology: 'triangle-strip' }, + multisample: { count: 4 }, +}); // Draw diff --git a/apps/typegpu-docs/src/examples/rendering/jelly-slider/index.ts b/apps/typegpu-docs/src/examples/rendering/jelly-slider/index.ts index 501bf917dc..396bfa9344 100644 --- a/apps/typegpu-docs/src/examples/rendering/jelly-slider/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/jelly-slider/index.ts @@ -806,10 +806,8 @@ const rayMarch = (rayOrigin: d.v3f, rayDirection: d.v3f, _uv: d.v2f) => { return background; }; -const raymarchFn = tgpu['~unstable'].fragmentFn({ - in: { - uv: d.vec2f, - }, +const raymarchFn = tgpu.fragmentFn({ + in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { randf.seed2(randomUniform.$.mul(uv)); @@ -825,7 +823,7 @@ const raymarchFn = tgpu['~unstable'].fragmentFn({ return d.vec4f(std.tanh(color.rgb.mul(1.3)), 1); }); -const fragmentMain = tgpu['~unstable'].fragmentFn({ +const fragmentMain = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => { @@ -836,15 +834,17 @@ const fragmentMain = tgpu['~unstable'].fragmentFn({ ); }); -const rayMarchPipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle, {}) - .withFragment(raymarchFn, { format: 'rgba8unorm' }) - .createPipeline(); +const rayMarchPipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: raymarchFn, + targets: { format: 'rgba8unorm' }, +}); -const renderPipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle, {}) - .withFragment(fragmentMain, { format: presentationFormat }) - .createPipeline(); +const renderPipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: fragmentMain, + targets: { format: presentationFormat }, +}); const eventHandler = new EventHandler(canvas); let lastTimeStamp = performance.now(); diff --git a/apps/typegpu-docs/src/examples/rendering/jelly-slider/slider.ts b/apps/typegpu-docs/src/examples/rendering/jelly-slider/slider.ts index 3f2173af43..2d20b7d7b2 100644 --- a/apps/typegpu-docs/src/examples/rendering/jelly-slider/slider.ts +++ b/apps/typegpu-docs/src/examples/rendering/jelly-slider/slider.ts @@ -129,7 +129,7 @@ export class Slider { this.bbox = [top, right, bottom, left]; - this.#computeBezierPipeline = this.#root['~unstable'] + this.#computeBezierPipeline = this.#root .createGuardedComputePipeline((x, y) => { 'use gpu'; const size = std.textureDimensions(bezierWriteView.$); diff --git a/apps/typegpu-docs/src/examples/rendering/jelly-slider/taa.ts b/apps/typegpu-docs/src/examples/rendering/jelly-slider/taa.ts index e9ced4731d..6956e2f700 100644 --- a/apps/typegpu-docs/src/examples/rendering/jelly-slider/taa.ts +++ b/apps/typegpu-docs/src/examples/rendering/jelly-slider/taa.ts @@ -2,7 +2,7 @@ import type { TgpuComputePipeline, TgpuRoot, TgpuTextureView } from 'typegpu'; import tgpu, { d, std } from 'typegpu'; import { taaResolveLayout } from './dataTypes.ts'; -export const taaResolveFn = tgpu['~unstable'].computeFn({ +export const taaResolveFn = tgpu.computeFn({ workgroupSize: [16, 16], in: { gid: d.builtin.globalInvocationId, @@ -122,9 +122,7 @@ export class TAAResolver { this.#width = width; this.#height = height; - this.#pipeline = root['~unstable'] - .withCompute(taaResolveFn) - .createPipeline(); + this.#pipeline = root.createComputePipeline({ compute: taaResolveFn }); this.#textures = createTaaTextures(root, width, height); } diff --git a/apps/typegpu-docs/src/examples/rendering/jelly-switch/index.ts b/apps/typegpu-docs/src/examples/rendering/jelly-switch/index.ts index f3fc08ff60..cc75527f97 100644 --- a/apps/typegpu-docs/src/examples/rendering/jelly-switch/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/jelly-switch/index.ts @@ -508,7 +508,7 @@ const rayMarch = (rayOrigin: d.v3f, rayDirection: d.v3f, _uv: d.v2f) => { return background; }; -const raymarchFn = tgpu['~unstable'].fragmentFn({ +const raymarchFn = tgpu.fragmentFn({ in: { uv: d.vec2f, }, @@ -529,7 +529,7 @@ const raymarchFn = tgpu['~unstable'].fragmentFn({ return d.vec4f(std.tanh(color.rgb.mul(exposure)), 1); }); -const fragmentMain = tgpu['~unstable'].fragmentFn({ +const fragmentMain = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => { @@ -540,15 +540,17 @@ const fragmentMain = tgpu['~unstable'].fragmentFn({ ); }); -const rayMarchPipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle, {}) - .withFragment(raymarchFn, { format: 'rgba8unorm' }) - .createPipeline(); +const rayMarchPipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: raymarchFn, + targets: { format: 'rgba8unorm' }, +}); -const renderPipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle, {}) - .withFragment(fragmentMain, { format: presentationFormat }) - .createPipeline(); +const renderPipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: fragmentMain, + targets: { format: presentationFormat }, +}); let lastTimeStamp = performance.now(); let frameCount = 0; diff --git a/apps/typegpu-docs/src/examples/rendering/jelly-switch/taa.ts b/apps/typegpu-docs/src/examples/rendering/jelly-switch/taa.ts index fd4d8f3892..3748b5cd1e 100644 --- a/apps/typegpu-docs/src/examples/rendering/jelly-switch/taa.ts +++ b/apps/typegpu-docs/src/examples/rendering/jelly-switch/taa.ts @@ -2,7 +2,7 @@ import type { TgpuComputePipeline, TgpuRoot, TgpuTextureView } from 'typegpu'; import tgpu, { d, std } from 'typegpu'; import { taaResolveLayout } from './dataTypes.ts'; -export const taaResolveFn = tgpu['~unstable'].computeFn({ +export const taaResolveFn = tgpu.computeFn({ workgroupSize: [16, 16], in: { gid: d.builtin.globalInvocationId, @@ -91,10 +91,7 @@ export class TAAResolver { this.#width = width; this.#height = height; - this.#pipeline = root['~unstable'] - .withCompute(taaResolveFn) - .createPipeline(); - + this.#pipeline = root.createComputePipeline({ compute: taaResolveFn }); this.#textures = createTaaTextures(root, width, height); } diff --git a/apps/typegpu-docs/src/examples/rendering/perlin-noise/index.ts b/apps/typegpu-docs/src/examples/rendering/perlin-noise/index.ts index 0b9d5971b7..2ccf191344 100644 --- a/apps/typegpu-docs/src/examples/rendering/perlin-noise/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/perlin-noise/index.ts @@ -39,7 +39,7 @@ const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); const createRenderPipeline = ( sharpenFn: (n: number, sharpness: number) => number, ) => - root['~unstable'] + root .pipe(perlinCacheConfig.inject(dynamicLayout.$)) .createRenderPipeline({ vertex: common.fullScreenTriangle, diff --git a/apps/typegpu-docs/src/examples/rendering/phong-reflection/index.ts b/apps/typegpu-docs/src/examples/rendering/phong-reflection/index.ts index d996a87334..b0ac6dc3dc 100644 --- a/apps/typegpu-docs/src/examples/rendering/phong-reflection/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/phong-reflection/index.ts @@ -39,7 +39,7 @@ const exampleControlsUniform = root.createUniform( p.initialControls, ); -const vertexShader = tgpu['~unstable'].vertexFn({ +const vertexShader = tgpu.vertexFn({ in: { ...ModelVertexInput.propTypes, instanceIndex: d.builtin.instanceIndex }, out: ModelVertexOutput, })((input) => { @@ -56,7 +56,7 @@ const vertexShader = tgpu['~unstable'].vertexFn({ }); // see https://gist.github.com/chicio/d983fff6ff304bd55bebd6ff05a2f9dd -const fragmentShader = tgpu['~unstable'].fragmentFn({ +const fragmentShader = tgpu.fragmentFn({ in: ModelVertexOutput, out: d.vec4f, })((input) => { @@ -95,7 +95,7 @@ const fragmentShader = tgpu['~unstable'].fragmentFn({ }); // pipelines -const renderPipeline = root['~unstable'].createRenderPipeline({ +const renderPipeline = root.createRenderPipeline({ attribs: modelVertexLayout.attrib, vertex: vertexShader, fragment: fragmentShader, diff --git a/apps/typegpu-docs/src/examples/rendering/point-light-shadow/index.ts b/apps/typegpu-docs/src/examples/rendering/point-light-shadow/index.ts index a41652729b..25029c0bc1 100644 --- a/apps/typegpu-docs/src/examples/rendering/point-light-shadow/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/point-light-shadow/index.ts @@ -84,7 +84,7 @@ const renderLayoutWithShadow = tgpu.bindGroupLayout({ lightPosition: { uniform: d.vec3f }, }); -const vertexDepth = tgpu['~unstable'].vertexFn({ +const vertexDepth = tgpu.vertexFn({ in: { ...VertexData.propTypes, ...InstanceData.propTypes }, out: { pos: d.builtin.position, worldPos: d.vec3f }, })(({ position, column1, column2, column3, column4 }) => { @@ -96,7 +96,7 @@ const vertexDepth = tgpu['~unstable'].vertexFn({ return { pos, worldPos }; }); -const fragmentDepth = tgpu['~unstable'].fragmentFn({ +const fragmentDepth = tgpu.fragmentFn({ in: { worldPos: d.vec3f }, out: d.builtin.fragDepth, })(({ worldPos }) => { @@ -104,7 +104,7 @@ const fragmentDepth = tgpu['~unstable'].fragmentFn({ return dist / pointLight.far; }); -const vertexMain = tgpu['~unstable'].vertexFn({ +const vertexMain = tgpu.vertexFn({ in: { ...VertexData.propTypes, ...InstanceData.propTypes }, out: { pos: d.builtin.position, @@ -148,7 +148,7 @@ const samplesUniform = root.createUniform( }), ); -const fragmentMain = tgpu['~unstable'].fragmentFn({ +const fragmentMain = tgpu.fragmentFn({ in: { worldPos: d.vec3f, uv: d.vec2f, normal: d.vec3f }, out: d.vec4f, })(({ worldPos, normal }) => { @@ -210,7 +210,7 @@ const lightIndicatorLayout = tgpu.bindGroupLayout({ lightPosition: { uniform: d.vec3f }, }); -const vertexLightIndicator = tgpu['~unstable'].vertexFn({ +const vertexLightIndicator = tgpu.vertexFn({ in: { position: d.vec3f }, out: { pos: d.builtin.position }, })(({ position }) => { @@ -221,7 +221,7 @@ const vertexLightIndicator = tgpu['~unstable'].vertexFn({ return { pos }; }); -const fragmentLightIndicator = tgpu['~unstable'].fragmentFn({ +const fragmentLightIndicator = tgpu.fragmentFn({ out: d.vec4f, })(() => d.vec4f(1.0, 1.0, 0.5, 1.0)); @@ -240,7 +240,7 @@ const depthToColor = tgpu.fn([d.f32], d.vec3f)((depth) => { return d.vec3f(r, g, b); }); -const fragmentDistanceView = tgpu['~unstable'].fragmentFn({ +const fragmentDistanceView = tgpu.fragmentFn({ in: { worldPos: d.vec3f, uv: d.vec2f, normal: d.vec3f }, out: d.vec4f, })(({ worldPos }) => { @@ -250,7 +250,7 @@ const fragmentDistanceView = tgpu['~unstable'].fragmentFn({ return d.vec4f(color, 1.0); }); -const previewFragment = tgpu['~unstable'].fragmentFn({ +const previewFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -310,53 +310,61 @@ const previewFragment = tgpu['~unstable'].fragmentFn({ return d.vec4f(finalColor, 1.0); }); -const pipelineDepthOne = root['~unstable'] - .withVertex(vertexDepth, { ...vertexLayout.attrib, ...instanceLayout.attrib }) - .withFragment(fragmentDepth) - .withDepthStencil({ +const pipelineDepthOne = root.createRenderPipeline({ + attribs: { ...vertexLayout.attrib, ...instanceLayout.attrib }, + vertex: vertexDepth, + fragment: fragmentDepth, + depthStencil: { format: 'depth24plus', depthWriteEnabled: true, depthCompare: 'less', - }) - .createPipeline(); + }, +}); -const pipelineMain = root['~unstable'] - .withVertex(vertexMain, { ...vertexLayout.attrib, ...instanceLayout.attrib }) - .withFragment(fragmentMain, { format: presentationFormat }) - .withDepthStencil({ +const pipelineMain = root.createRenderPipeline({ + attribs: { ...vertexLayout.attrib, ...instanceLayout.attrib }, + vertex: vertexMain, + fragment: fragmentMain, + targets: { format: presentationFormat }, + depthStencil: { format: 'depth24plus', depthWriteEnabled: true, depthCompare: 'less', - }) - .withMultisample({ count: 4 }) - .createPipeline(); - -const pipelinePreview = root['~unstable'] - .withVertex(common.fullScreenTriangle) - .withFragment(previewFragment, { format: presentationFormat }) - .createPipeline(); - -const pipelineLightIndicator = root['~unstable'] - .withVertex(vertexLightIndicator, vertexLayout.attrib) - .withFragment(fragmentLightIndicator, { format: presentationFormat }) - .withDepthStencil({ + }, + multisample: { count: 4 }, +}); + +const pipelinePreview = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: previewFragment, + targets: { format: presentationFormat }, +}); + +const pipelineLightIndicator = root.createRenderPipeline({ + attribs: vertexLayout.attrib, + vertex: vertexLightIndicator, + fragment: fragmentLightIndicator, + targets: { format: presentationFormat }, + depthStencil: { format: 'depth24plus', depthWriteEnabled: true, depthCompare: 'less', - }) - .withMultisample({ count: 4 }) - .createPipeline(); + }, + multisample: { count: 4 }, +}); -const pipelineDistanceView = root['~unstable'] - .withVertex(vertexMain, { ...vertexLayout.attrib, ...instanceLayout.attrib }) - .withFragment(fragmentDistanceView, { format: presentationFormat }) - .withDepthStencil({ +const pipelineDistanceView = root.createRenderPipeline({ + attribs: { ...vertexLayout.attrib, ...instanceLayout.attrib }, + vertex: vertexMain, + fragment: fragmentDistanceView, + targets: { format: presentationFormat }, + depthStencil: { format: 'depth24plus', depthWriteEnabled: true, depthCompare: 'less', - }) - .withMultisample({ count: 4 }) - .createPipeline(); + }, + multisample: { count: 4 }, +}); const mainBindGroup = root.createBindGroup(renderLayoutWithShadow, { camera: mainCamera.uniform.buffer, diff --git a/apps/typegpu-docs/src/examples/rendering/ray-marching/index.ts b/apps/typegpu-docs/src/examples/rendering/ray-marching/index.ts index fad92bdfdd..61a3acec96 100644 --- a/apps/typegpu-docs/src/examples/rendering/ray-marching/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/ray-marching/index.ts @@ -181,7 +181,7 @@ const getOrbitingLightPos = (t: number): d.v3f => { ); }; -const vertexMain = tgpu['~unstable'].vertexFn({ +const vertexMain = tgpu.vertexFn({ in: { idx: d.builtin.vertexIndex }, out: { pos: d.builtin.position, uv: d.vec2f }, })(({ idx }) => { @@ -194,7 +194,7 @@ const vertexMain = tgpu['~unstable'].vertexFn({ }; }); -const fragmentMain = tgpu['~unstable'].fragmentFn({ +const fragmentMain = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => { @@ -234,7 +234,7 @@ const fragmentMain = tgpu['~unstable'].fragmentFn({ return std.mix(d.vec4f(finalColor, 1), skyColor, fog); }); -const renderPipeline = root['~unstable'].createRenderPipeline({ +const renderPipeline = root.createRenderPipeline({ vertex: vertexMain, fragment: fragmentMain, targets: { format: presentationFormat }, diff --git a/apps/typegpu-docs/src/examples/rendering/simple-shadow/index.ts b/apps/typegpu-docs/src/examples/rendering/simple-shadow/index.ts index 97872dc2df..3a468aca9a 100644 --- a/apps/typegpu-docs/src/examples/rendering/simple-shadow/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/simple-shadow/index.ts @@ -147,7 +147,7 @@ const geometries = { }; // Shaders -const shadowVert = tgpu['~unstable'].vertexFn({ +const shadowVert = tgpu.vertexFn({ in: { position: d.vec4f }, out: { pos: d.builtin.position }, })(({ position }) => { @@ -156,7 +156,7 @@ const shadowVert = tgpu['~unstable'].vertexFn({ return { pos: clip }; }); -const mainVert = tgpu['~unstable'].vertexFn({ +const mainVert = tgpu.vertexFn({ in: { position: d.vec4f, normal: d.vec4f, @@ -180,7 +180,7 @@ const mainVert = tgpu['~unstable'].vertexFn({ }; }); -const mainFrag = tgpu['~unstable'].fragmentFn({ +const mainFrag = tgpu.fragmentFn({ in: { normal: d.vec4f, worldPos: d.vec3f, @@ -243,7 +243,7 @@ const mainFrag = tgpu['~unstable'].fragmentFn({ // Pipelines const vertexLayout = tgpu.vertexLayout(d.arrayOf(VertexInfo)); -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ attribs: vertexLayout.attrib, vertex: mainVert, fragment: mainFrag, @@ -262,7 +262,7 @@ const pipeline = root['~unstable'].createRenderPipeline({ }, }); -const shadowPipeline = root['~unstable'].createRenderPipeline({ +const shadowPipeline = root.createRenderPipeline({ attribs: vertexLayout.attrib, vertex: shadowVert, diff --git a/apps/typegpu-docs/src/examples/rendering/smoky-triangle/index.ts b/apps/typegpu-docs/src/examples/rendering/smoky-triangle/index.ts index 664fb0a75f..8941d1b66e 100644 --- a/apps/typegpu-docs/src/examples/rendering/smoky-triangle/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/smoky-triangle/index.ts @@ -53,7 +53,7 @@ const uvs = tgpu.const(d.arrayOf(d.vec2f, 3), [ ]); const perlinCache = perlin3d.staticCache({ root, size: d.vec3u(32, 32, 32) }); -const pipeline = root['~unstable'] +const pipeline = root .pipe(perlinCache.inject()) .createRenderPipeline({ vertex: ({ $vertexIndex }) => { diff --git a/apps/typegpu-docs/src/examples/rendering/two-boxes/index.ts b/apps/typegpu-docs/src/examples/rendering/two-boxes/index.ts index 2c0720bd28..a2ea9e71d3 100644 --- a/apps/typegpu-docs/src/examples/rendering/two-boxes/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/two-boxes/index.ts @@ -226,7 +226,7 @@ createDepthAndMsaaTextures(); // Shaders and Pipeline -const vertex = tgpu['~unstable'].vertexFn({ +const vertex = tgpu.vertexFn({ in: { position: d.vec4f, color: d.vec4f }, out: { pos: d.builtin.position, color: d.vec4f }, })((input) => { @@ -240,12 +240,12 @@ const vertex = tgpu['~unstable'].vertexFn({ return { pos, color: input.color }; }); -const fragment = tgpu['~unstable'].fragmentFn({ +const fragment = tgpu.fragmentFn({ in: { color: d.vec4f }, out: d.vec4f, })((input) => input.color); -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ attribs: vertexLayout.attrib, vertex, fragment, diff --git a/apps/typegpu-docs/src/examples/rendering/xor-dev-centrifuge-2/index.ts b/apps/typegpu-docs/src/examples/rendering/xor-dev-centrifuge-2/index.ts index 3eeafc0909..e58356b441 100644 --- a/apps/typegpu-docs/src/examples/rendering/xor-dev-centrifuge-2/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/xor-dev-centrifuge-2/index.ts @@ -46,7 +46,7 @@ const color = root.createUniform(d.vec3f); const tunnelRadius = 11; const moveSpeed = 5; -const fragmentMain = tgpu['~unstable'].fragmentFn({ +const fragmentMain = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -82,7 +82,7 @@ const fragmentMain = tgpu['~unstable'].fragmentFn({ /** * A full-screen triangle vertex shader */ -const vertexMain = tgpu['~unstable'].vertexFn({ +const vertexMain = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { pos: d.builtin.position, uv: d.vec2f }, })((input) => { @@ -98,7 +98,7 @@ const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); const canvas = document.querySelector('canvas') as HTMLCanvasElement; const context = root.configureContext({ canvas, alphaMode: 'premultiplied' }); -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ vertex: vertexMain, fragment: fragmentMain, targets: { format: presentationFormat }, diff --git a/apps/typegpu-docs/src/examples/rendering/xor-dev-runner/index.ts b/apps/typegpu-docs/src/examples/rendering/xor-dev-runner/index.ts index 9f35665404..fe8075fd56 100644 --- a/apps/typegpu-docs/src/examples/rendering/xor-dev-runner/index.ts +++ b/apps/typegpu-docs/src/examples/rendering/xor-dev-runner/index.ts @@ -86,7 +86,7 @@ const controlsOffsetUniform = root.createUniform(d.f32); const colorUniform = root.createUniform(d.vec3f); const shiftUniform = root.createUniform(d.f32); -const fragmentMain = tgpu['~unstable'].fragmentFn({ +const fragmentMain = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -125,7 +125,7 @@ const fragmentMain = tgpu['~unstable'].fragmentFn({ /** * A full-screen triangle vertex shader */ -const vertexMain = tgpu['~unstable'].vertexFn({ +const vertexMain = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { pos: d.builtin.position, uv: d.vec2f }, })((input) => { @@ -148,7 +148,7 @@ const { cleanupCamera, updatePosition } = setupFirstPersonCamera(canvas, { cameraUniform.writePartial(props); }); -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ vertex: vertexMain, fragment: fragmentMain, targets: { format: presentationFormat }, diff --git a/apps/typegpu-docs/src/examples/simple/gradient-tiles/index.ts b/apps/typegpu-docs/src/examples/simple/gradient-tiles/index.ts index 5b8ab9c41f..f7bf0f78c1 100644 --- a/apps/typegpu-docs/src/examples/simple/gradient-tiles/index.ts +++ b/apps/typegpu-docs/src/examples/simple/gradient-tiles/index.ts @@ -6,7 +6,7 @@ const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); const spanUniform = root.createUniform(d.vec2f); -const fragment = tgpu['~unstable'].fragmentFn({ +const fragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -15,10 +15,11 @@ const fragment = tgpu['~unstable'].fragmentFn({ return d.vec4f(red, green, 0.5, 1.0); }); -const pipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle) - .withFragment(fragment, { format: presentationFormat }) - .createPipeline(); +const pipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment, + targets: { format: presentationFormat }, +}); const canvas = document.querySelector('canvas') as HTMLCanvasElement; const context = root.configureContext({ canvas, alphaMode: 'premultiplied' }); diff --git a/apps/typegpu-docs/src/examples/simple/increment/index.ts b/apps/typegpu-docs/src/examples/simple/increment/index.ts index efc98b00b8..f8db1a83a3 100644 --- a/apps/typegpu-docs/src/examples/simple/increment/index.ts +++ b/apps/typegpu-docs/src/examples/simple/increment/index.ts @@ -6,7 +6,7 @@ const root = await tgpu.init(); const counter = root.createMutable(d.u32); // A 0-dimensional compute pipeline -const incrementPipeline = root['~unstable'].createGuardedComputePipeline(() => { +const incrementPipeline = root.createGuardedComputePipeline(() => { 'use gpu'; counter.$ += 1; }); diff --git a/apps/typegpu-docs/src/examples/simple/liquid-glass/index.ts b/apps/typegpu-docs/src/examples/simple/liquid-glass/index.ts index 01090ef842..1fc10579c3 100644 --- a/apps/typegpu-docs/src/examples/simple/liquid-glass/index.ts +++ b/apps/typegpu-docs/src/examples/simple/liquid-glass/index.ts @@ -104,7 +104,7 @@ const sampleWithChromaticAberration = ( return d.vec3f(samples[0].x, samples[1].y, samples[2].z); }; -const fragmentShader = tgpu['~unstable'].fragmentFn({ +const fragmentShader = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -156,7 +156,7 @@ const fragmentShader = tgpu['~unstable'].fragmentFn({ .add(normalSample.mul(weights.outside)); }); -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ vertex: common.fullScreenTriangle, fragment: fragmentShader, targets: { format: presentationFormat }, diff --git a/apps/typegpu-docs/src/examples/simple/oklab/index.ts b/apps/typegpu-docs/src/examples/simple/oklab/index.ts index 9f292dcb92..9fda835486 100644 --- a/apps/typegpu-docs/src/examples/simple/oklab/index.ts +++ b/apps/typegpu-docs/src/examples/simple/oklab/index.ts @@ -74,7 +74,7 @@ const patternSlot = tgpu.slot(patternSolid); // #endregion -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => { @@ -107,7 +107,7 @@ const uniformsValue = { alpha: 0.05, }; -let pipeline = root['~unstable'].createRenderPipeline({ +let pipeline = root.createRenderPipeline({ vertex: common.fullScreenTriangle, fragment: mainFragment, targets: { format: presentationFormat }, @@ -120,7 +120,7 @@ function setPipeline({ outOfGamutPattern: typeof patternSlot.$; gamutClip: typeof oklabGamutClipSlot.$; }) { - pipeline = root['~unstable'] + pipeline = root .with(patternSlot, outOfGamutPattern) .with(oklabGamutClipSlot, gamutClip) .with(oklabGamutClipAlphaAccess, () => uniforms.$.alpha) diff --git a/apps/typegpu-docs/src/examples/simple/ripple-cube/background.ts b/apps/typegpu-docs/src/examples/simple/ripple-cube/background.ts index df3e9dcf2b..2aafd9cf21 100644 --- a/apps/typegpu-docs/src/examples/simple/ripple-cube/background.ts +++ b/apps/typegpu-docs/src/examples/simple/ripple-cube/background.ts @@ -128,7 +128,7 @@ export function createBackgroundCubemap(root: TgpuRoot): BackgroundCubemap { const FaceBasis = d.struct({ forward: d.vec3f, right: d.vec3f, up: d.vec3f }); const faceBasisUniform = root.createUniform(FaceBasis); - const renderFacePipeline = root['~unstable'] + const renderFacePipeline = root .pipe(perlinCache.inject()) .createGuardedComputePipeline((x, y) => { 'use gpu'; diff --git a/apps/typegpu-docs/src/examples/simple/ripple-cube/index.ts b/apps/typegpu-docs/src/examples/simple/ripple-cube/index.ts index db1fbcb56e..2f1bc2171f 100644 --- a/apps/typegpu-docs/src/examples/simple/ripple-cube/index.ts +++ b/apps/typegpu-docs/src/examples/simple/ripple-cube/index.ts @@ -82,7 +82,7 @@ const pointOffsets = tgpu.const( ); const extendedRippleUniform = root.createUniform(d.u32); -const sdfPrecalcPipeline = root['~unstable'] +const sdfPrecalcPipeline = root .with(timeAccess, timeUniform) .with(blendFactorAccess, blendFactorUniform) .createGuardedComputePipeline((x, y, z) => { @@ -160,7 +160,7 @@ const getRayForUV = (uv: d.v2f) => { return Ray({ origin: camera.position, direction: d.vec4f(direction, 0) }); }; -const rayMarchPipeline = root['~unstable'] +const rayMarchPipeline = root .pipe(perlinCache.inject()) .with(materialAccess, materialUniform) .with(lightsAccess, lightsUniform) diff --git a/apps/typegpu-docs/src/examples/simple/ripple-cube/pbr.ts b/apps/typegpu-docs/src/examples/simple/ripple-cube/pbr.ts index 94db02a3a1..31867f24b4 100644 --- a/apps/typegpu-docs/src/examples/simple/ripple-cube/pbr.ts +++ b/apps/typegpu-docs/src/examples/simple/ripple-cube/pbr.ts @@ -9,8 +9,8 @@ export const envMapLayout = tgpu.bindGroupLayout({ envSampler: { sampler: 'filtering' }, }); -export const materialAccess = tgpu['~unstable'].accessor(Material); -export const lightsAccess = tgpu['~unstable'].accessor( +export const materialAccess = tgpu.accessor(Material); +export const lightsAccess = tgpu.accessor( d.arrayOf(Light, LIGHT_COUNT), ); diff --git a/apps/typegpu-docs/src/examples/simple/ripple-cube/post-processing.ts b/apps/typegpu-docs/src/examples/simple/ripple-cube/post-processing.ts index 0d836a7939..c3f52ae727 100644 --- a/apps/typegpu-docs/src/examples/simple/ripple-cube/post-processing.ts +++ b/apps/typegpu-docs/src/examples/simple/ripple-cube/post-processing.ts @@ -4,7 +4,7 @@ import { fullScreenTriangle } from 'typegpu/common'; import { BLUR_RADIUS, TAA_BLEND } from './constants.ts'; import { BloomParams } from './types.ts'; -export const bloomParamsAccess = tgpu['~unstable'].accessor(BloomParams); +export const bloomParamsAccess = tgpu.accessor(BloomParams); const taaResolveLayout = tgpu.bindGroupLayout({ currentTexture: { texture: d.texture2d() }, @@ -65,7 +65,7 @@ export function createPostProcessingPipelines( minFilter: 'linear', }); - const taaResolve = root['~unstable'].createGuardedComputePipeline((x, y) => { + const taaResolve = root.createGuardedComputePipeline((x, y) => { 'use gpu'; const coord = d.vec2i(d.i32(x), d.i32(y)); const current = std.textureLoad( @@ -110,7 +110,7 @@ export function createPostProcessingPipelines( ); }); - const copyToHistory = root['~unstable'].createGuardedComputePipeline( + const copyToHistory = root.createGuardedComputePipeline( (x, y) => { 'use gpu'; const color = std.textureLoad( @@ -122,7 +122,7 @@ export function createPostProcessingPipelines( }, ); - const extractBright = root['~unstable'] + const extractBright = root .with(bloomParamsAccess, bloomUniform) .createGuardedComputePipeline( (x, y) => { @@ -154,7 +154,7 @@ export function createPostProcessingPipelines( const blurVertical = createBlurPass(root, 'vertical'); - const fragmentMain = tgpu['~unstable'].fragmentFn({ + const fragmentMain = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -180,7 +180,7 @@ export function createPostProcessingPipelines( return d.vec4f(final, 1); }); - const renderPipeline = root['~unstable'] + const renderPipeline = root .with(bloomParamsAccess, bloomUniform) .createRenderPipeline({ vertex: fullScreenTriangle, @@ -259,7 +259,7 @@ function createBlurPass( root: TgpuRoot, direction: 'horizontal' | 'vertical', ) { - return root['~unstable'].createGuardedComputePipeline((x, y) => { + return root.createGuardedComputePipeline((x, y) => { 'use gpu'; const dimensions = std.textureDimensions(processLayout.$.inputTexture); const texelSize = d.vec2f(1).div(d.vec2f(dimensions)); diff --git a/apps/typegpu-docs/src/examples/simple/ripple-cube/sdf-scene.ts b/apps/typegpu-docs/src/examples/simple/ripple-cube/sdf-scene.ts index 1eeb00f88f..f102321346 100644 --- a/apps/typegpu-docs/src/examples/simple/ripple-cube/sdf-scene.ts +++ b/apps/typegpu-docs/src/examples/simple/ripple-cube/sdf-scene.ts @@ -1,8 +1,8 @@ import * as sdf from '@typegpu/sdf'; import tgpu, { d, std } from 'typegpu'; -export const timeAccess = tgpu['~unstable'].accessor(d.f32); -export const blendFactorAccess = tgpu['~unstable'].accessor(d.f32); +export const timeAccess = tgpu.accessor(d.f32); +export const blendFactorAccess = tgpu.accessor(d.f32); export const sdfLayout = tgpu.bindGroupLayout({ sdfTexture: { texture: d.texture3d() }, diff --git a/apps/typegpu-docs/src/examples/simple/square/index.ts b/apps/typegpu-docs/src/examples/simple/square/index.ts index 65712dac0d..2560632f96 100644 --- a/apps/typegpu-docs/src/examples/simple/square/index.ts +++ b/apps/typegpu-docs/src/examples/simple/square/index.ts @@ -25,7 +25,7 @@ const colorBuffer = root .$usage('vertex'); const vertexLayout = tgpu.vertexLayout(d.arrayOf(d.vec4f)); -const vertex = tgpu['~unstable'].vertexFn({ +const vertex = tgpu.vertexFn({ in: { idx: d.builtin.vertexIndex, color: d.vec4f, @@ -47,7 +47,7 @@ const vertex = tgpu['~unstable'].vertexFn({ }; }); -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { color: d.vec4f, }, @@ -58,13 +58,12 @@ const indexBuffer = root .createBuffer(d.arrayOf(d.u16, 6), [0, 2, 1, 0, 3, 2]) .$usage('index'); -const pipeline = root['~unstable'] - .createRenderPipeline({ - attribs: { color: vertexLayout.attrib }, - vertex, - fragment: mainFragment, - targets: { format: presentationFormat }, - }) +const pipeline = root.createRenderPipeline({ + attribs: { color: vertexLayout.attrib }, + vertex, + fragment: mainFragment, + targets: { format: presentationFormat }, +}) .withIndexBuffer(indexBuffer); function render() { diff --git a/apps/typegpu-docs/src/examples/simple/stencil/index.ts b/apps/typegpu-docs/src/examples/simple/stencil/index.ts index ef0fa110b2..c2cae506d1 100644 --- a/apps/typegpu-docs/src/examples/simple/stencil/index.ts +++ b/apps/typegpu-docs/src/examples/simple/stencil/index.ts @@ -25,7 +25,7 @@ const triangleData = { const rotationUniform = root.createUniform(d.mat2x2f, d.mat2x2f.identity()); -const vertexFn = tgpu['~unstable'].vertexFn({ +const vertexFn = tgpu.vertexFn({ in: { vid: d.builtin.vertexIndex, }, @@ -45,34 +45,34 @@ const vertexFn = tgpu['~unstable'].vertexFn({ }; }); -const fragmentFn = tgpu['~unstable'].fragmentFn({ - in: { - uv: d.vec2f, - }, +const fragmentFn = tgpu.fragmentFn({ + in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => d.vec4f(uv, 0, 1)); -const basePipeline = root['~unstable'] - .withVertex(vertexFn); - -const writeStencilPipeline = basePipeline - .withDepthStencil({ - format: 'stencil8', - stencilFront: { passOp: 'replace' }, +const writeStencilPipeline = root + .createRenderPipeline({ + vertex: vertexFn, + depthStencil: { + format: 'stencil8', + stencilFront: { passOp: 'replace' }, + }, }) - .createPipeline() .withStencilReference(1); -const testStencilPipeline = basePipeline - .withFragment(fragmentFn, { format: presentationFormat }) - .withDepthStencil({ - format: 'stencil8', - stencilFront: { - compare: 'equal', - passOp: 'keep', +const testStencilPipeline = root + .createRenderPipeline({ + vertex: vertexFn, + fragment: fragmentFn, + targets: { format: presentationFormat }, + depthStencil: { + format: 'stencil8', + stencilFront: { + compare: 'equal', + passOp: 'keep', + }, }, }) - .createPipeline() .withStencilReference(1); writeStencilPipeline diff --git a/apps/typegpu-docs/src/examples/simple/triangle-next/index.ts b/apps/typegpu-docs/src/examples/simple/triangle-next/index.ts index caf0cba3b7..6ee30d8255 100644 --- a/apps/typegpu-docs/src/examples/simple/triangle-next/index.ts +++ b/apps/typegpu-docs/src/examples/simple/triangle-next/index.ts @@ -25,7 +25,7 @@ const uv = tgpu.const(d.arrayOf(d.vec2f, 3), [ d.vec2f(1.0, 0.0), ]); -const pipeline = root['~unstable'].createRenderPipeline({ +const pipeline = root.createRenderPipeline({ vertex: ({ $vertexIndex }) => { 'use gpu'; return { diff --git a/apps/typegpu-docs/src/examples/simple/triangle/index.ts b/apps/typegpu-docs/src/examples/simple/triangle/index.ts index c7cbed9c06..57a1ce8cf8 100644 --- a/apps/typegpu-docs/src/examples/simple/triangle/index.ts +++ b/apps/typegpu-docs/src/examples/simple/triangle/index.ts @@ -8,7 +8,7 @@ const getGradientColor = tgpu.fn([d.f32], d.vec4f) /* wgsl */`(ratio) { } `.$uses({ purple, blue }); -const mainVertex = tgpu['~unstable'].vertexFn({ +const mainVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { outPos: d.builtin.position, uv: d.vec2f }, }) /* wgsl */`{ @@ -27,7 +27,7 @@ const mainVertex = tgpu['~unstable'].vertexFn({ return Out(vec4f(pos[in.vertexIndex], 0.0, 1.0), uv[in.vertexIndex]); }`; -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, }) /* wgsl */`{ @@ -41,12 +41,11 @@ const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); const canvas = document.querySelector('canvas') as HTMLCanvasElement; const context = root.configureContext({ canvas, alphaMode: 'premultiplied' }); -const pipeline = root['~unstable'] - .createRenderPipeline({ - vertex: mainVertex, - fragment: mainFragment, - targets: { format: presentationFormat }, - }); +const pipeline = root.createRenderPipeline({ + vertex: mainVertex, + fragment: mainFragment, + targets: { format: presentationFormat }, +}); setTimeout(() => { pipeline diff --git a/apps/typegpu-docs/src/examples/simple/vaporrave/index.ts b/apps/typegpu-docs/src/examples/simple/vaporrave/index.ts index 0a5706074c..f525350a5d 100644 --- a/apps/typegpu-docs/src/examples/simple/vaporrave/index.ts +++ b/apps/typegpu-docs/src/examples/simple/vaporrave/index.ts @@ -91,7 +91,7 @@ const rayMarch = tgpu.fn( return { ray: result, glow }; }); -const vertexMain = tgpu['~unstable'].vertexFn({ +const vertexMain = tgpu.vertexFn({ in: { idx: d.builtin.vertexIndex }, out: { pos: d.builtin.position, uv: d.vec2f }, })(({ idx }) => { @@ -104,7 +104,7 @@ const vertexMain = tgpu['~unstable'].vertexFn({ }; }); -const fragmentMain = tgpu['~unstable'].fragmentFn({ +const fragmentMain = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => { @@ -138,7 +138,7 @@ const perlinCache = perlin3d.staticCache({ size: d.vec3u(7), }); -let renderPipeline = root['~unstable'] +let renderPipeline = root .with(floorPatternSlot, circles) .pipe(perlinCache.inject()) .createRenderPipeline({ @@ -223,7 +223,7 @@ export const controls = defineControls({ initial: 'circles', options: ['grid', 'circles'], onSelectChange: (value) => { - renderPipeline = root['~unstable'] + renderPipeline = root .with(floorPatternSlot, value === 'grid' ? grid : circles) .pipe(perlinCache.inject()) .createRenderPipeline({ diff --git a/apps/typegpu-docs/src/examples/simulation/boids/index.ts b/apps/typegpu-docs/src/examples/simulation/boids/index.ts index f339b0b8b3..6b305146a7 100644 --- a/apps/typegpu-docs/src/examples/simulation/boids/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/boids/index.ts @@ -90,7 +90,7 @@ const VertexOutput = { color: d.vec4f, }; -const mainVert = tgpu['~unstable'].vertexFn({ +const mainVert = tgpu.vertexFn({ in: { v: d.vec2f, center: d.vec2f, velocity: d.vec2f }, out: VertexOutput, })((input) => { @@ -106,7 +106,7 @@ const mainVert = tgpu['~unstable'].vertexFn({ return { position: pos, color }; }); -const mainFrag = tgpu['~unstable'].fragmentFn({ +const mainFrag = tgpu.fragmentFn({ in: VertexOutput, out: d.vec4f, })((input) => input.color); @@ -148,16 +148,17 @@ const TriangleDataArray = d.arrayOf(TriangleData); const vertexLayout = tgpu.vertexLayout(d.arrayOf(d.vec2f)); const instanceLayout = tgpu.vertexLayout(TriangleDataArray, 'instance'); -const renderPipeline = root['~unstable'] - .withVertex(mainVert, { - v: vertexLayout.attrib, - center: instanceLayout.attrib.position, - velocity: instanceLayout.attrib.velocity, +const renderPipeline = root + .createRenderPipeline({ + attribs: { + v: vertexLayout.attrib, + center: instanceLayout.attrib.position, + velocity: instanceLayout.attrib.velocity, + }, + vertex: mainVert, + fragment: mainFrag, + targets: { format: presentationFormat }, }) - .withFragment(mainFrag, { - format: presentationFormat, - }) - .createPipeline() .with(vertexLayout, triangleVertexBuffer); const layout = tgpu.bindGroupLayout({ @@ -236,8 +237,7 @@ const simulate = (index: number) => { layout.$.nextTrianglePos[index] = TriangleData(instanceInfo); }; -const simulatePipeline = root['~unstable'] - .createGuardedComputePipeline(simulate); +const simulatePipeline = root.createGuardedComputePipeline(simulate); const computeBindGroups = [0, 1].map((idx) => root.createBindGroup(layout, { diff --git a/apps/typegpu-docs/src/examples/simulation/confetti/index.ts b/apps/typegpu-docs/src/examples/simulation/confetti/index.ts index 4c654c6b48..5aa70fc118 100644 --- a/apps/typegpu-docs/src/examples/simulation/confetti/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/confetti/index.ts @@ -87,7 +87,7 @@ const rotate = tgpu.fn([d.vec2f, d.f32], d.vec2f)((v, angle) => { return pos; }); -const mainVert = tgpu['~unstable'].vertexFn({ +const mainVert = tgpu.vertexFn({ in: { tilt: d.f32, angle: d.f32, @@ -119,12 +119,12 @@ const mainVert = tgpu['~unstable'].vertexFn({ aspectRatio, }); -const mainFrag = tgpu['~unstable'].fragmentFn({ +const mainFrag = tgpu.fragmentFn({ in: VertexOutput, out: d.vec4f, }) /* wgsl */`{ return in.color; }`; -const mainCompute = tgpu['~unstable'].computeFn({ +const mainCompute = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [1], }) /* wgsl */`{ @@ -142,7 +142,7 @@ const mainCompute = tgpu['~unstable'].computeFn({ // pipelines -const renderPipeline = root['~unstable'] +const renderPipeline = root .createRenderPipeline({ vertex: mainVert, fragment: mainFrag, @@ -161,9 +161,7 @@ const renderPipeline = root['~unstable'] .with(geometryLayout, particleGeometryBuffer) .with(dataLayout, particleDataBuffer); -const computePipeline = root['~unstable'].createComputePipeline({ - compute: mainCompute, -}); +const computePipeline = root.createComputePipeline({ compute: mainCompute }); // compute and draw diff --git a/apps/typegpu-docs/src/examples/simulation/fluid-double-buffering/index.ts b/apps/typegpu-docs/src/examples/simulation/fluid-double-buffering/index.ts index bbcbada495..6a93d3578f 100644 --- a/apps/typegpu-docs/src/examples/simulation/fluid-double-buffering/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/fluid-double-buffering/index.ts @@ -377,7 +377,7 @@ const limitedBoxX = () => { let boxY = 0.2; let leftWallX = 0; -const vertexMain = tgpu['~unstable'].vertexFn({ +const vertexMain = tgpu.vertexFn({ in: { idx: d.builtin.vertexIndex }, out: { pos: d.builtin.position, uv: d.vec2f }, })((input) => { @@ -390,7 +390,7 @@ const vertexMain = tgpu['~unstable'].vertexFn({ }; }); -const fragmentMain = tgpu['~unstable'].fragmentFn({ +const fragmentMain = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => { @@ -448,7 +448,7 @@ function makePipelines( inputGridReadonly: TgpuBufferReadonly, outputGridMutable: TgpuBufferMutable, ) { - const initWorldPipeline = root['~unstable'] + const initWorldPipeline = root .with(outputGridSlot, outputGridMutable) .createGuardedComputePipeline((xu, yu) => { 'use gpu'; @@ -471,17 +471,17 @@ function makePipelines( outputGridSlot.$[index] = d.vec4f(value); }); - const simulatePipeline = root['~unstable'] + const simulatePipeline = root .with(inputGridSlot, inputGridReadonly) .with(outputGridSlot, outputGridMutable) .createGuardedComputePipeline(simulate); - const moveObstaclesPipeline = root['~unstable'] + const moveObstaclesPipeline = root .with(inputGridSlot, outputGridMutable) .with(outputGridSlot, outputGridMutable) .createGuardedComputePipeline(moveObstacles); - const renderPipeline = root['~unstable'] + const renderPipeline = root .with(inputGridSlot, inputGridReadonly) .createRenderPipeline({ vertex: vertexMain, diff --git a/apps/typegpu-docs/src/examples/simulation/fluid-with-atomics/index.ts b/apps/typegpu-docs/src/examples/simulation/fluid-with-atomics/index.ts index d23bd48714..06ad4e73f9 100644 --- a/apps/typegpu-docs/src/examples/simulation/fluid-with-atomics/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/fluid-with-atomics/index.ts @@ -248,7 +248,7 @@ const decideWaterLevel = tgpu.fn([d.u32, d.u32])((x, y) => { } }); -const vertex = tgpu['~unstable'].vertexFn({ +const vertex = tgpu.vertexFn({ in: { squareData: d.vec2f, currentStateData: d.u32, @@ -278,7 +278,7 @@ const vertex = tgpu['~unstable'].vertexFn({ return { pos: d.vec4f(x, y, 0, 1), cell }; }); -const fragment = tgpu['~unstable'].fragmentFn({ +const fragment = tgpu.fragmentFn({ in: { cell: d.f32 }, out: d.vec4f, })((input) => { @@ -321,18 +321,18 @@ let renderChanges: () => void; function resetGameData() { drawCanvasData = []; - const compute = tgpu['~unstable'].computeFn({ + const compute = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [options.workgroupSize, options.workgroupSize], })((input) => { decideWaterLevel(input.gid.x, input.gid.y); }); - const computePipeline = root['~unstable'].createComputePipeline({ + const computePipeline = root.createComputePipeline({ compute, }); - const renderPipeline = root['~unstable'] + const renderPipeline = root .createRenderPipeline({ attribs: { squareData: vertexLayout.attrib, diff --git a/apps/typegpu-docs/src/examples/simulation/game-of-life/index.ts b/apps/typegpu-docs/src/examples/simulation/game-of-life/index.ts index 3544d0c67a..959eb410d1 100644 --- a/apps/typegpu-docs/src/examples/simulation/game-of-life/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/game-of-life/index.ts @@ -37,7 +37,7 @@ function createGame() { getCell(x - 1, y + 1) + getCell(x, y + 1) + getCell(x + 1, y + 1); }; - const computeFn = root['~unstable'].createGuardedComputePipeline((x, y) => { + const computeFn = root.createGuardedComputePipeline((x, y) => { 'use gpu'; const n = countNeighbors(x, y); computeLayout.$.next[getIndex(x, y)] = d.u32( @@ -57,17 +57,18 @@ function createGame() { const squareVertexLayout = tgpu.vertexLayout(d.arrayOf(d.vec2u), 'vertex'); const cellsVertexLayout = tgpu.vertexLayout(d.arrayOf(d.u32), 'instance'); - const renderPipeline = root['~unstable'] + const renderPipeline = root .with(sizeSlot, size) - .withVertex(vertexFn, { - cell: cellsVertexLayout.attrib, - pos: squareVertexLayout.attrib, - }) - .withFragment(fragmentFn, { - format: presentationFormat, - }) - .withPrimitive({ topology: 'triangle-strip' }) - .createPipeline(); + .createRenderPipeline({ + attribs: { + cell: cellsVertexLayout.attrib, + pos: squareVertexLayout.attrib, + }, + vertex: vertexFn, + fragment: fragmentFn, + targets: { format: presentationFormat }, + primitive: { topology: 'triangle-strip' }, + }); const length = size.x * size.y; const buffers = [ diff --git a/apps/typegpu-docs/src/examples/simulation/game-of-life/shaders/fragment.ts b/apps/typegpu-docs/src/examples/simulation/game-of-life/shaders/fragment.ts index c1a4463e4c..32ca811f54 100644 --- a/apps/typegpu-docs/src/examples/simulation/game-of-life/shaders/fragment.ts +++ b/apps/typegpu-docs/src/examples/simulation/game-of-life/shaders/fragment.ts @@ -2,7 +2,7 @@ import tgpu from 'typegpu'; import * as d from 'typegpu/data'; import * as std from 'typegpu/std'; -export const fragmentFn = tgpu['~unstable'].fragmentFn({ +export const fragmentFn = tgpu.fragmentFn({ in: { cell: d.interpolate('flat', d.u32), uv: d.vec2f, diff --git a/apps/typegpu-docs/src/examples/simulation/game-of-life/shaders/vertex.ts b/apps/typegpu-docs/src/examples/simulation/game-of-life/shaders/vertex.ts index 4e35ca11af..40cd615161 100644 --- a/apps/typegpu-docs/src/examples/simulation/game-of-life/shaders/vertex.ts +++ b/apps/typegpu-docs/src/examples/simulation/game-of-life/shaders/vertex.ts @@ -4,7 +4,7 @@ import * as std from 'typegpu/std'; export const sizeSlot = tgpu.slot(d.vec2u(64, 64)); -export const vertexFn = tgpu['~unstable'].vertexFn({ +export const vertexFn = tgpu.vertexFn({ in: { iid: d.builtin.instanceIndex, cell: d.u32, diff --git a/apps/typegpu-docs/src/examples/simulation/gravity/compute.ts b/apps/typegpu-docs/src/examples/simulation/gravity/compute.ts index 6b99712a96..705651f389 100644 --- a/apps/typegpu-docs/src/examples/simulation/gravity/compute.ts +++ b/apps/typegpu-docs/src/examples/simulation/gravity/compute.ts @@ -21,7 +21,7 @@ const isSmaller = tgpu.fn([d.u32, d.u32], d.bool)((currentId, otherId) => { return false; }); -export const computeCollisionsShader = tgpu['~unstable'].computeFn({ +export const computeCollisionsShader = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [1], })((input) => { @@ -95,7 +95,7 @@ export const computeCollisionsShader = tgpu['~unstable'].computeFn({ computeLayout.$.outState[currentId] = CelestialBody(current); }); -export const computeGravityShader = tgpu['~unstable'].computeFn({ +export const computeGravityShader = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [1], })((input) => { diff --git a/apps/typegpu-docs/src/examples/simulation/gravity/index.ts b/apps/typegpu-docs/src/examples/simulation/gravity/index.ts index f30a4d93b5..27b72af639 100644 --- a/apps/typegpu-docs/src/examples/simulation/gravity/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/gravity/index.ts @@ -100,14 +100,14 @@ const dynamicResourcesBox = { }; // Pipelines -const computeCollisionsPipeline = root['~unstable'] +const computeCollisionsPipeline = root .createComputePipeline({ compute: computeCollisionsShader }); -const computeGravityPipeline = root['~unstable'] +const computeGravityPipeline = root .with(timeAccess, time) .createComputePipeline({ compute: computeGravityShader }); -const skyBoxPipeline = root['~unstable'] +const skyBoxPipeline = root .with(filteringSamplerSlot, sampler) .with(cameraAccess, camera) .with(skyBoxAccess, skyBox) @@ -118,7 +118,7 @@ const skyBoxPipeline = root['~unstable'] targets: { format: presentationFormat }, }); -const renderPipeline = root['~unstable'] +const renderPipeline = root .with(filteringSamplerSlot, sampler) .with(lightSourceAccess, lightSource) .with(cameraAccess, camera) diff --git a/apps/typegpu-docs/src/examples/simulation/gravity/render.ts b/apps/typegpu-docs/src/examples/simulation/gravity/render.ts index d3e6c05396..716419d2c4 100644 --- a/apps/typegpu-docs/src/examples/simulation/gravity/render.ts +++ b/apps/typegpu-docs/src/examples/simulation/gravity/render.ts @@ -10,7 +10,7 @@ import { VertexOutput, } from './schemas.ts'; -export const skyBoxVertex = tgpu['~unstable'].vertexFn({ +export const skyBoxVertex = tgpu.vertexFn({ in: { position: d.vec3f, uv: d.vec2f, @@ -31,7 +31,7 @@ export const skyBoxVertex = tgpu['~unstable'].vertexFn({ }; }); -export const skyBoxFragment = tgpu['~unstable'].fragmentFn({ +export const skyBoxFragment = tgpu.fragmentFn({ in: { texCoord: d.vec3f, }, @@ -44,7 +44,7 @@ export const skyBoxFragment = tgpu['~unstable'].fragmentFn({ ) ); -export const mainVertex = tgpu['~unstable'].vertexFn({ +export const mainVertex = tgpu.vertexFn({ in: { ...VertexInput, instanceIndex: d.builtin.instanceIndex, @@ -73,7 +73,7 @@ export const mainVertex = tgpu['~unstable'].vertexFn({ }; }); -export const mainFragment = tgpu['~unstable'].fragmentFn({ +export const mainFragment = tgpu.fragmentFn({ in: VertexOutput, out: d.vec4f, })((input) => { diff --git a/apps/typegpu-docs/src/examples/simulation/slime-mold-3d/index.ts b/apps/typegpu-docs/src/examples/simulation/slime-mold-3d/index.ts index 59a56e08a1..30a277d288 100644 --- a/apps/typegpu-docs/src/examples/simulation/slime-mold-3d/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/slime-mold-3d/index.ts @@ -99,7 +99,7 @@ const agentsDataBuffers = [0, 1].map(() => ); const mutableAgentsDataBuffers = agentsDataBuffers.map((b) => b.as('mutable')); -root['~unstable'].createGuardedComputePipeline((x) => { +root.createGuardedComputePipeline((x) => { 'use gpu'; randf.seed(x / NUM_AGENTS); const pos = randf.inUnitSphere().mul(resolution.x / 4).add(resolution.div(2)); @@ -211,7 +211,7 @@ const sense3D = (pos: d.v3f, direction: d.v3f) => { return SenseResult({ weightedDir, totalWeight }); }; -const updateAgents = tgpu['~unstable'].computeFn({ +const updateAgents = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [AGENT_WORKGROUP_SIZE], })(({ gid }) => { @@ -315,7 +315,7 @@ const getSummand = tgpu.fn([d.vec3f, d.vec3f], d.f32)((uv, offset) => ).x ); -const blur = tgpu['~unstable'].computeFn({ +const blur = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: BLUR_WORKGROUP_SIZE, })(({ gid }) => { @@ -361,7 +361,7 @@ const rayBoxIntersection = ( return RayBoxResult({ tNear, tFar, hit }); }; -const fragmentShader = tgpu['~unstable'].fragmentFn({ +const fragmentShader = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -441,17 +441,15 @@ const fragmentShader = tgpu['~unstable'].fragmentFn({ return d.vec4f(accum, alpha); }); -const renderPipeline = root['~unstable'].createRenderPipeline({ +const renderPipeline = root.createRenderPipeline({ vertex: common.fullScreenTriangle, fragment: fragmentShader, targets: { format: presentationFormat }, }); -const computePipeline = root['~unstable'] - .createComputePipeline({ compute: updateAgents }); +const computePipeline = root.createComputePipeline({ compute: updateAgents }); -const blurPipeline = root['~unstable'] - .createComputePipeline({ compute: blur }); +const blurPipeline = root.createComputePipeline({ compute: blur }); const bindGroups = [0, 1].map((i) => root.createBindGroup(computeLayout, { diff --git a/apps/typegpu-docs/src/examples/simulation/slime-mold/index.ts b/apps/typegpu-docs/src/examples/simulation/slime-mold/index.ts index 7268fe6d49..2110fa5f26 100644 --- a/apps/typegpu-docs/src/examples/simulation/slime-mold/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/slime-mold/index.ts @@ -32,7 +32,7 @@ const defaultParams = { const NUM_AGENTS = 200_000; const agentsData = root.createMutable(d.arrayOf(Agent, NUM_AGENTS)); -root['~unstable'].createGuardedComputePipeline((x) => { +root.createGuardedComputePipeline((x) => { 'use gpu'; randf.seed(x / NUM_AGENTS + 0.1); const pos = randf.inUnitCircle().mul(resolution.x / 2 - 10).add( @@ -85,7 +85,7 @@ const sense = (pos: d.v2f, angle: number, sensorAngleOffset: number) => { return color.x + color.y + color.z; }; -const updateAgents = tgpu['~unstable'].computeFn({ +const updateAgents = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [64], })(({ gid }) => { @@ -157,7 +157,7 @@ const updateAgents = tgpu['~unstable'].computeFn({ ); }); -const blur = tgpu['~unstable'].computeFn({ +const blur = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [16, 16], })(({ gid }) => { @@ -198,7 +198,7 @@ const blur = tgpu['~unstable'].computeFn({ ); }); -const fullScreenTriangle = tgpu['~unstable'].vertexFn({ +const fullScreenTriangle = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { pos: d.builtin.position, uv: d.vec2f }, })((input) => { @@ -216,25 +216,21 @@ const filteringSampler = root['~unstable'].createSampler({ minFilter: 'linear', }); -const fragmentShader = tgpu['~unstable'].fragmentFn({ +const fragmentShader = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { return std.textureSample(renderLayout.$.state, filteringSampler.$, uv); }); -const renderPipeline = root['~unstable'] - .withVertex(fullScreenTriangle, {}) - .withFragment(fragmentShader, { format: presentationFormat }) - .createPipeline(); - -const computePipeline = root['~unstable'] - .withCompute(updateAgents) - .createPipeline(); +const renderPipeline = root.createRenderPipeline({ + vertex: fullScreenTriangle, + fragment: fragmentShader, + targets: { format: presentationFormat }, +}); -const blurPipeline = root['~unstable'] - .withCompute(blur) - .createPipeline(); +const computePipeline = root.createComputePipeline({ compute: updateAgents }); +const blurPipeline = root.createComputePipeline({ compute: blur }); const bindGroups = [0, 1].map((i) => root.createBindGroup(computeLayout, { diff --git a/apps/typegpu-docs/src/examples/simulation/stable-fluid/index.ts b/apps/typegpu-docs/src/examples/simulation/stable-fluid/index.ts index 13fba129f5..141e659484 100644 --- a/apps/typegpu-docs/src/examples/simulation/stable-fluid/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/stable-fluid/index.ts @@ -38,9 +38,7 @@ function createField(name: string) { } function createComputePipeline(fn: TgpuComputeFn) { - return root['~unstable'].createComputePipeline({ - compute: fn, - }); + return root.createComputePipeline({ compute: fn }); } function toGrid(x: number, y: number): [number, number] { @@ -142,7 +140,7 @@ const addInkPipeline = createComputePipeline(c.addInkFn); function createRenderPipeline( fragmentFn: TgpuFragmentFn<{ uv: d.Vec2f }, d.Vec4f>, ) { - return root['~unstable'].createRenderPipeline({ + return root.createRenderPipeline({ vertex: renderFn, fragment: fragmentFn, targets: { format }, diff --git a/apps/typegpu-docs/src/examples/simulation/stable-fluid/render.ts b/apps/typegpu-docs/src/examples/simulation/stable-fluid/render.ts index edda88432c..c1de903bbd 100644 --- a/apps/typegpu-docs/src/examples/simulation/stable-fluid/render.ts +++ b/apps/typegpu-docs/src/examples/simulation/stable-fluid/render.ts @@ -7,7 +7,7 @@ export const renderLayout = tgpu.bindGroupLayout({ linSampler: { sampler: 'filtering' }, }); -export const renderFn = tgpu['~unstable'].vertexFn({ +export const renderFn = tgpu.vertexFn({ in: { idx: d.builtin.vertexIndex }, out: { pos: d.builtin.position, uv: d.vec2f }, })((input) => { @@ -17,7 +17,7 @@ export const renderFn = tgpu['~unstable'].vertexFn({ return { pos: d.vec4f(vertices[input.idx], 0, 1), uv: texCoords[input.idx] }; }); -export const fragmentInkFn = tgpu['~unstable'].fragmentFn({ +export const fragmentInkFn = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => { @@ -29,7 +29,7 @@ export const fragmentInkFn = tgpu['~unstable'].fragmentFn({ return d.vec4f(density, density * 0.8, density * 0.5, d.f32(1.0)); }); -export const fragmentVelFn = tgpu['~unstable'].fragmentFn({ +export const fragmentVelFn = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => { @@ -48,7 +48,7 @@ export const fragmentVelFn = tgpu['~unstable'].fragmentFn({ return outColor; }); -export const fragmentImageFn = tgpu['~unstable'].fragmentFn({ +export const fragmentImageFn = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => { diff --git a/apps/typegpu-docs/src/examples/simulation/stable-fluid/simulation.ts b/apps/typegpu-docs/src/examples/simulation/stable-fluid/simulation.ts index d1606521eb..21bb70bdbf 100644 --- a/apps/typegpu-docs/src/examples/simulation/stable-fluid/simulation.ts +++ b/apps/typegpu-docs/src/examples/simulation/stable-fluid/simulation.ts @@ -26,7 +26,7 @@ export const brushLayout = tgpu.bindGroupLayout({ inkDst: { storageTexture: d.textureStorage2d('rgba16float', 'write-only') }, }); -export const brushFn = tgpu['~unstable'].computeFn({ +export const brushFn = tgpu.computeFn({ workgroupSize: [p.WORKGROUP_SIZE_X, p.WORKGROUP_SIZE_Y], in: { gid: d.builtin.globalInvocationId }, })((input) => { @@ -69,7 +69,7 @@ export const addForcesLayout = tgpu.bindGroupLayout({ simParams: { uniform: p.ShaderParams }, }); -export const addForcesFn = tgpu['~unstable'].computeFn({ +export const addForcesFn = tgpu.computeFn({ workgroupSize: [p.WORKGROUP_SIZE_X, p.WORKGROUP_SIZE_Y], in: { gid: d.builtin.globalInvocationId }, })((input) => { @@ -88,7 +88,7 @@ export const advectLayout = tgpu.bindGroupLayout({ linSampler: { sampler: 'filtering' }, }); -export const advectFn = tgpu['~unstable'].computeFn({ +export const advectFn = tgpu.computeFn({ workgroupSize: [p.WORKGROUP_SIZE_X, p.WORKGROUP_SIZE_Y], in: { gid: d.builtin.globalInvocationId }, })((input) => { @@ -132,7 +132,7 @@ export const diffusionLayout = tgpu.bindGroupLayout({ simParams: { uniform: p.ShaderParams }, }); -export const diffusionFn = tgpu['~unstable'].computeFn({ +export const diffusionFn = tgpu.computeFn({ workgroupSize: [p.WORKGROUP_SIZE_X, p.WORKGROUP_SIZE_Y], in: { gid: d.builtin.globalInvocationId }, })((input) => { @@ -170,7 +170,7 @@ export const divergenceLayout = tgpu.bindGroupLayout({ div: { storageTexture: d.textureStorage2d('rgba16float', 'write-only') }, }); -export const divergenceFn = tgpu['~unstable'].computeFn({ +export const divergenceFn = tgpu.computeFn({ workgroupSize: [p.WORKGROUP_SIZE_X, p.WORKGROUP_SIZE_Y], in: { gid: d.builtin.globalInvocationId }, })((input) => { @@ -201,7 +201,7 @@ export const pressureLayout = tgpu.bindGroupLayout({ out: { storageTexture: d.textureStorage2d('rgba16float', 'write-only') }, }); -export const pressureFn = tgpu['~unstable'].computeFn({ +export const pressureFn = tgpu.computeFn({ workgroupSize: [p.WORKGROUP_SIZE_X, p.WORKGROUP_SIZE_Y], in: { gid: d.builtin.globalInvocationId }, })((input) => { @@ -232,7 +232,7 @@ export const projectLayout = tgpu.bindGroupLayout({ out: { storageTexture: d.textureStorage2d('rgba16float', 'write-only') }, }); -export const projectFn = tgpu['~unstable'].computeFn({ +export const projectFn = tgpu.computeFn({ workgroupSize: [p.WORKGROUP_SIZE_X, p.WORKGROUP_SIZE_Y], in: { gid: d.builtin.globalInvocationId }, })((input) => { @@ -263,7 +263,7 @@ export const advectInkLayout = tgpu.bindGroupLayout({ linSampler: { sampler: 'filtering' }, }); -export const advectInkFn = tgpu['~unstable'].computeFn({ +export const advectInkFn = tgpu.computeFn({ workgroupSize: [p.WORKGROUP_SIZE_X, p.WORKGROUP_SIZE_Y], in: { gid: d.builtin.globalInvocationId }, })((input) => { @@ -298,7 +298,7 @@ export const addInkLayout = tgpu.bindGroupLayout({ add: { texture: d.texture2d(d.f32) }, }); -export const addInkFn = tgpu['~unstable'].computeFn({ +export const addInkFn = tgpu.computeFn({ workgroupSize: [p.WORKGROUP_SIZE_X, p.WORKGROUP_SIZE_Y], in: { gid: d.builtin.globalInvocationId }, })((input) => { diff --git a/apps/typegpu-docs/src/examples/simulation/wind-map/index.ts b/apps/typegpu-docs/src/examples/simulation/wind-map/index.ts index 60c0b558d7..b2ef5a043e 100644 --- a/apps/typegpu-docs/src/examples/simulation/wind-map/index.ts +++ b/apps/typegpu-docs/src/examples/simulation/wind-map/index.ts @@ -105,7 +105,7 @@ const vectorField = tgpu.fn([vec2f], vec2f)((pos) => { }); const WORKGROUP_SIZE = 64; -const advectCompute = tgpu['~unstable'].computeFn({ +const advectCompute = tgpu.computeFn({ in: { globalInvocationId: builtin.globalInvocationId }, workgroupSize: [WORKGROUP_SIZE], })(({ globalInvocationId }) => { @@ -125,7 +125,7 @@ const advectCompute = tgpu['~unstable'].computeFn({ const lineWidth = tgpu.fn([f32], f32)((x) => 0.004 * (1 - x)); -const mainVertex = tgpu['~unstable'].vertexFn({ +const mainVertex = tgpu.vertexFn({ in: { instanceIndex: builtin.instanceIndex, vertexIndex: builtin.vertexIndex, @@ -187,7 +187,7 @@ const mainVertex = tgpu['~unstable'].vertexFn({ }; }); -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { position: vec2f, trailPosition: f32, @@ -214,20 +214,17 @@ const alphaBlend: GPUBlendState = { }; function createPipelines() { - const advect = root['~unstable'] - .withCompute(advectCompute) - .createPipeline(); + const advect = root.createComputePipeline({ compute: advectCompute }); - const fill = root['~unstable'] + const fill = root .with(joinSlot, lineJoins.round) .with(startCapSlot, lineCaps.arrow) .with(endCapSlot, lineCaps.butt) - .withVertex(mainVertex, {}) - .withFragment(mainFragment, { - format: presentationFormat, - blend: alphaBlend, + .createRenderPipeline({ + vertex: mainVertex, + fragment: mainFragment, + targets: { format: presentationFormat, blend: alphaBlend }, }) - .createPipeline() .withIndexBuffer(indexBuffer); return { diff --git a/apps/typegpu-docs/src/examples/tests/dispatch/index.ts b/apps/typegpu-docs/src/examples/tests/dispatch/index.ts index 564d76a15c..26d91d6c30 100644 --- a/apps/typegpu-docs/src/examples/tests/dispatch/index.ts +++ b/apps/typegpu-docs/src/examples/tests/dispatch/index.ts @@ -11,7 +11,7 @@ function isEqual(e1: unknown, e2: unknown): boolean { async function test0d(): Promise { const mutable = root.createMutable(d.u32); - root['~unstable'].createGuardedComputePipeline(() => { + root.createGuardedComputePipeline(() => { 'use gpu'; mutable.$ = 126; }).dispatchThreads(); @@ -22,7 +22,7 @@ async function test0d(): Promise { async function test1d(): Promise { const size = [7] as const; const mutable = root.createMutable(d.arrayOf(d.u32, size[0])); - root['~unstable'].createGuardedComputePipeline((x) => { + root.createGuardedComputePipeline((x) => { 'use gpu'; mutable.$[x] = x; }).dispatchThreads(...size); @@ -35,7 +35,7 @@ async function test2d(): Promise { const mutable = root.createMutable( d.arrayOf(d.arrayOf(d.vec2u, size[1]), size[0]), ); - root['~unstable'].createGuardedComputePipeline((x, y) => { + root.createGuardedComputePipeline((x, y) => { 'use gpu'; mutable.$[x][y] = d.vec2u(x, y); }).dispatchThreads(...size); @@ -54,7 +54,7 @@ async function test3d(): Promise { size[0], ), ); - root['~unstable'].createGuardedComputePipeline((x, y, z) => { + root.createGuardedComputePipeline((x, y, z) => { 'use gpu'; mutable.$[x][y][z] = d.vec3u(x, y, z); }).dispatchThreads(...size); @@ -67,7 +67,7 @@ async function test3d(): Promise { async function testWorkgroupSize(): Promise { const mutable = root.createMutable(d.atomic(d.u32)); - root['~unstable'].createGuardedComputePipeline((_x, _y, _z) => { + root.createGuardedComputePipeline((_x, _y, _z) => { 'use gpu'; std.atomicAdd(mutable.$, 1); }).dispatchThreads(4, 3, 2); @@ -79,7 +79,7 @@ async function testMultipleDispatches(): Promise { const size = [7] as const; const mutable = root .createMutable(d.arrayOf(d.u32, size[0]), [0, 1, 2, 3, 4, 5, 6]); - const test = root['~unstable'].createGuardedComputePipeline((x: number) => { + const test = root.createGuardedComputePipeline((x: number) => { 'use gpu'; mutable.$[x] *= 2; }); @@ -105,7 +105,7 @@ async function testDifferentBindGroups(): Promise { buffer: buffer2, }); - const test = root['~unstable'].createGuardedComputePipeline(() => { + const test = root.createGuardedComputePipeline(() => { 'use gpu'; for (let i = d.u32(); i < std.arrayLength(layout.$.buffer); i++) { layout.$.buffer[i] *= 2; @@ -129,8 +129,8 @@ async function testSlots(): Promise { result.$ += valueSlot.$; }; - root['~unstable'].createGuardedComputePipeline(main).dispatchThreads(); // add 1 - root['~unstable'] + root.createGuardedComputePipeline(main).dispatchThreads(); // add 1 + root .with(valueSlot, 3) .createGuardedComputePipeline(main) .dispatchThreads(); // add 3 diff --git a/apps/typegpu-docs/src/examples/tests/log-test/index.ts b/apps/typegpu-docs/src/examples/tests/log-test/index.ts index 6c0b2251de..0cbccbf381 100644 --- a/apps/typegpu-docs/src/examples/tests/log-test/index.ts +++ b/apps/typegpu-docs/src/examples/tests/log-test/index.ts @@ -15,7 +15,7 @@ const root = await tgpu.init({ const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); const canvas = document.querySelector('canvas') as HTMLCanvasElement; -const mainVertex = tgpu['~unstable'].vertexFn({ +const mainVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { pos: d.builtin.position }, })((input) => { @@ -28,7 +28,7 @@ const mainVertex = tgpu['~unstable'].vertexFn({ return { pos: d.vec4f(positions[input.vertexIndex], 0, 1) }; }); -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { pos: d.builtin.position }, out: d.vec4f, })(({ pos }) => { @@ -43,28 +43,28 @@ const context = root.configureContext({ canvas, alphaMode: 'premultiplied' }); export const controls = defineControls({ 'One argument': { onButtonClick: () => - root['~unstable'].createGuardedComputePipeline(() => { + root.createGuardedComputePipeline(() => { 'use gpu'; console.log(d.u32(321)); }).dispatchThreads(), }, 'Multiple arguments': { onButtonClick: () => - root['~unstable'].createGuardedComputePipeline(() => { + root.createGuardedComputePipeline(() => { 'use gpu'; console.log(1, d.vec3u(2, 3, 4), 5, 6); }).dispatchThreads(), }, 'String literals': { onButtonClick: () => - root['~unstable'].createGuardedComputePipeline(() => { + root.createGuardedComputePipeline(() => { 'use gpu'; console.log(2, 'plus', 3, 'equals', 5); }).dispatchThreads(), }, 'Two logs': { onButtonClick: () => - root['~unstable'].createGuardedComputePipeline(() => { + root.createGuardedComputePipeline(() => { 'use gpu'; console.log('First log.'); console.log('Second log.'); @@ -72,7 +72,7 @@ export const controls = defineControls({ }, 'Different types': { onButtonClick: () => - root['~unstable'].createGuardedComputePipeline(() => { + root.createGuardedComputePipeline(() => { 'use gpu'; console.log('--- scalars ---'); console.log(d.f32(3.14)); @@ -121,7 +121,7 @@ export const controls = defineControls({ const SimpleArray = d.arrayOf(d.u32, 2); const ComplexArray = d.arrayOf(SimpleArray, 3); - root['~unstable'].createGuardedComputePipeline(() => { + root.createGuardedComputePipeline(() => { 'use gpu'; const simpleStruct = SimpleStruct({ vec: d.vec3u(1, 2, 3), num: 4 }); console.log(simpleStruct); @@ -142,7 +142,7 @@ export const controls = defineControls({ }, 'Two threads': { onButtonClick: () => - root['~unstable'].createGuardedComputePipeline((x) => { + root.createGuardedComputePipeline((x) => { 'use gpu'; console.log('Log from thread', x); }).dispatchThreads(2), @@ -150,7 +150,7 @@ export const controls = defineControls({ '100 dispatches': { onButtonClick: async () => { const indexUniform = root.createUniform(d.u32); - const test = root['~unstable'].createGuardedComputePipeline(() => { + const test = root.createGuardedComputePipeline(() => { 'use gpu'; console.log('Log from dispatch', indexUniform.$); }); @@ -163,7 +163,7 @@ export const controls = defineControls({ 'Varying size logs': { onButtonClick: async () => { const logCountUniform = root.createUniform(d.u32); - const test = root['~unstable'].createGuardedComputePipeline(() => { + const test = root.createGuardedComputePipeline(() => { 'use gpu'; for (let i = d.u32(); i < logCountUniform.$; i++) { console.log('Log index', i + 1, 'out of', logCountUniform.$); @@ -177,7 +177,7 @@ export const controls = defineControls({ }, 'String interpolation': { onButtonClick: async () => - root['~unstable'].createGuardedComputePipeline(() => { + root.createGuardedComputePipeline(() => { 'use gpu'; console.log( 'The values %d, %f and %s were interpolated in this message.', @@ -195,7 +195,7 @@ export const controls = defineControls({ }, 'Different log functionalities': { onButtonClick: async () => - root['~unstable'].createGuardedComputePipeline(() => { + root.createGuardedComputePipeline(() => { 'use gpu'; console.log('This message should be cleared.'); console.clear(); @@ -213,7 +213,7 @@ export const controls = defineControls({ alphaMode: 'premultiplied', }); - const pipeline = root['~unstable'].createRenderPipeline({ + const pipeline = root.createRenderPipeline({ vertex: mainVertex, fragment: mainFragment, targets: { format: presentationFormat }, @@ -231,7 +231,7 @@ export const controls = defineControls({ }, 'Draw indexed': { onButtonClick: () => { - const pipeline = root['~unstable'].createRenderPipeline({ + const pipeline = root.createRenderPipeline({ vertex: mainVertex, fragment: mainFragment, targets: { format: presentationFormat }, @@ -253,7 +253,7 @@ export const controls = defineControls({ }, 'Too many logs': { onButtonClick: () => - root['~unstable'].createGuardedComputePipeline((x) => { + root.createGuardedComputePipeline((x) => { 'use gpu'; console.log('Log 1 from thread', x); console.log('Log 2 from thread', x); diff --git a/apps/typegpu-docs/src/examples/tests/texture-test/index.ts b/apps/typegpu-docs/src/examples/tests/texture-test/index.ts index 92fa6e5f08..c659295bdc 100644 --- a/apps/typegpu-docs/src/examples/tests/texture-test/index.ts +++ b/apps/typegpu-docs/src/examples/tests/texture-test/index.ts @@ -90,7 +90,7 @@ function createPipelineForFormat(format: TestFormat) { const sampler = filterable ? filteringSampler : nearestSampler; - const fragmentFunction = tgpu['~unstable'].fragmentFn({ + const fragmentFunction = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })`{ @@ -109,10 +109,11 @@ function createPipelineForFormat(format: TestFormat) { channel: channelUniform, }); - const pipeline = root['~unstable'] - .withVertex(common.fullScreenTriangle) - .withFragment(fragmentFunction, { format: presentationFormat }) - .createPipeline(); + const pipeline = root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: fragmentFunction, + targets: { format: presentationFormat }, + }); return { layout, pipeline }; } diff --git a/apps/typegpu-docs/src/examples/tests/tgsl-parsing-test/index.ts b/apps/typegpu-docs/src/examples/tests/tgsl-parsing-test/index.ts index ecc7a53870..93ee265748 100644 --- a/apps/typegpu-docs/src/examples/tests/tgsl-parsing-test/index.ts +++ b/apps/typegpu-docs/src/examples/tests/tgsl-parsing-test/index.ts @@ -9,7 +9,7 @@ import { defineControls } from '../../common/defineControls.ts'; const root = await tgpu.init(); const result = root.createMutable(d.i32, 0); -const computeRunTests = tgpu['~unstable'] +const computeRunTests = tgpu .computeFn({ workgroupSize: [1] })(() => { let s = true; s = s && logicalExpressionTests(); @@ -25,7 +25,7 @@ const computeRunTests = tgpu['~unstable'] } }); -const pipeline = root['~unstable'].createComputePipeline({ +const pipeline = root.createComputePipeline({ compute: computeRunTests, }); diff --git a/apps/typegpu-docs/src/examples/tests/uniformity/index.ts b/apps/typegpu-docs/src/examples/tests/uniformity/index.ts index b00f073965..42ee6ceda6 100644 --- a/apps/typegpu-docs/src/examples/tests/uniformity/index.ts +++ b/apps/typegpu-docs/src/examples/tests/uniformity/index.ts @@ -17,7 +17,7 @@ const canvasRatioUniform = root.createUniform( canvas.width / canvas.height, ); -const fragmentShader = tgpu['~unstable'].fragmentFn({ +const fragmentShader = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })((input) => { @@ -35,14 +35,13 @@ let prng: PRNG = c.initialPRNG; const redraw = () => { let pipeline = pipelineCache.get(prng); if (!pipeline) { - pipeline = root['~unstable'] + pipeline = root .with(randomGeneratorSlot, getPRNG(prng)) - .withVertex(common.fullScreenTriangle) - .withFragment( - fragmentShader, - { format: presentationFormat }, - ) - .createPipeline(); + .createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: fragmentShader, + targets: { format: presentationFormat }, + }); pipelineCache.set(prng, pipeline); } @@ -79,14 +78,13 @@ export const controls = defineControls({ c.prngs .map((prng) => tgpu.resolve([ - root['~unstable'] + root .with(randomGeneratorSlot, getPRNG(prng)) - .withVertex(common.fullScreenTriangle) - .withFragment( - fragmentShader, - { format: presentationFormat }, - ) - .createPipeline(), + .createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: fragmentShader, + targets: { format: presentationFormat }, + }), ], { names: namespace }) ) .map((r) => root.device.createShaderModule({ code: r })); diff --git a/apps/typegpu-docs/src/examples/tests/wgsl-resolution/index.ts b/apps/typegpu-docs/src/examples/tests/wgsl-resolution/index.ts index fef91effdf..bca38e9906 100644 --- a/apps/typegpu-docs/src/examples/tests/wgsl-resolution/index.ts +++ b/apps/typegpu-docs/src/examples/tests/wgsl-resolution/index.ts @@ -57,7 +57,7 @@ const VertexOutput = { color: d.vec4f, }; -const mainVert = tgpu['~unstable'].vertexFn({ +const mainVert = tgpu.vertexFn({ in: { v: d.vec2f, center: d.vec2f, velocity: d.vec2f }, out: VertexOutput, })((input) => { @@ -82,14 +82,14 @@ const mainVert = tgpu['~unstable'].vertexFn({ return { position: pos, color }; }).$name('vertex shader'); -const mainFrag = tgpu['~unstable'] +const mainFrag = tgpu .fragmentFn({ in: VertexOutput, out: d.vec4f, })((input) => input.color) .$name('fragment shader'); -const mainCompute = tgpu['~unstable'].computeFn({ +const mainCompute = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [1], })((input) => { diff --git a/packages/typegpu-geometry/src/lines/constants.ts b/packages/typegpu-geometry/src/lines/constants.ts index e0233f7ed5..eac34ff307 100644 --- a/packages/typegpu-geometry/src/lines/constants.ts +++ b/packages/typegpu-geometry/src/lines/constants.ts @@ -1,4 +1,4 @@ import tgpu from 'typegpu'; import { f32 } from 'typegpu/data'; -export const JOIN_LIMIT = tgpu['~unstable'].const(f32, 0.999); +export const JOIN_LIMIT = tgpu.const(f32, 0.999); diff --git a/packages/typegpu-noise/src/perlin-2d/dynamic-cache.ts b/packages/typegpu-noise/src/perlin-2d/dynamic-cache.ts index 7dfad5f8fe..03fbbd7a52 100644 --- a/packages/typegpu-noise/src/perlin-2d/dynamic-cache.ts +++ b/packages/typegpu-noise/src/perlin-2d/dynamic-cache.ts @@ -91,8 +91,9 @@ const DefaultPerlin2DLayoutPrefix = 'perlin2dCache__' as const; * // Plugging the cache into the pipeline * .pipe(cacheConfig.inject(dynamicLayout.$)) * // ... - * .withFragment(mainFragment) - * .createPipeline(); + * .createRenderPipeline({ + * // ... + * }); * * const frame = () => { * // A bind group to fulfill the resource needs of the cache @@ -169,8 +170,7 @@ export function dynamicCacheConfig( .createBuffer(d.vec2u, size) .$usage('uniform'); - const computePipeline = root['~unstable'] - .createGuardedComputePipeline(mainCompute); + const computePipeline = root.createGuardedComputePipeline(mainCompute); const createMemory = () => { const memory = root diff --git a/packages/typegpu-noise/src/perlin-2d/static-cache.ts b/packages/typegpu-noise/src/perlin-2d/static-cache.ts index cba941542b..8a627c56b7 100644 --- a/packages/typegpu-noise/src/perlin-2d/static-cache.ts +++ b/packages/typegpu-noise/src/perlin-2d/static-cache.ts @@ -31,8 +31,9 @@ export interface StaticPerlin2DCache { * // Plugging the cache into the pipeline * .pipe(cache.inject()) * // ... - * .withFragment(mainFragment) - * .createPipeline(); + * .createRenderPipeline({ + * // ... + * }); * ``` * * --- Wrapped coordinates @@ -64,7 +65,7 @@ export function staticCache(options: { const memoryReadonly = memoryBuffer.as('readonly'); const memoryMutable = memoryBuffer.as('mutable'); - const computePipeline = root['~unstable'] + const computePipeline = root .createGuardedComputePipeline((x, y) => { 'use gpu'; const idx = x + y * size.x; diff --git a/packages/typegpu-noise/src/perlin-3d/dynamic-cache.ts b/packages/typegpu-noise/src/perlin-3d/dynamic-cache.ts index 4b5a6ffd31..9d7957369a 100644 --- a/packages/typegpu-noise/src/perlin-3d/dynamic-cache.ts +++ b/packages/typegpu-noise/src/perlin-3d/dynamic-cache.ts @@ -91,8 +91,9 @@ const DefaultPerlin3DLayoutPrefix = 'perlin3dCache__' as const; * // Plugging the cache into the pipeline * .pipe(perlinCacheConfig.inject(dynamicLayout.$)) * // ... - * .withFragment(mainFragment) - * .createPipeline(); + * .createRenderPipeline({ + * // ... + * }); * * const frame = () => { * // A bind group to fulfill the resource needs of the cache @@ -170,7 +171,7 @@ export function dynamicCacheConfig( .createBuffer(d.vec4u, size) .$usage('uniform'); - const computePipeline = root['~unstable'] + const computePipeline = root .createGuardedComputePipeline(mainCompute); const createMemory = () => { diff --git a/packages/typegpu-noise/src/perlin-3d/static-cache.ts b/packages/typegpu-noise/src/perlin-3d/static-cache.ts index 6419bf435d..916bdffd62 100644 --- a/packages/typegpu-noise/src/perlin-3d/static-cache.ts +++ b/packages/typegpu-noise/src/perlin-3d/static-cache.ts @@ -31,8 +31,9 @@ export interface StaticPerlin3DCache { * // Plugging the cache into the pipeline * .pipe(cache.inject()) * // ... - * .withFragment(mainFragment) - * .createPipeline(); + * .createRenderPipeline({ + * // ... + * }); * ``` * * --- Wrapped coordinates @@ -65,7 +66,7 @@ export function staticCache(options: { const memoryReadonly = memoryBuffer.as('readonly'); const memoryMutable = memoryBuffer.as('mutable'); - const computePipeline = root['~unstable'] + const computePipeline = root .createGuardedComputePipeline((x, y, z) => { 'use gpu'; const idx = x + diff --git a/packages/typegpu-sdf/README.md b/packages/typegpu-sdf/README.md index 5b3a492eab..14119c82d2 100644 --- a/packages/typegpu-sdf/README.md +++ b/packages/typegpu-sdf/README.md @@ -12,7 +12,7 @@ A set of signed distance functions and utilities for use in WebGPU/TypeGPU apps. import tgpu, { d } from 'typegpu'; import * as sdf from '@typegpu/sdf'; -const mainFragment = tgpu['~unstable'].fragmentFn({ +const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { diff --git a/packages/typegpu/README.md b/packages/typegpu/README.md index ab2e2ab9a0..f72b70d39a 100644 --- a/packages/typegpu/README.md +++ b/packages/typegpu/README.md @@ -37,7 +37,7 @@ const wgsl = tgpu.resolve([main]); // // #3) Executed on the GPU (generates WGSL underneath) // -root['~unstable'] +root .createGuardedComputePipeline(main) .dispatchThreads(); ``` diff --git a/packages/typegpu/src/common/fullScreenTriangle.ts b/packages/typegpu/src/common/fullScreenTriangle.ts index 1d94c6f21d..3add862035 100644 --- a/packages/typegpu/src/common/fullScreenTriangle.ts +++ b/packages/typegpu/src/common/fullScreenTriangle.ts @@ -8,12 +8,12 @@ import { vec2f } from '../data/vector.ts'; * * @example * ```ts - * import { fullScreenTriangle } from 'typegpu/common'; + * import { common } from 'typegpu'; * - * const pipeline = root['~unstable'] - * .withVertex(fullScreenTriangle) - * .withFragment(yourFragmentShader) - * .createPipeline(); + * const pipeline = root.createRenderPipeline({ + * vertex: common.fullScreenTriangle, + * fragment: yourFragmentShader, + * }); * * pipeline.draw(3); * ``` diff --git a/packages/typegpu/src/core/root/init.ts b/packages/typegpu/src/core/root/init.ts index 7baefd977e..c4858fe71b 100644 --- a/packages/typegpu/src/core/root/init.ts +++ b/packages/typegpu/src/core/root/init.ts @@ -460,7 +460,7 @@ class WithFragmentImpl implements WithFragment { */ class TgpuRootImpl extends WithBindingImpl implements TgpuRoot, ExperimentalTgpuRoot { - '~unstable': Omit; + '~unstable': TgpuRoot['~unstable']; private _unwrappedBindGroupLayouts = new WeakMemo( (key: TgpuBindGroupLayout) => key.unwrap(this), diff --git a/packages/typegpu/src/core/root/rootTypes.ts b/packages/typegpu/src/core/root/rootTypes.ts index 641bd06aca..4d80c00113 100644 --- a/packages/typegpu/src/core/root/rootTypes.ts +++ b/packages/typegpu/src/core/root/rootTypes.ts @@ -252,6 +252,33 @@ export interface Withable { ): TSelf; } +export interface Withable_Deprecated { + /** + * @deprecated This feature is stable, remove the `['~unstable']` + * @param slot + * @param value + */ + with(slot: TgpuSlot, value: Eventual): TSelf; + /** + * @deprecated This feature is stable, remove the `['~unstable']` + * @param slot + * @param value + */ + with( + accessor: TgpuAccessor, + value: TgpuAccessor.In>, + ): TSelf; + /** + * @deprecated This feature is stable, remove the `['~unstable']` + * @param slot + * @param value + */ + with( + accessor: TgpuMutableAccessor, + value: TgpuMutableAccessor.In>, + ): TSelf; +} + export interface Configurable extends Withable { readonly bindings: [slot: TgpuSlot, value: unknown][]; @@ -271,6 +298,7 @@ type NormalizeOutput = T extends : { [K in keyof OmitBuiltins]: InstanceToSchema[K]> }; export interface WithBinding extends Withable { + /** @deprecated Use `root.createComputePipeline` instead. */ withCompute>( entryFn: TgpuComputeFn, ): WithCompute; @@ -786,7 +814,7 @@ export type ConfigureContextOptions = { format?: GPUTextureFormat; } & Omit; -export interface TgpuRoot extends Unwrapper { +export interface TgpuRoot extends Unwrapper, WithBinding { [$internal]: { logOptions: LogGeneratorOptions; }; @@ -976,10 +1004,25 @@ export interface TgpuRoot extends Unwrapper { */ destroy(): void; - '~unstable': Omit; + '~unstable': Pick< + ExperimentalTgpuRoot, + | 'beginRenderPass' + | 'createComparisonSampler' + | 'createGuardedComputePipeline' + | 'createSampler' + | 'createTexture' + | 'flush' + | 'nameRegistrySetting' + | 'shaderGenerator' + | 'pipe' + | 'with' + | 'withCompute' + | 'withVertex' + >; } -export interface ExperimentalTgpuRoot extends TgpuRoot, WithBinding { +export interface ExperimentalTgpuRoot + extends Omit, Withable_Deprecated { readonly nameRegistrySetting: 'strict' | 'random'; readonly shaderGenerator?: | ShaderGenerator @@ -1035,4 +1078,26 @@ export interface ExperimentalTgpuRoot extends TgpuRoot, WithBinding { * which makes this method unnecessary. */ flush(): void; + + /** @deprecated Use `root.createComputePipeline` instead. */ + withCompute>( + entryFn: TgpuComputeFn, + ): WithCompute; + + /** @deprecated This feature is now stable, use `root.createGuardedComputePipeline`. */ + createGuardedComputePipeline( + callback: (...args: TArgs) => void, + ): TgpuGuardedComputePipeline; + + /** @deprecated Use `root.createRenderPipeline` instead. */ + withVertex< + VertexIn extends TgpuVertexFn.In, + VertexOut extends TgpuVertexFn.Out, + >( + entryFn: TgpuVertexFn, + ...args: OptionalArgs>> + ): WithVertex; + + /** @deprecated This feature is now stable, use `root.pipe`. */ + pipe(transform: (cfg: Configurable) => Configurable): WithBinding; } diff --git a/packages/typegpu/src/tgpu.ts b/packages/typegpu/src/tgpu.ts index f9587e63ed..77267ee113 100644 --- a/packages/typegpu/src/tgpu.ts +++ b/packages/typegpu/src/tgpu.ts @@ -11,5 +11,8 @@ export { accessor, mutableAccessor } from './core/slot/accessor.ts'; export { privateVar, workgroupVar } from './core/variable/tgpuVariable.ts'; export { vertexLayout } from './core/vertexLayout/vertexLayout.ts'; export { bindGroupLayout } from './tgpuBindGroupLayout.ts'; +export { computeFn } from './core/function/tgpuComputeFn.ts'; +export { fragmentFn } from './core/function/tgpuFragmentFn.ts'; +export { vertexFn } from './core/function/tgpuVertexFn.ts'; export * as '~unstable' from './tgpuUnstable.ts'; diff --git a/packages/typegpu/src/tgpuUnstable.ts b/packages/typegpu/src/tgpuUnstable.ts index 07d27928e8..ca40ad6b6e 100644 --- a/packages/typegpu/src/tgpuUnstable.ts +++ b/packages/typegpu/src/tgpuUnstable.ts @@ -9,13 +9,22 @@ export { /** @deprecated This feature is now stable, use tgpu.comptime. */ comptime, } from './core/function/comptime.ts'; -export { computeFn } from './core/function/tgpuComputeFn.ts'; +export { + /** @deprecated This feature is now stable, use tgpu.computeFn. */ + computeFn, +} from './core/function/tgpuComputeFn.ts'; export { /** @deprecated This feature is now stable, use tgpu.fn. */ fn, } from './core/function/tgpuFn.ts'; -export { fragmentFn } from './core/function/tgpuFragmentFn.ts'; -export { vertexFn } from './core/function/tgpuVertexFn.ts'; +export { + /** @deprecated This feature is now stable, use tgpu.fragmentFn. */ + fragmentFn, +} from './core/function/tgpuFragmentFn.ts'; +export { + /** @deprecated This feature is now stable, use tgpu.vertexFn. */ + vertexFn, +} from './core/function/tgpuVertexFn.ts'; export { rawCodeSnippet } from './core/rawCodeSnippet/tgpuRawCodeSnippet.ts'; export { namespace } from './core/resolve/namespace.ts'; export { simulate } from './core/simulate/tgpuSimulate.ts'; diff --git a/packages/typegpu/tests/computePipeline.test.ts b/packages/typegpu/tests/computePipeline.test.ts index ce7833c82d..2bf0dcf75a 100644 --- a/packages/typegpu/tests/computePipeline.test.ts +++ b/packages/typegpu/tests/computePipeline.test.ts @@ -12,7 +12,7 @@ import { extensionEnabled } from '../src/std/extensions.ts'; describe('TgpuComputePipeline', () => { it('can be created with a compute entry function', ({ root, device }) => { - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [32] })(() => { + const entryFn = tgpu.computeFn({ workgroupSize: [32] })(() => { // do something }); @@ -36,7 +36,7 @@ describe('TgpuComputePipeline', () => { it('throws an error if bind groups are missing', ({ root }) => { const layout = tgpu.bindGroupLayout({ alpha: { uniform: d.f32 } }); - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })(() => { + const entryFn = tgpu.computeFn({ workgroupSize: [1] })(() => { layout.$.alpha; // Using an entry of the layout }); @@ -55,7 +55,7 @@ describe('TgpuComputePipeline', () => { }); it('is resolvable', ({ root }) => { - const main = tgpu['~unstable'] + const main = tgpu .computeFn({ workgroupSize: [32] })(() => { // do something }); @@ -72,7 +72,7 @@ describe('TgpuComputePipeline', () => { }); it('type checks passed bind groups', ({ root }) => { - const main = tgpu['~unstable'] + const main = tgpu .computeFn({ workgroupSize: [32] })(() => { // do something }); @@ -97,7 +97,7 @@ describe('TgpuComputePipeline', () => { describe('Performance Callbacks', () => { it('should add performance callback with automatic query set', ({ root }) => { - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const entryFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); @@ -118,7 +118,7 @@ describe('TgpuComputePipeline', () => { }); it('should create automatic query set when adding performance callback', ({ root, device }) => { - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const entryFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); @@ -139,7 +139,7 @@ describe('TgpuComputePipeline', () => { }); it('should replace previous performance callback', ({ root }) => { - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const entryFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); @@ -166,7 +166,7 @@ describe('TgpuComputePipeline', () => { //@ts-expect-error device.features = new Set(); - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const entryFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); @@ -187,7 +187,7 @@ describe('TgpuComputePipeline', () => { describe('Timestamp Writes', () => { it('should add timestamp writes with custom query set', ({ root }) => { - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const entryFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); @@ -211,7 +211,7 @@ describe('TgpuComputePipeline', () => { }); it('should add timestamp writes with raw GPU query set', ({ root, device }) => { - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const entryFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); @@ -237,7 +237,7 @@ describe('TgpuComputePipeline', () => { }); it('should handle optional timestamp write indices', ({ root }) => { - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const entryFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); @@ -287,7 +287,7 @@ describe('TgpuComputePipeline', () => { }); it('should setup timestamp writes in compute pass descriptor', ({ root, commandEncoder }) => { - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const entryFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); @@ -325,7 +325,7 @@ describe('TgpuComputePipeline', () => { data: buffer, }); - const entryFn = tgpu['~unstable'] + const entryFn = tgpu .computeFn({ workgroupSize: [1] })(() => { layout.$.data; }) @@ -376,7 +376,7 @@ describe('TgpuComputePipeline', () => { describe('Combined Performance callback and Timestamp Writes', () => { it('should work with both performance callback and custom timestamp writes', ({ root, commandEncoder }) => { - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const entryFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); @@ -419,7 +419,7 @@ describe('TgpuComputePipeline', () => { }); it('should prioritize custom timestamp writes over automatic ones', ({ root, commandEncoder }) => { - const entryFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const entryFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); @@ -465,14 +465,14 @@ describe('TgpuComputePipeline', () => { writable: true, }); - const fn = tgpu['~unstable'].computeFn({ + const fn = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [1], })(({ gid }) => { const a = d.arrayOf(d.f32, 3)(); }); - const pipeline = root['~unstable'].createComputePipeline({ compute: fn }); + const pipeline = root.createComputePipeline({ compute: fn }); pipeline.dispatchWorkgroups(1); @@ -501,7 +501,7 @@ describe('TgpuComputePipeline', () => { writable: true, }); - const fn = tgpu['~unstable'].computeFn({ + const fn = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [1], })(({ gid }) => { @@ -517,7 +517,7 @@ describe('TgpuComputePipeline', () => { } }); - const pipeline = root['~unstable'].createComputePipeline({ compute: fn }); + const pipeline = root.createComputePipeline({ compute: fn }); pipeline.dispatchWorkgroups(1); diff --git a/packages/typegpu/tests/entryFnBuiltinArgs.test.ts b/packages/typegpu/tests/entryFnBuiltinArgs.test.ts index 3700c122f2..de3c76e422 100644 --- a/packages/typegpu/tests/entryFnBuiltinArgs.test.ts +++ b/packages/typegpu/tests/entryFnBuiltinArgs.test.ts @@ -9,7 +9,7 @@ import { attest } from '@ark/attest'; describe('entry functions accepting only the allowed subset of builtins', () => { it('works for vertex functions', () => { - tgpu['~unstable'].vertexFn({ + tgpu.vertexFn({ in: { pos: d.builtin.instanceIndex }, out: { uv: d.vec4f, @@ -17,7 +17,7 @@ describe('entry functions accepting only the allowed subset of builtins', () => }); // @ts-expect-error - tgpu['~unstable'].vertexFn({ + tgpu.vertexFn({ in: { pos: d.builtin.sampleIndex }, out: { uv: d.vec4f, @@ -25,21 +25,21 @@ describe('entry functions accepting only the allowed subset of builtins', () => }); // @ts-expect-error - tgpu['~unstable'].vertexFn({ + tgpu.vertexFn({ in: { pos: d.builtin.position }, out: { uv: d.vec4f, }, }); - tgpu['~unstable'].vertexFn({ + tgpu.vertexFn({ out: { uv: d.vec4f, pos: d.builtin.position, }, }); - tgpu['~unstable'].vertexFn({ + tgpu.vertexFn({ out: { uv: d.vec4f, // @ts-expect-error @@ -49,37 +49,37 @@ describe('entry functions accepting only the allowed subset of builtins', () => }); it('works for fragment functions', () => { - tgpu['~unstable'].fragmentFn({ + tgpu.fragmentFn({ in: { pos: d.builtin.position }, out: d.vec4f, }); - tgpu['~unstable'].fragmentFn({ + tgpu.fragmentFn({ out: { index: d.builtin.sampleMask, }, }); // @ts-expect-error - tgpu['~unstable'].fragmentFn({ + tgpu.fragmentFn({ in: { pos: d.builtin.vertexIndex }, out: d.vec4f, }); - tgpu['~unstable'].fragmentFn({ + tgpu.fragmentFn({ // @ts-expect-error out: { index: d.builtin.sampleIndex }, }); }); it('works for compute functions', () => { - tgpu['~unstable'].computeFn({ + tgpu.computeFn({ in: { pos: d.builtin.localInvocationId }, workgroupSize: [1], }); // @ts-expect-error - tgpu['~unstable'].computeFn({ + tgpu.computeFn({ in: { pos: d.builtin.position }, workgroupSize: [1], }); @@ -90,7 +90,7 @@ describe('entry functions being always assignable to the type with default gener it('works for vertex functions', () => { function test(fn: TgpuVertexFn) {} - const fn = tgpu['~unstable'].vertexFn({ + const fn = tgpu.vertexFn({ in: { pos: d.builtin.instanceIndex }, out: { uv: d.vec4f, @@ -103,7 +103,7 @@ describe('entry functions being always assignable to the type with default gener it('works for fragment functions', () => { function test(fn: TgpuFragmentFn) {} - const fn = tgpu['~unstable'].fragmentFn({ + const fn = tgpu.fragmentFn({ in: { pos: d.builtin.position }, out: d.vec4f, })``; @@ -114,7 +114,7 @@ describe('entry functions being always assignable to the type with default gener it('works for compute functions', () => { function test(fn: TgpuComputeFn) {} - const fn = tgpu['~unstable'].computeFn({ + const fn = tgpu.computeFn({ in: { pos: d.builtin.localInvocationId }, workgroupSize: [1], })``; @@ -125,7 +125,7 @@ describe('entry functions being always assignable to the type with default gener describe('@location and @interpolate type stripping (irrelevant when verifying entry functions)', () => { it('works for vertex functions', () => { - const vertexMain = tgpu['~unstable'].vertexFn({ + const vertexMain = tgpu.vertexFn({ out: { bar: d.location(0, d.vec3f) }, })(() => ({ bar: d.vec3f(), @@ -135,7 +135,7 @@ describe('@location and @interpolate type stripping (irrelevant when verifying e }); it('works for fragment functions', () => { - const fragmentMain = tgpu['~unstable'].fragmentFn({ + const fragmentMain = tgpu.fragmentFn({ in: { bar: d.vec3f }, out: d.vec4f, })(() => d.vec4f()); diff --git a/packages/typegpu/tests/entryFnHeaderGen.test.ts b/packages/typegpu/tests/entryFnHeaderGen.test.ts index ec397cc379..f330f95765 100644 --- a/packages/typegpu/tests/entryFnHeaderGen.test.ts +++ b/packages/typegpu/tests/entryFnHeaderGen.test.ts @@ -4,7 +4,7 @@ import tgpu from '../src/index.ts'; describe('autogenerating wgsl headers for tgpu entry functions with raw string WGSL implementations', () => { it('works for fragment entry function with non-decorated non-struct output', () => { - const mainFragment = tgpu['~unstable'].fragmentFn({ + const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, }) /* wgsl */`{ return vec4f(in.uv[0]); }`; @@ -19,7 +19,7 @@ describe('autogenerating wgsl headers for tgpu entry functions with raw string W }); it('works for fragment entry function with decorated non-struct output', () => { - const mainFragment = tgpu['~unstable'].fragmentFn({ + const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.location(1, d.vec4f), }) /* wgsl */`{ return vec4f(in.uv[0]); }`; @@ -34,7 +34,7 @@ describe('autogenerating wgsl headers for tgpu entry functions with raw string W }); it('works for fragment entry function with struct output', () => { - const mainFragment = tgpu['~unstable'].fragmentFn({ + const mainFragment = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: { primary: d.location(1, d.vec4f), @@ -55,7 +55,7 @@ describe('autogenerating wgsl headers for tgpu entry functions with raw string W }); it('works for compute entry function', () => { - const mainCompute = tgpu['~unstable'].computeFn({ + const mainCompute = tgpu.computeFn({ in: { index: d.builtin.globalInvocationId }, workgroupSize: [1], }) /* wgsl */`{ let x = in.index; }`; @@ -70,7 +70,7 @@ describe('autogenerating wgsl headers for tgpu entry functions with raw string W }); it('works for vertex entry function', () => { - const mainVertex = tgpu['~unstable'].vertexFn({ + const mainVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { outPos: d.builtin.position, uv: d.vec2f }, })(/* wgsl */ `{ diff --git a/packages/typegpu/tests/function.test.ts b/packages/typegpu/tests/function.test.ts index 09a4dd2359..84f8a9a40a 100644 --- a/packages/typegpu/tests/function.test.ts +++ b/packages/typegpu/tests/function.test.ts @@ -101,7 +101,7 @@ describe('tgpu.fn', () => { describe('tgpu.computeFn', () => { it('does not create In struct when the are no arguments', () => { - const foo = tgpu['~unstable'].computeFn({ workgroupSize: [1] })(() => { + const foo = tgpu.computeFn({ workgroupSize: [1] })(() => { const x = 2; }); @@ -110,7 +110,7 @@ describe('tgpu.computeFn', () => { }); it('does not create In struct when there is empty object for arguments', () => { - const foo = tgpu['~unstable'].computeFn({ in: {}, workgroupSize: [1] })( + const foo = tgpu.computeFn({ in: {}, workgroupSize: [1] })( () => { const x = 2; }, @@ -123,7 +123,7 @@ describe('tgpu.computeFn', () => { describe('tgpu.vertexFn', () => { it('does not create In struct when the are no arguments', () => { - const foo = tgpu['~unstable'].vertexFn({ + const foo = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(() => ({ pos: d.vec4f(), @@ -134,7 +134,7 @@ describe('tgpu.vertexFn', () => { }); it('does not create In struct when there is empty object for arguments', () => { - const foo = tgpu['~unstable'].vertexFn({ + const foo = tgpu.vertexFn({ in: {}, out: { pos: d.builtin.position }, })(() => { @@ -150,7 +150,7 @@ describe('tgpu.vertexFn', () => { describe('tgpu.fragmentFn', () => { it('does not create Out struct when the are no output parameters', () => { - const foo = tgpu['~unstable'].fragmentFn({ out: Void })(() => {}); + const foo = tgpu.fragmentFn({ out: Void })(() => {}); expect(tgpu.resolve([foo])).not.toContain('struct foo_Out'); }); }); diff --git a/packages/typegpu/tests/functionTagged.test.ts b/packages/typegpu/tests/functionTagged.test.ts index 20df15b3e5..9ee35ed534 100644 --- a/packages/typegpu/tests/functionTagged.test.ts +++ b/packages/typegpu/tests/functionTagged.test.ts @@ -39,7 +39,7 @@ describe('tagged syntax', () => { describe('vertex', () => { it('parses template literal without arguments', () => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ in: { idx: d.builtin.instanceIndex }, out: { pos: d.builtin.position }, })`{ return in.pos; }`.$name('vertexFn'); @@ -58,7 +58,7 @@ describe('tagged syntax', () => { }); it('parses template literal with arguments of different types', () => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ in: { idx: d.builtin.instanceIndex }, out: { pos: d.builtin.position }, })`{ @@ -85,7 +85,7 @@ describe('tagged syntax', () => { describe('fragment', () => { it('parses template literal without arguments', () => { - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ in: { pos: d.builtin.position }, out: d.vec4f, })`{ return vec4f(); }`; @@ -100,7 +100,7 @@ describe('tagged syntax', () => { }); it('parses template literal with arguments of different types', () => { - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ in: { pos: d.builtin.position }, out: d.vec4f, })`{ @@ -123,7 +123,7 @@ describe('tagged syntax', () => { describe('compute', () => { it('parses template literal without arguments', () => { - const computeFn = tgpu['~unstable'].computeFn({ + const computeFn = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [1], })`{}`; @@ -138,7 +138,7 @@ describe('tagged syntax', () => { }); it('parses template literal with arguments of different types', () => { - const computeFn = tgpu['~unstable'].computeFn({ + const computeFn = tgpu.computeFn({ in: { gid: d.builtin.globalInvocationId }, workgroupSize: [1], })`{ diff --git a/packages/typegpu/tests/indent.test.ts b/packages/typegpu/tests/indent.test.ts index bc58844f4c..b7fc76a33f 100644 --- a/packages/typegpu/tests/indent.test.ts +++ b/packages/typegpu/tests/indent.test.ts @@ -336,7 +336,7 @@ describe('indents', () => { sampler: { sampler: 'filtering', multisampled: true }, }); - const someVertex = tgpu['~unstable'].vertexFn({ + const someVertex = tgpu.vertexFn({ in: { vertexIndex: d.builtin.vertexIndex, position: d.vec4f, diff --git a/packages/typegpu/tests/pipeline-resolution.test.ts b/packages/typegpu/tests/pipeline-resolution.test.ts index f8710ded01..ce21693f93 100644 --- a/packages/typegpu/tests/pipeline-resolution.test.ts +++ b/packages/typegpu/tests/pipeline-resolution.test.ts @@ -8,7 +8,7 @@ describe('resolve', () => { color: d.vec4f, }); - const computeFn = tgpu['~unstable'].computeFn({ + const computeFn = tgpu.computeFn({ workgroupSize: [1, 1, 1], in: { gid: d.builtin.globalInvocationId }, })(() => { @@ -18,14 +18,14 @@ describe('resolve', () => { }); }); - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position, color: d.vec4f }, })(() => { const myBoid = Boid(); return { pos: d.vec4f(myBoid.position, 0, 1), color: myBoid.color }; }); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ in: { color: d.vec4f }, out: d.vec4f, })((input) => { diff --git a/packages/typegpu/tests/rawFn.test.ts b/packages/typegpu/tests/rawFn.test.ts index 2d7881feb8..7bc6b1bba9 100644 --- a/packages/typegpu/tests/rawFn.test.ts +++ b/packages/typegpu/tests/rawFn.test.ts @@ -118,7 +118,7 @@ describe('tgpu.fn with raw string WGSL implementation', () => { }); it('adds output struct definition when resolving vertex functions', () => { - const vertexFunction = tgpu['~unstable'] + const vertexFunction = tgpu .vertexFn({ in: { vertexIndex: d.builtin.vertexIndex }, out: { outPos: d.builtin.position }, @@ -148,7 +148,7 @@ struct vertex_fn_Output { }); it('adds output struct definition when resolving fragment functions', () => { - const fragmentFunction = tgpu['~unstable'] + const fragmentFunction = tgpu .fragmentFn({ in: { position: d.builtin.position }, out: { a: d.vec4f, b: d.builtin.fragDepth }, @@ -172,7 +172,7 @@ struct fragment_Output { }); it('properly handles fragment functions with a single output argument', () => { - const fragmentFunction = tgpu['~unstable'] + const fragmentFunction = tgpu .fragmentFn({ in: { position: d.builtin.position }, out: d.vec4f, @@ -509,7 +509,7 @@ describe('tgpu.fn with raw wgsl and missing types', () => { describe('tgpu.computeFn with raw string WGSL implementation', () => { it('does not replace supposed input arg types in code', () => { - const foo = tgpu['~unstable'].computeFn({ + const foo = tgpu.computeFn({ workgroupSize: [1], in: { gid: d.builtin.globalInvocationId, diff --git a/packages/typegpu/tests/renderPipeline.test.ts b/packages/typegpu/tests/renderPipeline.test.ts index 2c41be4048..c8533299ae 100644 --- a/packages/typegpu/tests/renderPipeline.test.ts +++ b/packages/typegpu/tests/renderPipeline.test.ts @@ -13,20 +13,20 @@ import { $internal } from '../src/shared/symbols.ts'; import { it } from './utils/extendedIt.ts'; describe('root.withVertex(...).withFragment(...)', () => { - const vert = tgpu['~unstable'].vertexFn({ + const vert = tgpu.vertexFn({ out: { a: d.vec3f, b: d.vec2f }, })`{ return Out(); }`; - const vertWithBuiltin = tgpu['~unstable'].vertexFn({ + const vertWithBuiltin = tgpu.vertexFn({ out: { a: d.vec3f, b: d.vec2f, pos: d.builtin.position }, })`{ return Out(); }`; it('allows fragment functions to use a subset of the vertex output', ({ root }) => { - const emptyFragment = tgpu['~unstable'].fragmentFn({ in: {}, out: {} })`{}`; - const emptyFragmentWithBuiltin = tgpu['~unstable'].fragmentFn({ + const emptyFragment = tgpu.fragmentFn({ in: {}, out: {} })`{}`; + const emptyFragmentWithBuiltin = tgpu.fragmentFn({ in: { pos: d.builtin.frontFacing }, out: {}, })`{}`; - const fullFragment = tgpu['~unstable'].fragmentFn({ + const fullFragment = tgpu.fragmentFn({ in: { a: d.vec3f, b: d.vec2f }, out: d.vec4f, })`{ return vec4f(); }`; @@ -70,7 +70,7 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('rejects fragment functions that use non-existent vertex output', ({ root }) => { - const fragment = tgpu['~unstable'].fragmentFn({ + const fragment = tgpu.fragmentFn({ in: { a: d.vec3f, c: d.f32 }, out: {}, })(''); @@ -80,7 +80,7 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('rejects fragment functions that use mismatched vertex output data types', ({ root }) => { - const fragment = tgpu['~unstable'].fragmentFn({ + const fragment = tgpu.fragmentFn({ in: { a: d.vec3f, b: d.f32 }, out: {}, })(''); @@ -92,11 +92,11 @@ describe('root.withVertex(...).withFragment(...)', () => { it('throws an error if bind groups are missing', ({ root }) => { const layout = tgpu.bindGroupLayout({ alpha: { uniform: d.f32 } }); - const vertexFn = tgpu['~unstable'] + const vertexFn = tgpu .vertexFn({ out: { pos: d.builtin.position } })`{ layout.$.alpha; }` .$uses({ layout }); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ out: { out: d.vec4f }, })`{}`; @@ -118,19 +118,19 @@ describe('root.withVertex(...).withFragment(...)', () => { it('allows to omit input in entry function shell', () => { expectTypeOf( - tgpu['~unstable'].vertexFn({ in: {}, out: { pos: d.builtin.position } }), + tgpu.vertexFn({ in: {}, out: { pos: d.builtin.position } }), ).toEqualTypeOf>(); expectTypeOf( - tgpu['~unstable'].vertexFn({ out: { pos: d.builtin.position } }), + tgpu.vertexFn({ out: { pos: d.builtin.position } }), ).toEqualTypeOf>(); expectTypeOf( - tgpu['~unstable'].fragmentFn({ in: {}, out: {} }), + tgpu.fragmentFn({ in: {}, out: {} }), ).toEqualTypeOf>(); expectTypeOf( - tgpu['~unstable'].fragmentFn({ out: {} }), + tgpu.fragmentFn({ out: {} }), ).toEqualTypeOf>(); }); @@ -140,12 +140,12 @@ describe('root.withVertex(...).withFragment(...)', () => { d.vec2f(3, -1), d.vec2f(-1, 3), ]); - const vertexMain = tgpu['~unstable'].vertexFn({ + const vertexMain = tgpu.vertexFn({ in: { vid: d.builtin.vertexIndex }, out: { pos: d.builtin.position }, })(({ vid }) => ({ pos: d.vec4f(vertices.$[vid]!, 0, 1) })); - const fragmentMain = tgpu['~unstable'].fragmentFn({ + const fragmentMain = tgpu.fragmentFn({ out: { color: d.vec4f, depth: d.builtin.fragDepth }, })(() => ({ color: d.vec4f(1, 0, 0, 1), depth: 0.5 })); @@ -180,12 +180,12 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('type checks passed bind groups', ({ root }) => { - const vertexMain = tgpu['~unstable'].vertexFn({ + const vertexMain = tgpu.vertexFn({ out: { bar: d.location(0, d.vec3f) }, })(() => ({ bar: d.vec3f(), })); - const fragmentMain = tgpu['~unstable'].fragmentFn({ + const fragmentMain = tgpu.fragmentFn({ in: { bar: d.vec3f }, out: d.vec4f, })(() => d.vec4f()); @@ -211,10 +211,10 @@ describe('root.withVertex(...).withFragment(...)', () => { describe('resolve', () => { it('allows resolving the entire shader code', ({ root }) => { - const pipeline = root['~unstable'] + const pipeline = root .withVertex(vertWithBuiltin.$name('vertex'), {}) .withFragment( - tgpu['~unstable'].fragmentFn({ + tgpu.fragmentFn({ in: { a: d.builtin.position }, out: d.vec4f, })(() => d.vec4f(1, 2, 3, 4)).$name('fragment'), @@ -242,7 +242,7 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('resolves with correct locations when pairing up a vertex and a fragment function', ({ root }) => { - const vertexMain = tgpu['~unstable'].vertexFn({ + const vertexMain = tgpu.vertexFn({ out: { foo: d.vec3f, bar: d.vec3f, @@ -260,7 +260,7 @@ describe('root.withVertex(...).withFragment(...)', () => { pos: d.vec4f(), })); - const fragmentMain = tgpu['~unstable'].fragmentFn({ + const fragmentMain = tgpu.fragmentFn({ in: { baz3: d.u32, bar: d.vec3f, @@ -270,7 +270,7 @@ describe('root.withVertex(...).withFragment(...)', () => { out: d.vec4f, })(() => d.vec4f()); - const pipeline = root['~unstable'] + const pipeline = root .withVertex(vertexMain, {}) .withFragment(fragmentMain, { format: 'r8unorm' }) .createPipeline(); @@ -303,7 +303,7 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('resolves with correct locations when pairing up a vertex and a fragment function with rawFn implementation', ({ root }) => { - const vertexMain = tgpu['~unstable'].vertexFn({ + const vertexMain = tgpu.vertexFn({ out: { foo: d.vec3f, bar: d.vec3f, @@ -314,7 +314,7 @@ describe('root.withVertex(...).withFragment(...)', () => { }, })`{ return Out(); }`; - const fragmentMain = tgpu['~unstable'].fragmentFn({ + const fragmentMain = tgpu.fragmentFn({ in: { position: d.builtin.position, baz3: d.u32, @@ -325,7 +325,7 @@ describe('root.withVertex(...).withFragment(...)', () => { out: d.vec4f, })`{ return vec4f(); }`; - const pipeline = root['~unstable'] + const pipeline = root .withVertex(vertexMain, {}) .withFragment(fragmentMain, { format: 'r8unorm' }) .createPipeline(); @@ -359,7 +359,7 @@ describe('root.withVertex(...).withFragment(...)', () => { () => {}, ); - const vertexMain = tgpu['~unstable'].vertexFn({ + const vertexMain = tgpu.vertexFn({ out: { foo: d.vec3f, bar: d.location(0, d.vec3f), @@ -369,14 +369,14 @@ describe('root.withVertex(...).withFragment(...)', () => { bar: d.vec3f(), })); - const fragmentMain = tgpu['~unstable'].fragmentFn({ + const fragmentMain = tgpu.fragmentFn({ in: { bar: d.location(1, d.vec3f), }, out: d.vec4f, })(() => d.vec4f()); - const pipeline = root['~unstable'] + const pipeline = root .withVertex(vertexMain, {}) .withFragment(fragmentMain, { format: 'r8unorm' }) .createPipeline(); @@ -392,7 +392,7 @@ describe('root.withVertex(...).withFragment(...)', () => { () => {}, ); - const vertexMain = tgpu['~unstable'].vertexFn({ + const vertexMain = tgpu.vertexFn({ out: { foo: d.vec3f, bar: d.location(0, d.vec3f), @@ -402,14 +402,14 @@ describe('root.withVertex(...).withFragment(...)', () => { bar: d.vec3f(), })); - const fragmentMain = tgpu['~unstable'].fragmentFn({ + const fragmentMain = tgpu.fragmentFn({ in: { bar: d.location(0, d.vec3f), }, out: d.vec4f, })(() => d.vec4f()); - const pipeline = root['~unstable'] + const pipeline = root .withVertex(vertexMain, {}) .withFragment(fragmentMain, { format: 'r8unorm' }) .createPipeline(); @@ -423,11 +423,11 @@ describe('root.withVertex(...).withFragment(...)', () => { describe('Performance Callbacks', () => { it('should add performance callback with automatic query set', ({ root }) => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ out: { color: d.vec4f }, })(''); @@ -452,11 +452,11 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('should create automatic query set when adding performance callback', ({ root, device }) => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ out: { color: d.vec4f }, })(''); @@ -490,11 +490,11 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('should replace previous performance callback', ({ root }) => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ out: { color: d.vec4f }, })(''); @@ -523,11 +523,11 @@ describe('root.withVertex(...).withFragment(...)', () => { //@ts-expect-error device.features = new Set(); - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ out: { color: d.vec4f }, })(''); @@ -548,11 +548,11 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it("should not throw 'A color target was not provided to the shader'", ({ root, device }) => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ in: {}, out: { fragColor: d.vec4f, @@ -578,11 +578,11 @@ describe('root.withVertex(...).withFragment(...)', () => { describe('Timestamp Writes', () => { it('should add timestamp writes with custom query set', ({ root }) => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ out: { color: d.vec4f }, })(''); @@ -610,11 +610,11 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('should add timestamp writes with raw GPU query set', ({ root, device }) => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ out: { color: d.vec4f }, })(''); @@ -642,11 +642,11 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('should handle optional timestamp write indices', ({ root }) => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ out: { color: d.vec4f }, })(''); @@ -702,11 +702,11 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('should setup timestamp writes in render pass descriptor', ({ root, commandEncoder }) => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ out: { color: d.vec4f }, })(''); @@ -745,11 +745,11 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('should handle depth stencil attachments with timestamp writes', ({ root, commandEncoder }) => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ out: { color: d.vec4f }, })(''); @@ -790,13 +790,13 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('should handle stencil reference value correctly', ({ root, commandEncoder }) => { - const vertexFn = tgpu['~unstable'] + const vertexFn = tgpu .vertexFn({ out: { pos: d.builtin.position }, })('') .$name('vertex'); - const fragmentFn = tgpu['~unstable'] + const fragmentFn = tgpu .fragmentFn({ out: { color: d.vec4f }, })('') @@ -837,13 +837,13 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('should onlly allow for drawIndexed with assigned index buffer', ({ root }) => { - const vertexFn = tgpu['~unstable'] + const vertexFn = tgpu .vertexFn({ out: { pos: d.builtin.position }, })('') .$name('vertex'); - const fragmentFn = tgpu['~unstable'] + const fragmentFn = tgpu .fragmentFn({ out: { color: d.vec4f }, })('') @@ -882,13 +882,13 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('works when combining timestamp writes and index buffer', ({ root, device, commandEncoder }) => { - const vertexFn = tgpu['~unstable'] + const vertexFn = tgpu .vertexFn({ out: { pos: d.builtin.position }, })('') .$name('vertex'); - const fragmentFn = tgpu['~unstable'] + const fragmentFn = tgpu .fragmentFn({ out: { color: d.vec4f }, })('') @@ -954,13 +954,13 @@ describe('root.withVertex(...).withFragment(...)', () => { }); it('should handle a combination of timestamp writes, index buffer, and performance callback', ({ root, device, commandEncoder }) => { - const vertexFn = tgpu['~unstable'] + const vertexFn = tgpu .vertexFn({ out: { pos: d.builtin.position }, })('') .$name('vertex'); - const fragmentFn = tgpu['~unstable'] + const fragmentFn = tgpu .fragmentFn({ out: { color: d.vec4f }, })('') @@ -1082,11 +1082,11 @@ describe('root.withVertex(...).withFragment(...)', () => { const readonly8 = root.createReadonly(d.u32); const readonly9 = root.createReadonly(d.u32); - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(''); - const fragmentFn = tgpu['~unstable'].fragmentFn({ out: d.vec4f })(() => { + const fragmentFn = tgpu.fragmentFn({ out: d.vec4f })(() => { let a = d.u32(); a = uniform1.$; a = uniform2.$; @@ -1137,20 +1137,20 @@ describe('root.withVertex(...).withFragment(...)', () => { }); describe('root.createRenderPipeline', () => { - const vertex = tgpu['~unstable'].vertexFn({ + const vertex = tgpu.vertexFn({ out: { a: d.vec3f, b: d.vec2f }, })`{ return Out(); }`; - const vertexWithBuiltin = tgpu['~unstable'].vertexFn({ + const vertexWithBuiltin = tgpu.vertexFn({ out: { a: d.vec3f, b: d.vec2f, pos: d.builtin.position }, })`{ return Out(); }`; it('allows fragment functions to use a subset of the vertex output', ({ root }) => { - const emptyFragment = tgpu['~unstable'].fragmentFn({ in: {}, out: {} })`{}`; - const emptyFragmentWithBuiltin = tgpu['~unstable'].fragmentFn({ + const emptyFragment = tgpu.fragmentFn({ in: {}, out: {} })`{}`; + const emptyFragmentWithBuiltin = tgpu.fragmentFn({ in: { pos: d.builtin.frontFacing }, out: {}, })`{}`; - const fullFragment = tgpu['~unstable'].fragmentFn({ + const fullFragment = tgpu.fragmentFn({ in: { a: d.vec3f, b: d.vec2f }, out: d.vec4f, })`{ return vec4f(); }`; @@ -1803,7 +1803,7 @@ describe('matchUpVaryingLocations', () => { describe('TgpuRenderPipeline', () => { it('any pipeline is assignable to default type', ({ root }) => { - const pipeline = root['~unstable'].createRenderPipeline({ + const pipeline = root.createRenderPipeline({ vertex: common.fullScreenTriangle, fragment: () => { return d.vec4f(1); @@ -1819,9 +1819,9 @@ describe('TgpuRenderPipeline', () => { }); it('a "wider" pipeline is assignable to a "thinner" pipeline', ({ root }) => { - const pipeline = root['~unstable'].createRenderPipeline({ + const pipeline = root.createRenderPipeline({ vertex: common.fullScreenTriangle, - fragment: tgpu['~unstable'].fragmentFn({ out: { a: d.vec4f } })(() => { + fragment: tgpu.fragmentFn({ out: { a: d.vec4f } })(() => { return { a: d.vec4f(1) }; }), targets: { a: { format: 'rgba8unorm' } }, diff --git a/packages/typegpu/tests/resolve.test.ts b/packages/typegpu/tests/resolve.test.ts index b9c02ff138..4475c31d72 100644 --- a/packages/typegpu/tests/resolve.test.ts +++ b/packages/typegpu/tests/resolve.test.ts @@ -75,10 +75,10 @@ describe('tgpu resolve', () => { }; setName(intensity, 'intensity'); - const fragment1 = tgpu['~unstable'] + const fragment1 = tgpu .fragmentFn({ out: d.vec4f })(() => d.vec4f(0, intensity.$, 0, 1)); - const fragment2 = tgpu['~unstable'] + const fragment2 = tgpu .fragmentFn({ out: d.vec4f })(() => d.vec4f(intensity.$, 0, 0, 1)); const resolved = tgpu.resolve([fragment1, fragment2], { names: 'strict' }); diff --git a/packages/typegpu/tests/root.test.ts b/packages/typegpu/tests/root.test.ts index 45d248b5ed..90238a33cf 100644 --- a/packages/typegpu/tests/root.test.ts +++ b/packages/typegpu/tests/root.test.ts @@ -189,7 +189,7 @@ describe('TgpuRoot', () => { const layout = tgpu.bindGroupLayout({ foo: { uniform: d.f32 } }); // A vertex function that is using entries from the layout - const mainVertexUsing = tgpu['~unstable'].vertexFn({ + const mainVertexUsing = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(() => { layout.$.foo; @@ -199,7 +199,7 @@ describe('TgpuRoot', () => { }); // A vertex function that is using none of the layout's entries - const mainVertexNotUsing = tgpu['~unstable'].vertexFn({ + const mainVertexNotUsing = tgpu.vertexFn({ out: { pos: d.builtin.position, }, @@ -207,7 +207,7 @@ describe('TgpuRoot', () => { pos: d.vec4f(), })); - const mainFragment = tgpu['~unstable'].fragmentFn({ out: Void })(() => {}); + const mainFragment = tgpu.fragmentFn({ out: Void })(() => {}); it('ignores bind groups that are not used in the shader', ({ root, commandEncoder }) => { const group = root.createBindGroup(layout, { diff --git a/packages/typegpu/tests/texture.test.ts b/packages/typegpu/tests/texture.test.ts index d2fa74d17d..b1bf9bcc2c 100644 --- a/packages/typegpu/tests/texture.test.ts +++ b/packages/typegpu/tests/texture.test.ts @@ -746,13 +746,13 @@ Overload 3 of 4, '(schema: "(Error) Texture not usable as storage, call $usage(' }); describe('Attachment usage', () => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position, uv: d.vec2f }, })(() => { return { pos: d.vec4f(0, 0, 0, 1), uv: d.vec2f() }; }); - const fragmentFn = tgpu['~unstable'].fragmentFn({ + const fragmentFn = tgpu.fragmentFn({ in: { uv: d.vec2f }, out: d.vec4f, })(({ uv }) => { @@ -760,7 +760,7 @@ Overload 3 of 4, '(schema: "(Error) Texture not usable as storage, call $usage(' }); const createRenderPipeline = (root: ExperimentalTgpuRoot) => - root['~unstable'] + root .withVertex(vertexFn) .withFragment(fragmentFn, { format: 'rgba8unorm' }) .createPipeline(); diff --git a/packages/typegpu/tests/tgpuGenericFn.test.ts b/packages/typegpu/tests/tgpuGenericFn.test.ts index 512f6578d3..ab844b85e0 100644 --- a/packages/typegpu/tests/tgpuGenericFn.test.ts +++ b/packages/typegpu/tests/tgpuGenericFn.test.ts @@ -16,7 +16,7 @@ describe('TgpuGenericFn - shellless callback wrapper', () => { }); it('generates only one definition when both original and wrapped function are used', () => { - const countAccess = tgpu['~unstable'].accessor(d.f32, 2); + const countAccess = tgpu.accessor(d.f32, 2); const getDouble = () => { 'use gpu'; @@ -46,7 +46,7 @@ describe('TgpuGenericFn - shellless callback wrapper', () => { }); it('works when only the wrapped function is used', () => { - const countAccess = tgpu['~unstable'].accessor(d.f32, 0); + const countAccess = tgpu.accessor(d.f32, 0); const getDouble = () => { 'use gpu'; @@ -72,7 +72,7 @@ describe('TgpuGenericFn - shellless callback wrapper', () => { }); it('does not duplicate the same function', () => { - const countAccess = tgpu['~unstable'].accessor(d.f32, 0); + const countAccess = tgpu.accessor(d.f32, 0); const getDouble = () => { 'use gpu'; @@ -135,7 +135,7 @@ describe('TgpuGenericFn - shellless callback wrapper', () => { }); it('supports .with for accessor bindings on generic functions', () => { - const valueAccess = tgpu['~unstable'].accessor(d.f32); + const valueAccess = tgpu.accessor(d.f32); const getValue = () => { 'use gpu'; @@ -161,7 +161,7 @@ describe('TgpuGenericFn - shellless callback wrapper', () => { }); it('generates one function even when .with is called multiple times with the same arguments', () => { - const valueAccess = tgpu['~unstable'].accessor(d.f32); + const valueAccess = tgpu.accessor(d.f32); const getValue = () => { 'use gpu'; @@ -188,7 +188,7 @@ describe('TgpuGenericFn - shellless callback wrapper', () => { }); it('allows for shellless inline usage', () => { - const valueAccess = tgpu['~unstable'].accessor(d.f32); + const valueAccess = tgpu.accessor(d.f32); const getValueGeneric = tgpu.fn(() => { 'use gpu'; @@ -212,7 +212,7 @@ describe('TgpuGenericFn - shellless callback wrapper', () => { }); it('shellfull vs shellless', () => { - const valueAccess = tgpu['~unstable'].accessor(d.f32); + const valueAccess = tgpu.accessor(d.f32); const slot = tgpu.slot(); const getValue = tgpu.fn(() => { @@ -304,7 +304,7 @@ describe('TgpuGenericFn - shellless callback wrapper', () => { console.log(x + y + z + offsetSlot.$); }).with(offsetSlot, 1); - const pipeline = root['~unstable'].createGuardedComputePipeline(f); + const pipeline = root.createGuardedComputePipeline(f); expect(tgpu.resolve([pipeline.pipeline])).toMatchInlineSnapshot(` "@group(0) @binding(0) var sizeUniform: vec3u; diff --git a/packages/typegpu/tests/tgsl/consoleLog.test.ts b/packages/typegpu/tests/tgsl/consoleLog.test.ts index da95f8cece..3f90233d2e 100644 --- a/packages/typegpu/tests/tgsl/consoleLog.test.ts +++ b/packages/typegpu/tests/tgsl/consoleLog.test.ts @@ -40,7 +40,7 @@ describe('wgslGenerator with console.log', () => { console.log(n); }; - const vs = tgpu['~unstable'].vertexFn({ out: { pos: d.builtin.position } })( + const vs = tgpu.vertexFn({ out: { pos: d.builtin.position } })( () => { myLog(5); console.log(6); @@ -65,7 +65,7 @@ describe('wgslGenerator with console.log', () => { }); it('Ignores console.log in a fragment shader resolved without a pipeline', () => { - const fs = tgpu['~unstable'] + const fs = tgpu .fragmentFn({ out: d.vec4f })(() => { console.log(d.u32(321)); return d.vec4f(); @@ -80,17 +80,17 @@ describe('wgslGenerator with console.log', () => { }); it('Parses a single console.log in a render pipeline', ({ root }) => { - const vs = tgpu['~unstable'] + const vs = tgpu .vertexFn({ out: { pos: d.builtin.position } })(() => { return { pos: d.vec4f() }; }); - const fs = tgpu['~unstable'] + const fs = tgpu .fragmentFn({ out: d.vec4f })(() => { console.log(d.u32(321)); return d.vec4f(); }); - const pipeline = root['~unstable'] + const pipeline = root .withVertex(vs) .withFragment(fs, { format: 'rg8unorm' }) .createPipeline(); @@ -155,13 +155,13 @@ describe('wgslGenerator with console.log', () => { console.log(n); }; - const vs = tgpu['~unstable'].vertexFn({ out: { pos: d.builtin.position } })( + const vs = tgpu.vertexFn({ out: { pos: d.builtin.position } })( () => { myLog(6); return { pos: d.vec4f() }; }, ); - const fs = tgpu['~unstable'].fragmentFn({ out: d.vec4f })(() => { + const fs = tgpu.fragmentFn({ out: d.vec4f })(() => { myLog(7); return d.vec4f(); }); @@ -236,14 +236,14 @@ describe('wgslGenerator with console.log', () => { }); it('Parses a single console.log in a compute pipeline', ({ root }) => { - const fn = tgpu['~unstable'].computeFn({ + const fn = tgpu.computeFn({ workgroupSize: [1], in: { gid: d.builtin.globalInvocationId }, })(() => { console.log(d.u32(10)); }); - const pipeline = root['~unstable'].createComputePipeline({ compute: fn }); + const pipeline = root.createComputePipeline({ compute: fn }); expect(tgpu.resolve([pipeline])).toMatchInlineSnapshot(` "@group(0) @binding(0) var indexBuffer: atomic; @@ -295,7 +295,7 @@ describe('wgslGenerator with console.log', () => { }); it('Parses two console.logs in a compute pipeline', ({ root }) => { - const fn = tgpu['~unstable'].computeFn({ + const fn = tgpu.computeFn({ workgroupSize: [1], in: { gid: d.builtin.globalInvocationId }, })(() => { @@ -303,7 +303,7 @@ describe('wgslGenerator with console.log', () => { console.log(d.u32(20)); }); - const pipeline = root['~unstable'].createComputePipeline({ + const pipeline = root.createComputePipeline({ compute: fn, }); @@ -373,7 +373,7 @@ describe('wgslGenerator with console.log', () => { }); it('Parses console.logs with more arguments in a compute pipeline', ({ root }) => { - const fn = tgpu['~unstable'].computeFn({ + const fn = tgpu.computeFn({ workgroupSize: [1], in: { gid: d.builtin.globalInvocationId }, })(() => { @@ -385,7 +385,7 @@ describe('wgslGenerator with console.log', () => { ); }); - const pipeline = root['~unstable'].createComputePipeline({ + const pipeline = root.createComputePipeline({ compute: fn, }); @@ -452,7 +452,7 @@ describe('wgslGenerator with console.log', () => { const ComplexArray = d.arrayOf(SimpleStruct, 3); const ComplexStruct = d.struct({ pos: d.vec3f, data: ComplexArray }); - const fn = tgpu['~unstable'].computeFn({ + const fn = tgpu.computeFn({ workgroupSize: [1], in: { gid: d.builtin.globalInvocationId }, })(() => { @@ -467,7 +467,7 @@ describe('wgslGenerator with console.log', () => { console.log(complexStruct); }); - const pipeline = root['~unstable'].createComputePipeline({ compute: fn }); + const pipeline = root.createComputePipeline({ compute: fn }); expect(tgpu.resolve([pipeline])).toMatchInlineSnapshot(` "struct SimpleStruct { @@ -567,7 +567,7 @@ describe('wgslGenerator with console.log', () => { }); it('Throws when not enough space to serialize console.log', ({ root }) => { - const fn = tgpu['~unstable'].computeFn({ + const fn = tgpu.computeFn({ workgroupSize: [1], in: { gid: d.builtin.globalInvocationId }, })(() => { @@ -592,7 +592,7 @@ describe('wgslGenerator with console.log', () => { ); }); - const pipeline = root['~unstable'].createComputePipeline({ compute: fn }); + const pipeline = root.createComputePipeline({ compute: fn }); expect(() => tgpu.resolve([pipeline])).toThrowErrorMatchingInlineSnapshot(` [Error: Resolution of the following tree failed: @@ -608,16 +608,14 @@ describe('wgslGenerator with console.log', () => { .spyOn(console, 'warn') .mockImplementation(() => {}); - const fn = tgpu['~unstable'].computeFn({ + const fn = tgpu.computeFn({ workgroupSize: [1], in: { gid: d.builtin.globalInvocationId }, })(() => { console.trace(); }); - const pipeline = root['~unstable'] - .withCompute(fn) - .createPipeline(); + const pipeline = root.createComputePipeline({ compute: fn }); expect(tgpu.resolve([pipeline])).toMatchInlineSnapshot(` "struct fn_Input { diff --git a/packages/typegpu/tests/tgsl/ternaryOperator.test.ts b/packages/typegpu/tests/tgsl/ternaryOperator.test.ts index 99f40ad537..56a76fb9a8 100644 --- a/packages/typegpu/tests/tgsl/ternaryOperator.test.ts +++ b/packages/typegpu/tests/tgsl/ternaryOperator.test.ts @@ -28,7 +28,7 @@ describe('ternary operator', () => { it('should work for different comptime known expressions', () => { const condition = true; - const comptime = tgpu['~unstable'].comptime(() => true); + const comptime = tgpu.comptime(() => true); const slot = tgpu.slot(true); const lazy = tgpu.lazy(() => slot.$); diff --git a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts index bbcba1dfe5..a5ed4660bc 100644 --- a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts +++ b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts @@ -617,7 +617,7 @@ describe('wgslGenerator', () => { }); it('creates correct code for "for ... of ..." statements using lazy and comptime iterables', () => { - const comptimeVec = tgpu['~unstable'].comptime(() => d.vec2f(1, 2)); + const comptimeVec = tgpu.comptime(() => d.vec2f(1, 2)); const main = () => { 'use gpu'; diff --git a/packages/typegpu/tests/tgslFn.test.ts b/packages/typegpu/tests/tgslFn.test.ts index 629438c522..5aa8084c41 100644 --- a/packages/typegpu/tests/tgslFn.test.ts +++ b/packages/typegpu/tests/tgslFn.test.ts @@ -124,7 +124,7 @@ describe('TGSL tgpu.fn function', () => { }); it('resolves vertexFn', () => { - const vertexFn = tgpu['~unstable'] + const vertexFn = tgpu .vertexFn({ in: { vi: builtin.vertexIndex, @@ -169,7 +169,7 @@ describe('TGSL tgpu.fn function', () => { }); it('resolves vertexFn with empty in', () => { - const vertexFn = tgpu['~unstable'].vertexFn({ + const vertexFn = tgpu.vertexFn({ out: { pos: d.builtin.position }, })(() => ({ pos: d.vec4f() })); @@ -186,7 +186,7 @@ describe('TGSL tgpu.fn function', () => { it('throws when vertexFn with empty out', () => { expect(() => - tgpu['~unstable'].vertexFn({ + tgpu.vertexFn({ in: { vi: builtin.vertexIndex }, out: {}, }) @@ -196,7 +196,7 @@ describe('TGSL tgpu.fn function', () => { }); it('allows destructuring the input argument in vertexFn', () => { - const vertexFn = tgpu['~unstable'] + const vertexFn = tgpu .vertexFn({ in: { vi: builtin.vertexIndex, @@ -234,7 +234,7 @@ describe('TGSL tgpu.fn function', () => { }); it('allows access to output struct as second argument in vertexFn', () => { - const vertexFn = tgpu['~unstable'] + const vertexFn = tgpu .vertexFn({ in: { vi: builtin.vertexIndex, @@ -280,7 +280,7 @@ describe('TGSL tgpu.fn function', () => { }); it('resolves computeFn', () => { - const computeFn = tgpu['~unstable'] + const computeFn = tgpu .computeFn({ in: { gid: builtin.globalInvocationId }, workgroupSize: [24], @@ -307,7 +307,7 @@ describe('TGSL tgpu.fn function', () => { }); it('allows destructuring the input argument in computeFn', () => { - const computeFn = tgpu['~unstable'] + const computeFn = tgpu .computeFn({ in: { gid: builtin.globalInvocationId }, workgroupSize: [24], @@ -334,22 +334,20 @@ describe('TGSL tgpu.fn function', () => { }); it('rejects invalid arguments for computeFn', () => { - const u = tgpu['~unstable']; - // @ts-expect-error - u.computeFn({ in: { vid: builtin.vertexIndex }, workgroupSize: [24] })( + tgpu.computeFn({ in: { vid: builtin.vertexIndex }, workgroupSize: [24] })( () => {}, ); // @ts-expect-error - u.computeFn({ + tgpu.computeFn({ in: { gid: builtin.globalInvocationId, random: d.f32 }, workgroupSize: [24], })(() => {}); }); it('resolves fragmentFn', () => { - const fragmentFn = tgpu['~unstable'] + const fragmentFn = tgpu .fragmentFn({ in: { pos: builtin.position, @@ -400,7 +398,7 @@ describe('TGSL tgpu.fn function', () => { }); it('allows accessing the output struct as second argument in fragmentFn', () => { - const fragmentFn = tgpu['~unstable'] + const fragmentFn = tgpu .fragmentFn({ in: { pos: builtin.position, @@ -449,7 +447,7 @@ describe('TGSL tgpu.fn function', () => { }); it('allows accessing fragment output even when it is not a struct', () => { - const fragmentFn = tgpu['~unstable'] + const fragmentFn = tgpu .fragmentFn({ in: { pos: builtin.position, @@ -477,7 +475,7 @@ describe('TGSL tgpu.fn function', () => { }); it('allows destructuring the input argument in fragmentFn', () => { - const fragmentFn = tgpu['~unstable'] + const fragmentFn = tgpu .fragmentFn({ in: { pos: builtin.position, @@ -526,7 +524,7 @@ describe('TGSL tgpu.fn function', () => { }); it('resolves fragmentFn with a single output', () => { - const fragmentFn = tgpu['~unstable'] + const fragmentFn = tgpu .fragmentFn({ in: { pos: builtin.position }, out: d.vec4f })((input) => { return input.pos; }); @@ -587,7 +585,7 @@ describe('TGSL tgpu.fn function', () => { }; }); - const fn2 = tgpu['~unstable'] + const fn2 = tgpu .computeFn({ in: { gid: builtin.globalInvocationId }, workgroupSize: [24], diff --git a/packages/typegpu/tests/unplugin/autoname.test.ts b/packages/typegpu/tests/unplugin/autoname.test.ts index 6c48278931..d2be3a8939 100644 --- a/packages/typegpu/tests/unplugin/autoname.test.ts +++ b/packages/typegpu/tests/unplugin/autoname.test.ts @@ -39,13 +39,12 @@ describe('autonaming', () => { const myReadonly = root.createReadonly(d.u32); const myUniform = root.createUniform(d.u32); const myQuerySet = root.createQuerySet('timestamp', 2); - const myPipeline = root['~unstable'].createComputePipeline({ - compute: tgpu['~unstable'].computeFn({ workgroupSize: [1] })(() => {}), + const myPipeline = root.createComputePipeline({ + compute: tgpu.computeFn({ workgroupSize: [1] })(() => {}), + }); + const myGuardedPipeline = root.createGuardedComputePipeline(() => { + 'use gpu'; }); - const myGuardedPipeline = root['~unstable'] - .createGuardedComputePipeline(() => { - 'use gpu'; - }); const myTexture = root['~unstable'].createTexture({ size: [1, 1], format: 'rgba8unorm', @@ -114,13 +113,13 @@ describe('autonaming', () => { it('names TGPU functions', () => { const myFunction = tgpu.fn([])(() => 0); - const myComputeFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const myComputeFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); - const myVertexFn = tgpu['~unstable'].vertexFn({ out: { ret: d.i32 } })( + const myVertexFn = tgpu.vertexFn({ out: { ret: d.i32 } })( () => ({ ret: 0 }), ); - const myFragmentFn = tgpu['~unstable'].fragmentFn({ + const myFragmentFn = tgpu.fragmentFn({ in: { position: d.builtin.position }, out: d.vec4f, })( diff --git a/packages/unplugin-typegpu/test/auto-naming.test.ts b/packages/unplugin-typegpu/test/auto-naming.test.ts index 944ad61baa..e83bf1f824 100644 --- a/packages/unplugin-typegpu/test/auto-naming.test.ts +++ b/packages/unplugin-typegpu/test/auto-naming.test.ts @@ -110,13 +110,13 @@ describe('[BABEL] auto naming', () => { import * as d from 'typegpu/data'; const myFunction = tgpu.fn([])(() => 0); - const myComputeFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const myComputeFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); - const myVertexFn = tgpu['~unstable'].vertexFn({ out: { ret: d.i32 } })( + const myVertexFn = tgpu.vertexFn({ out: { ret: d.i32 } })( () => ({ ret: 0 }), ); - const myFragmentFn = tgpu['~unstable'].fragmentFn({ + const myFragmentFn = tgpu.fragmentFn({ in: { position: d.builtin.position }, out: d.vec4f, })( @@ -136,7 +136,7 @@ describe('[BABEL] auto naming', () => { return {}; } }) && $.f)({})), "myFunction"); - const myComputeFn = (globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu['~unstable'].computeFn({ + const myComputeFn = (globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu.computeFn({ workgroupSize: [1] })(($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = () => {}, { v: 1, @@ -146,7 +146,7 @@ describe('[BABEL] auto naming', () => { return {}; } }) && $.f)({})), "myComputeFn"); - const myVertexFn = (globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu['~unstable'].vertexFn({ + const myVertexFn = (globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu.vertexFn({ out: { ret: d.i32 } @@ -160,7 +160,7 @@ describe('[BABEL] auto naming', () => { return {}; } }) && $.f)({})), "myVertexFn"); - const myFragmentFn = (globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu['~unstable'].fragmentFn({ + const myFragmentFn = (globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu.fragmentFn({ in: { position: d.builtin.position }, @@ -476,12 +476,11 @@ describe('[BABEL] auto naming', () => { const root = await tgpu.init(); - const myGuardedPipeline = root['~unstable'] - .createGuardedComputePipeline(() => { - 'use gpu'; - }); + const myGuardedPipeline = root.createGuardedComputePipeline(() => { + 'use gpu'; + }); - const anotherGuardedPipeline = root['~unstable'] + const anotherGuardedPipeline = root .createGuardedComputePipeline(() => { 'use gpu'; }).dispatchThreads(); @@ -493,7 +492,7 @@ describe('[BABEL] auto naming', () => { .toMatchInlineSnapshot(` "import tgpu from 'typegpu'; const root = await tgpu.init(); - const myGuardedPipeline = (globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(root['~unstable'].createGuardedComputePipeline(($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = () => { + const myGuardedPipeline = (globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(root.createGuardedComputePipeline(($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = () => { 'use gpu'; }, { v: 1, @@ -503,7 +502,7 @@ describe('[BABEL] auto naming', () => { return {}; } }) && $.f)({})), "myGuardedPipeline"); - const anotherGuardedPipeline = (globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(root['~unstable'].createGuardedComputePipeline(($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = () => { + const anotherGuardedPipeline = (globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(root.createGuardedComputePipeline(($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = () => { 'use gpu'; }, { v: 1, From de2317062397ef809eebdd4e273f37cec3e8778b Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Fri, 20 Feb 2026 22:35:41 +0100 Subject: [PATCH 2/2] Review fixes --- .../unplugin-typegpu/test/auto-naming.test.ts | 64 +++++++------------ .../test/tgsl-transpiling.test.ts | 34 +++++----- 2 files changed, 39 insertions(+), 59 deletions(-) diff --git a/packages/unplugin-typegpu/test/auto-naming.test.ts b/packages/unplugin-typegpu/test/auto-naming.test.ts index e83bf1f824..8a7e3e4316 100644 --- a/packages/unplugin-typegpu/test/auto-naming.test.ts +++ b/packages/unplugin-typegpu/test/auto-naming.test.ts @@ -527,6 +527,8 @@ describe('[ROLLUP] auto naming', () => { const vertexLayout = tgpu.vertexLayout(d.arrayOf(d.u32)); let shell = tgpu.fn([]); var fn = tgpu.fn([])(() => {}); + let nothing, accessor = tgpu.accessor(d.u32); + const cst = tgpu.const(d.u32, 1); console.log(bindGroupLayout, vertexLayout); `; @@ -545,36 +547,14 @@ describe('[ROLLUP] auto naming', () => { ast: {"params":[],"body":[0,[]],"externalNames":[]}, externals: () => ({}), }) && $.f)({}))), "fn")); + ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu.accessor(d.u32), "accessor")); + ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu.const(d.u32, 1), "cst")); console.log(bindGroupLayout, vertexLayout); " `); }); - it(`works with tgpu['~unstable'] items`, async () => { - const code = `\ - import tgpu from 'typegpu'; - import * as d from 'typegpu/data'; - - let nothing, accessor = tgpu['~unstable'].accessor(d.u32); - const cst = tgpu.const(d.u32, 1); - - console.log(accessor, shell, fn, cst); - `; - - expect(await rollupTransform(code, { autoNamingEnabled: true })) - .toMatchInlineSnapshot(` - "import tgpu from 'typegpu'; - import * as d from 'typegpu/data'; - - let accessor = ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu['~unstable'].accessor(d.u32), "accessor")); - const cst = ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu.const(d.u32, 1), "cst")); - - console.log(accessor, shell, fn, cst); - " - `); - }); - it('works with structs', async () => { const code = `\ import * as d from 'typegpu/data'; @@ -629,13 +609,13 @@ describe('[ROLLUP] auto naming', () => { import * as d from 'typegpu/data'; const myFunction = tgpu.fn([])(() => 0); - const myComputeFn = tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + const myComputeFn = tgpu.computeFn({ workgroupSize: [1] })( () => {}, ); - const myVertexFn = tgpu['~unstable'].vertexFn({ out: { ret: d.i32 } })( + const myVertexFn = tgpu.vertexFn({ out: { ret: d.i32 } })( () => ({ ret: 0 }), ); - const myFragmentFn = tgpu['~unstable'].fragmentFn({ + const myFragmentFn = tgpu.fragmentFn({ in: { position: d.builtin.position }, out: d.vec4f, })( @@ -654,7 +634,7 @@ describe('[ROLLUP] auto naming', () => { ast: {"params":[],"body":[0,[[10,[5,"0"]]]],"externalNames":[]}, externals: () => ({}), }) && $.f)({}))), "myFunction")); - ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu['~unstable'].computeFn({ workgroupSize: [1] })( + ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu.computeFn({ workgroupSize: [1] })( (($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = (() => {}), { v: 1, name: undefined, @@ -662,7 +642,7 @@ describe('[ROLLUP] auto naming', () => { externals: () => ({}), }) && $.f)({})), ), "myComputeFn")); - ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu['~unstable'].vertexFn({ out: { ret: d.i32 } })( + ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu.vertexFn({ out: { ret: d.i32 } })( (($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = (() => ({ ret: 0 })), { v: 1, name: undefined, @@ -670,7 +650,7 @@ describe('[ROLLUP] auto naming', () => { externals: () => ({}), }) && $.f)({})), ), "myVertexFn")); - ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu['~unstable'].fragmentFn({ + ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(tgpu.fragmentFn({ in: { position: d.builtin.position }, out: d.vec4f, })( @@ -1014,15 +994,15 @@ describe('[ROLLUP] auto naming', () => { const root = await tgpu.init(); - const myGuardedPipeline = root['~unstable'] - .createGuardedComputePipeline(() => { - 'use gpu'; - }); + const myGuardedPipeline = root.createGuardedComputePipeline(() => { + 'use gpu'; + }); - const anotherGuardedPipeline = root['~unstable'] + const anotherGuardedPipeline = root .createGuardedComputePipeline(() => { 'use gpu'; - }).dispatchThreads(); + }) + .dispatchThreads(); console.log(myGuardedPipeline, anotherGuardedPipeline); `; @@ -1033,17 +1013,16 @@ describe('[ROLLUP] auto naming', () => { const root = await tgpu.init(); - const myGuardedPipeline = ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(root['~unstable'] - .createGuardedComputePipeline((($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = (() => { - 'use gpu'; - }), { + const myGuardedPipeline = ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(root.createGuardedComputePipeline((($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = (() => { + 'use gpu'; + }), { v: 1, name: undefined, ast: {"params":[],"body":[0,[]],"externalNames":[]}, externals: () => ({}), }) && $.f)({}))), "myGuardedPipeline")); - const anotherGuardedPipeline = ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(root['~unstable'] + const anotherGuardedPipeline = ((globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(root .createGuardedComputePipeline((($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = (() => { 'use gpu'; }), { @@ -1051,7 +1030,8 @@ describe('[ROLLUP] auto naming', () => { name: undefined, ast: {"params":[],"body":[0,[]],"externalNames":[]}, externals: () => ({}), - }) && $.f)({}))).dispatchThreads(), "anotherGuardedPipeline")); + }) && $.f)({}))) + .dispatchThreads(), "anotherGuardedPipeline")); console.log(myGuardedPipeline, anotherGuardedPipeline); " diff --git a/packages/unplugin-typegpu/test/tgsl-transpiling.test.ts b/packages/unplugin-typegpu/test/tgsl-transpiling.test.ts index 0bf1530c65..73e6f5933e 100644 --- a/packages/unplugin-typegpu/test/tgsl-transpiling.test.ts +++ b/packages/unplugin-typegpu/test/tgsl-transpiling.test.ts @@ -52,25 +52,25 @@ describe('[BABEL] plugin for transpiling tgsl functions to tinyest', () => { it('works for multiple functions, skips wgsl-implemented', () => { const code = `\ - import tgpu from 'typegpu'; + import tgpu from 'typegpu'; - const a = tgpu['~unstable'].computeFn({ workgroupSize: [1] })((input) => { + const a = tgpu.computeFn({ workgroupSize: [1] })((input) => { const x = true; - }); + }); - const b = tgpu.fn([])(() => { + const b = tgpu.fn([])(() => { const y = 2 + 2; - }); + }); - const cx = 2; - const c = tgpu.fn([])(() => cx); + const cx = 2; + const c = tgpu.fn([])(() => cx); - const d = tgpu.fn([])('() {}'); + const d = tgpu.fn([])('() {}'); `; expect(babelTransform(code)).toMatchInlineSnapshot(` "import tgpu from 'typegpu'; - const a = tgpu['~unstable'].computeFn({ + const a = tgpu.computeFn({ workgroupSize: [1] })(($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = input => { const x = true; @@ -126,22 +126,22 @@ describe('[BABEL] plugin for transpiling tgsl functions to tinyest', () => { const code = `\ import tgpu from 'typegpu'; - const fun = tgpu['~unstable'].computeFn({ workgroupSize: [1] })((input) => { + const fun = tgpu.computeFn({ workgroupSize: [1] })((input) => { const x = true; }); - const funcWithAs = tgpu['~unstable'].computeFn({ workgroupSize: [1] })((input) => { + const funcWithAs = tgpu.computeFn({ workgroupSize: [1] })((input) => { const x = true as boolean; }); - const funcWithSatisfies = tgpu['~unstable'].computeFn({ workgroupSize: [1] })((input) => { + const funcWithSatisfies = tgpu.computeFn({ workgroupSize: [1] })((input) => { const x = true satisfies boolean; }); `; expect(babelTransform(code)).toMatchInlineSnapshot(` "import tgpu from 'typegpu'; - const fun = tgpu['~unstable'].computeFn({ + const fun = tgpu.computeFn({ workgroupSize: [1] })(($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = input => { const x = true; @@ -153,7 +153,7 @@ describe('[BABEL] plugin for transpiling tgsl functions to tinyest', () => { return {}; } }) && $.f)({})); - const funcWithAs = tgpu['~unstable'].computeFn({ + const funcWithAs = tgpu.computeFn({ workgroupSize: [1] })(($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = input => { const x = true as boolean; @@ -165,7 +165,7 @@ describe('[BABEL] plugin for transpiling tgsl functions to tinyest', () => { return {}; } }) && $.f)({})); - const funcWithSatisfies = tgpu['~unstable'].computeFn({ + const funcWithSatisfies = tgpu.computeFn({ workgroupSize: [1] })(($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = input => { const x = true satisfies boolean; @@ -272,7 +272,7 @@ describe('[ROLLUP] plugin for transpiling tgsl functions to tinyest', () => { const code = `\ import tgpu from 'typegpu'; - const a = tgpu['~unstable'].computeFn({ workgroupSize: [1] })((input) => { + const a = tgpu.computeFn({ workgroupSize: [1] })((input) => { const x = true; }); @@ -289,7 +289,7 @@ describe('[ROLLUP] plugin for transpiling tgsl functions to tinyest', () => { expect(await rollupTransform(code)).toMatchInlineSnapshot(` "import tgpu from 'typegpu'; - tgpu['~unstable'].computeFn({ workgroupSize: [1] })((($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = ((input) => { + tgpu.computeFn({ workgroupSize: [1] })((($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = ((input) => { }), { v: 1, name: undefined,