From 43e4f427919cd1a574dc17288316209cd7ec66a9 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Wed, 11 Feb 2026 11:26:35 +0100 Subject: [PATCH 01/14] new name registry --- packages/typegpu/src/nameRegistry.ts | 98 +++++++++++++++++++++------ packages/typegpu/src/resolutionCtx.ts | 2 + 2 files changed, 79 insertions(+), 21 deletions(-) diff --git a/packages/typegpu/src/nameRegistry.ts b/packages/typegpu/src/nameRegistry.ts index 05319a7d66..3c6b668900 100644 --- a/packages/typegpu/src/nameRegistry.ts +++ b/packages/typegpu/src/nameRegistry.ts @@ -1,3 +1,5 @@ +import { invariant } from './errors.ts'; + const bannedTokens = new Set([ // keywords 'alias', @@ -385,6 +387,8 @@ export interface NameRegistry { pushFunctionScope(): void; popFunctionScope(): void; + pushBlockScope(): void; + popBlockScope(): void; } function sanitizePrimer(primer: string | undefined) { @@ -429,69 +433,121 @@ export function isValidProp(ident: string): boolean { const prefix = ident.split('_')[0] as string; return !bannedTokens.has(prefix); } +type FunctionScopeLayer = { + type: 'functionScope'; +}; + +type BlockScopeLayer = { + type: 'blockScope'; + usedBlockScopeNames: Set; +}; + +type ScopeLayer = FunctionScopeLayer | BlockScopeLayer; abstract class NameRegistryImpl implements NameRegistry { - abstract getUniqueVariant(base: string): string; + abstract getUniqueVariant(base: string, global: boolean): string; readonly #usedNames: Set; - readonly #usedFunctionScopeNamesStack: Set[]; + readonly #usedAllTimeBlockScopeNames: Set; + readonly #scopeStack: ScopeLayer[]; constructor() { this.#usedNames = new Set([ ...bannedTokens, ...builtins, ]); - this.#usedFunctionScopeNamesStack = []; + this.#usedAllTimeBlockScopeNames = new Set(); + this.#scopeStack = []; } - get usedFunctionScopeNames(): Set | undefined { - return this - .#usedFunctionScopeNamesStack[ - this.#usedFunctionScopeNamesStack.length - 1 - ]; + get #usedBlockScopeNames(): Set | undefined { + return this.#scopeStack.findLast((scope) => scope.type === 'blockScope') + ?.usedBlockScopeNames; } makeUnique(primer: string | undefined, global: boolean): string { const sanitizedPrimer = sanitizePrimer(primer); - const name = this.getUniqueVariant(sanitizedPrimer); + const name = this.getUniqueVariant(sanitizedPrimer, global); if (global) { this.#usedNames.add(name); } else { - this.usedFunctionScopeNames?.add(name); + this.#usedAllTimeBlockScopeNames.add(name); + this.#usedBlockScopeNames?.add(name); } return name; } + #isUsedInBlocksBefore(name: string): boolean { + const functionScopeIndex = this.#scopeStack.findLastIndex((scope) => + scope.type === 'functionScope' + ); + return this.#scopeStack.slice(functionScopeIndex + 1).some((scope) => + (scope as BlockScopeLayer).usedBlockScopeNames.has(name) + ); + } + makeValid(primer: string): string { - if (isValidIdentifier(primer) && !this.#usedNames.has(primer)) { - this.usedFunctionScopeNames?.add(primer); + if ( + isValidIdentifier(primer) && !this.#usedNames.has(primer) && + !this.#isUsedInBlocksBefore(primer) + ) { + this.#usedAllTimeBlockScopeNames.add(primer); + this.#usedBlockScopeNames?.add(primer); return primer; } return this.makeUnique(primer, false); } - isUsed(name: string): boolean { - return this.#usedNames.has(name) || - !!this.usedFunctionScopeNames?.has(name); + isUsed(name: string, global: boolean): boolean { + const varyingCond = global + ? this.#usedAllTimeBlockScopeNames.has(name) + : this.#isUsedInBlocksBefore(name); + return this.#usedNames.has(name) || varyingCond; } pushFunctionScope(): void { - this.#usedFunctionScopeNamesStack.push(new Set()); + this.#scopeStack.push({ type: 'functionScope' }); + this.#scopeStack.push({ + type: 'blockScope', + usedBlockScopeNames: new Set(), + }); } popFunctionScope(): void { - this.#usedFunctionScopeNamesStack.pop(); + const functionScopeIndex = this.#scopeStack.findLastIndex((scope) => + scope.type === 'functionScope' + ); + + if (functionScopeIndex === -1) { + return; + } + + this.#scopeStack.splice(functionScopeIndex); + } + + pushBlockScope(): void { + this.#scopeStack.push({ + type: 'blockScope', + usedBlockScopeNames: new Set(), + }); + } + popBlockScope(): void { + invariant( + this.#scopeStack[this.#scopeStack.length - 1]?.type === 'blockScope', + 'Tried to pop block scope, but it is not present', + ); + this.#scopeStack.pop(); } } export class RandomNameRegistry extends NameRegistryImpl { #lastUniqueId = 0; - getUniqueVariant(base: string): string { + getUniqueVariant(base: string, global: boolean): string { let name = `${base}_${this.#lastUniqueId++}`; - while (this.isUsed(name)) { + while (this.isUsed(name, global)) { name = `${base}_${this.#lastUniqueId++}`; } return name; @@ -499,10 +555,10 @@ export class RandomNameRegistry extends NameRegistryImpl { } export class StrictNameRegistry extends NameRegistryImpl { - getUniqueVariant(base: string): string { + getUniqueVariant(base: string, global: boolean): string { let index = 0; let name = base; - while (this.isUsed(name)) { + while (this.isUsed(name, global)) { index++; name = `${base}_${index}`; } diff --git a/packages/typegpu/src/resolutionCtx.ts b/packages/typegpu/src/resolutionCtx.ts index af8302a3b8..f797d304be 100644 --- a/packages/typegpu/src/resolutionCtx.ts +++ b/packages/typegpu/src/resolutionCtx.ts @@ -420,10 +420,12 @@ export class ResolutionCtxImpl implements ResolutionCtx { } pushBlockScope() { + this.#namespaceInternal.nameRegistry.pushBlockScope(); this._itemStateStack.pushBlockScope(); } popBlockScope() { + this.#namespaceInternal.nameRegistry.popBlockScope(); this._itemStateStack.pop('blockScope'); } From 03aaab5a86a2560ce019616fa2faaa46f5d5edbe Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Wed, 18 Feb 2026 12:03:16 +0100 Subject: [PATCH 02/14] test align --- .../algorithms/mnist-inference/index.ts | 4 +- packages/typegpu/src/tgsl/wgslGenerator.ts | 108 ++++++----- .../tests/examples/individual/3d-fish.test.ts | 22 +-- .../tests/examples/individual/blur.test.ts | 6 +- .../examples/individual/caustics.test.ts | 14 +- .../tests/examples/individual/clouds.test.ts | 14 +- .../individual/fluid-double-buffering.test.ts | 28 +-- .../examples/individual/jelly-slider.test.ts | 16 +- .../examples/individual/jelly-switch.test.ts | 6 +- .../individual/jump-flood-voronoi.test.ts | 14 +- .../examples/individual/perlin-noise.test.ts | 14 +- .../examples/individual/probability.test.ts | 182 +++++++++--------- .../examples/individual/ripple-cube.test.ts | 46 ++--- .../examples/individual/slime-mold-3d.test.ts | 42 ++-- .../examples/individual/slime-mold.test.ts | 28 +-- .../individual/smoky-triangle.test.ts | 14 +- .../individual/tgsl-parsing-test.test.ts | 6 +- .../examples/individual/uniformity.test.ts | 26 +-- .../examples/individual/vaporrave.test.ts | 14 +- .../typegpu/tests/tgsl/wgslGenerator.test.ts | 19 +- 20 files changed, 325 insertions(+), 298 deletions(-) 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..68d105fd72 100644 --- a/apps/typegpu-docs/src/examples/algorithms/mnist-inference/index.ts +++ b/apps/typegpu-docs/src/examples/algorithms/mnist-inference/index.ts @@ -19,7 +19,7 @@ const hasTimestampQuery = root.enabledFeatures.has('timestamp-query'); const hasSubgroups = root.enabledFeatures.has('subgroups'); let useSubgroups = hasSubgroups; -const canvasData = Array.from({ length: (SIZE ** 2) }, () => 0); +const canvasData = Array.from({ length: SIZE ** 2 }, () => 0); // Shaders @@ -313,7 +313,7 @@ function centerImage(data: number[]) { const offsetX = Math.round(SIZE / 2 - x); const offsetY = Math.round(SIZE / 2 - y); - const newData = Array.from({ length: (SIZE * SIZE) }, () => 0); + const newData = Array.from({ length: SIZE * SIZE }, () => 0); for (let i = 0; i < SIZE; i++) { for (let j = 0; j < SIZE; j++) { const index = i * SIZE + j; diff --git a/packages/typegpu/src/tgsl/wgslGenerator.ts b/packages/typegpu/src/tgsl/wgslGenerator.ts index 409ba2d7c3..32acbeebaf 100644 --- a/packages/typegpu/src/tgsl/wgslGenerator.ts +++ b/packages/typegpu/src/tgsl/wgslGenerator.ts @@ -1228,64 +1228,74 @@ ${this.ctx.pre}else ${alternate}`; ); } - // If it's ephemeral, it's a value that cannot change. If it's a reference, we take - // an implicit pointer to it - let loopVarKind = 'let'; - const loopVarName = this.ctx.makeNameValid(loopVar[1]); - - if (!isEphemeralSnippet(elementSnippet)) { - if (elementSnippet.origin === 'constant-tgpu-const-ref') { - loopVarKind = 'const'; - } else if (elementSnippet.origin === 'runtime-tgpu-const-ref') { - loopVarKind = 'let'; - } else { - loopVarKind = 'let'; - if (!wgsl.isPtr(elementType)) { - const ptrType = createPtrFromOrigin( - elementSnippet.origin, - concretize(elementType as wgsl.AnyWgslData) as wgsl.StorableData, - ); - invariant( - ptrType !== undefined, - `Creating pointer type from origin ${elementSnippet.origin}`, - ); - elementType = ptrType; - } + try { + this.ctx.pushBlockScope(); + + // If it's ephemeral, it's a value that cannot change. If it's a reference, we take + // an implicit pointer to it + let loopVarKind = 'let'; + const loopVarName = this.ctx.makeNameValid(loopVar[1]); + + if (!isEphemeralSnippet(elementSnippet)) { + if (elementSnippet.origin === 'constant-tgpu-const-ref') { + loopVarKind = 'const'; + } else if (elementSnippet.origin === 'runtime-tgpu-const-ref') { + loopVarKind = 'let'; + } else { + loopVarKind = 'let'; + if (!wgsl.isPtr(elementType)) { + const ptrType = createPtrFromOrigin( + elementSnippet.origin, + concretize( + elementType as wgsl.AnyWgslData, + ) as wgsl.StorableData, + ); + invariant( + ptrType !== undefined, + `Creating pointer type from origin ${elementSnippet.origin}`, + ); + elementType = ptrType; + } - elementType = implicitFrom(elementType as wgsl.Ptr); + elementType = implicitFrom(elementType as wgsl.Ptr); + } } - } - const loopVarSnippet = snip( - loopVarName, - elementType, - elementSnippet.origin, - ); - this.ctx.defineVariable(loopVarName, loopVarSnippet); + const loopVarSnippet = snip( + loopVarName, + elementType, + elementSnippet.origin, + ); - const forStr = stitch`${this.ctx.pre}for (var ${index} = 0u; ${index} < ${ - tryConvertSnippet(this.ctx, elementCountSnippet, u32, false) - }; ${index}++) {`; + this.ctx.defineVariable(loopVar[1], loopVarSnippet); - this.ctx.indent(); + const forStr = + stitch`${this.ctx.pre}for (var ${index} = 0u; ${index} < ${ + tryConvertSnippet(this.ctx, elementCountSnippet, u32, false) + }; ${index}++) {`; - const loopVarDeclStr = - stitch`${this.ctx.pre}${loopVarKind} ${loopVarName} = ${ - tryConvertSnippet( - this.ctx, - elementSnippet, - elementType, - false, - ) - };`; + this.ctx.indent(); - const bodyStr = `${this.ctx.pre}${ - this.block(blockifySingleStatement(body)) - }`; + const loopVarDeclStr = + stitch`${this.ctx.pre}${loopVarKind} ${loopVarName} = ${ + tryConvertSnippet( + this.ctx, + elementSnippet, + elementType, + false, + ) + };`; - this.ctx.dedent(); + const bodyStr = `${this.ctx.pre}${ + this.block(blockifySingleStatement(body)) + }`; - return stitch`${forStr}\n${loopVarDeclStr}\n${bodyStr}\n${this.ctx.pre}}`; + this.ctx.dedent(); + + return stitch`${forStr}\n${loopVarDeclStr}\n${bodyStr}\n${this.ctx.pre}}`; + } finally { + this.ctx.popBlockScope(); + } } if (statement[0] === NODE.continue) { diff --git a/packages/typegpu/tests/examples/individual/3d-fish.test.ts b/packages/typegpu/tests/examples/individual/3d-fish.test.ts index 4c75b546b6..107a074ec6 100644 --- a/packages/typegpu/tests/examples/individual/3d-fish.test.ts +++ b/packages/typegpu/tests/examples/individual/3d-fish.test.ts @@ -31,10 +31,10 @@ describe('3d fish example', () => { @group(0) @binding(1) var seedUniform: f32; - var seed: vec2f; + var seed_1: vec2f; fn seed2(value: vec2f) { - seed = value; + seed_1 = value; } fn randSeed2(seed: vec2f) { @@ -42,11 +42,11 @@ describe('3d fish example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randFloat01() -> f32 { @@ -160,11 +160,11 @@ describe('3d fish example', () => { if ((cohesionCount > 0i)) { cohesion = (((1f / f32(cohesionCount)) * cohesion) - (*fishData).position); } - for (var i = 0; (i < 3i); i += 1i) { + for (var i_1 = 0; (i_1 < 3i); i_1 += 1i) { var repulsion = vec3f(); - repulsion[i] = 1f; - let axisAquariumSize = (vec3f(10, 4, 10)[i] / 2f); - let axisPosition = (*fishData).position[i]; + repulsion[i_1] = 1f; + let axisAquariumSize = (vec3f(10, 4, 10)[i_1] / 2f); + let axisPosition = (*fishData).position[i_1]; const distance_1 = 0.1; if ((axisPosition > (axisAquariumSize - distance_1))) { let str2 = (axisPosition - (axisAquariumSize - distance_1)); diff --git a/packages/typegpu/tests/examples/individual/blur.test.ts b/packages/typegpu/tests/examples/individual/blur.test.ts index 137c90c309..8732ae8e21 100644 --- a/packages/typegpu/tests/examples/individual/blur.test.ts +++ b/packages/typegpu/tests/examples/individual/blur.test.ts @@ -62,9 +62,9 @@ describe('blur example', () => { } } workgroupBarrier(); - for (var r = 0; (r < 4i); r++) { + for (var r_1 = 0; (r_1 < 4i); r_1++) { for (var c = 0; (c < 4i); c++) { - var writeIndex = (baseIndex + vec2i(c, r)); + var writeIndex = (baseIndex + vec2i(c, r_1)); if ((flip != 0u)) { writeIndex = writeIndex.yx; } @@ -73,7 +73,7 @@ describe('blur example', () => { var acc = vec3f(); for (var f = 0; (f < (*settings2).filterDim); f++) { let i = ((center + f) - filterOffset); - acc = (acc + (tileData[r][i] * (1f / f32((*settings2).filterDim)))); + acc = (acc + (tileData[r_1][i] * (1f / f32((*settings2).filterDim)))); } textureStore(outTexture, writeIndex, vec4f(acc, 1f)); } diff --git a/packages/typegpu/tests/examples/individual/caustics.test.ts b/packages/typegpu/tests/examples/individual/caustics.test.ts index cac8c27b83..33cd236b8e 100644 --- a/packages/typegpu/tests/examples/individual/caustics.test.ts +++ b/packages/typegpu/tests/examples/individual/caustics.test.ts @@ -43,10 +43,10 @@ describe('caustics example', () => { @group(0) @binding(1) var time: f32; - var seed: vec2f; + var seed_1: vec2f; fn seed3(value: vec3f) { - seed = (value.xy + vec2f(value.z)); + seed_1 = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -54,11 +54,11 @@ describe('caustics example', () => { } fn sample_1() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randOnUnitSphere() -> vec3f { diff --git a/packages/typegpu/tests/examples/individual/clouds.test.ts b/packages/typegpu/tests/examples/individual/clouds.test.ts index df70cf0435..e64f32f7de 100644 --- a/packages/typegpu/tests/examples/individual/clouds.test.ts +++ b/packages/typegpu/tests/examples/individual/clouds.test.ts @@ -43,10 +43,10 @@ describe('clouds example', () => { @group(1) @binding(0) var params: CloudsParams; - var seed: vec2f; + var seed_1: vec2f; fn seed2(value: vec2f) { - seed = value; + seed_1 = value; } fn randSeed2(seed: vec2f) { @@ -56,11 +56,11 @@ describe('clouds example', () => { @group(0) @binding(0) var resolutionUniform: vec2f; fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/fluid-double-buffering.test.ts b/packages/typegpu/tests/examples/individual/fluid-double-buffering.test.ts index 1bc06bccb2..db9423ce72 100644 --- a/packages/typegpu/tests/examples/individual/fluid-double-buffering.test.ts +++ b/packages/typegpu/tests/examples/individual/fluid-double-buffering.test.ts @@ -102,10 +102,10 @@ describe('fluid double buffering example', () => { @group(0) @binding(1) var time: f32; - var seed: vec2f; + var seed_1: vec2f; fn seed2(value: vec2f) { - seed = value; + seed_1 = value; } fn randSeed2(seed: vec2f) { @@ -160,11 +160,11 @@ describe('fluid double buffering example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randFloat01() -> f32 { @@ -282,10 +282,10 @@ describe('fluid double buffering example', () => { @group(0) @binding(1) var time: f32; - var seed: vec2f; + var seed_1: vec2f; fn seed2(value: vec2f) { - seed = value; + seed_1 = value; } fn randSeed2(seed: vec2f) { @@ -340,11 +340,11 @@ describe('fluid double buffering example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/jelly-slider.test.ts b/packages/typegpu/tests/examples/individual/jelly-slider.test.ts index 544d5b5ae7..8b600d72c2 100644 --- a/packages/typegpu/tests/examples/individual/jelly-slider.test.ts +++ b/packages/typegpu/tests/examples/individual/jelly-slider.test.ts @@ -69,10 +69,10 @@ describe('jelly-slider example', () => { @group(0) @binding(0) var randomUniform: vec2f; - var seed: vec2f; + var seed_1: vec2f; fn seed2(value: vec2f) { - seed = value; + seed_1 = value; } fn randSeed2(seed: vec2f) { @@ -166,11 +166,11 @@ describe('jelly-slider example', () => { @group(0) @binding(6) var bezierTexture: texture_2d; fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randFloat01() -> f32 { @@ -533,7 +533,7 @@ describe('jelly-slider example', () => { return background; } var distanceFromOrigin = max(0f, intersection.tMin); - for (var i = 0; (i < 64i); i++) { + for (var i_1 = 0; (i_1 < 64i); i_1++) { if ((totalSteps >= 64u)) { break; } diff --git a/packages/typegpu/tests/examples/individual/jelly-switch.test.ts b/packages/typegpu/tests/examples/individual/jelly-switch.test.ts index 8b4760c223..62a934e3de 100644 --- a/packages/typegpu/tests/examples/individual/jelly-switch.test.ts +++ b/packages/typegpu/tests/examples/individual/jelly-switch.test.ts @@ -43,10 +43,10 @@ describe('jelly switch example', () => { @group(0) @binding(0) var randomUniform: vec2f; - var seed: vec2f; + var seed_1: vec2f; fn seed2(value: vec2f) { - seed = value; + seed_1 = value; } fn randSeed2(seed: vec2f) { @@ -337,7 +337,7 @@ describe('jelly switch example', () => { return background; } var distanceFromOrigin = max(0f, intersection.tMin); - for (var i = 0; (i < 64i); i++) { + for (var i_1 = 0; (i_1 < 64i); i_1++) { if ((totalSteps >= 64u)) { break; } diff --git a/packages/typegpu/tests/examples/individual/jump-flood-voronoi.test.ts b/packages/typegpu/tests/examples/individual/jump-flood-voronoi.test.ts index fbb318b98c..9987c5e464 100644 --- a/packages/typegpu/tests/examples/individual/jump-flood-voronoi.test.ts +++ b/packages/typegpu/tests/examples/individual/jump-flood-voronoi.test.ts @@ -25,10 +25,10 @@ describe('jump flood (voronoi) example', () => { @group(0) @binding(1) var timeUniform: f32; - var seed: vec2f; + var seed_1: vec2f; fn seed2(value: vec2f) { - seed = value; + seed_1 = value; } fn randSeed2(seed: vec2f) { @@ -36,11 +36,11 @@ describe('jump flood (voronoi) example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/perlin-noise.test.ts b/packages/typegpu/tests/examples/individual/perlin-noise.test.ts index cc90153c0c..daa5f527af 100644 --- a/packages/typegpu/tests/examples/individual/perlin-noise.test.ts +++ b/packages/typegpu/tests/examples/individual/perlin-noise.test.ts @@ -23,10 +23,10 @@ describe('perlin noise example', () => { @group(1) @binding(1) var memory: array; - var seed: vec2f; + var seed_1: vec2f; fn seed3(value: vec3f) { - seed = (value.xy + vec2f(value.z)); + seed_1 = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -34,11 +34,11 @@ describe('perlin noise example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randOnUnitSphere() -> vec3f { diff --git a/packages/typegpu/tests/examples/individual/probability.test.ts b/packages/typegpu/tests/examples/individual/probability.test.ts index 13a01bb952..ddb31bd409 100644 --- a/packages/typegpu/tests/examples/individual/probability.test.ts +++ b/packages/typegpu/tests/examples/individual/probability.test.ts @@ -22,10 +22,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -33,11 +33,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randUniformExclusive() -> f32 { @@ -74,10 +74,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -85,11 +85,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randOnUnitSphere() -> vec3f { @@ -118,10 +118,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -129,11 +129,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randInUnitCircle() -> vec2f { @@ -163,10 +163,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -174,11 +174,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randOnUnitCircle() -> vec2f { @@ -207,10 +207,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -218,11 +218,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randInUnitCube() -> vec3f { @@ -246,10 +246,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -257,11 +257,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randOnUnitCube() -> vec3f { @@ -291,10 +291,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -302,11 +302,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randUniformExclusive() -> f32 { @@ -353,10 +353,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -364,11 +364,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randOnUnitSphere() -> vec3f { @@ -407,10 +407,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -418,11 +418,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randBernoulli(p: f32) -> f32 { @@ -451,10 +451,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -462,11 +462,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randFloat01() -> f32 { @@ -494,10 +494,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -505,11 +505,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randUniformExclusive() -> f32 { @@ -542,10 +542,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -553,11 +553,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randUniformExclusive() -> f32 { @@ -591,10 +591,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -602,11 +602,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randUniformExclusive() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/ripple-cube.test.ts b/packages/typegpu/tests/examples/individual/ripple-cube.test.ts index dbe13f72fd..4cd0057425 100644 --- a/packages/typegpu/tests/examples/individual/ripple-cube.test.ts +++ b/packages/typegpu/tests/examples/individual/ripple-cube.test.ts @@ -23,10 +23,10 @@ describe('ripple-cube example', () => { @group(0) @binding(1) var memoryBuffer: array; - var seed: vec2f; + var seed_1: vec2f; fn seed3(value: vec3f) { - seed = (value.xy + vec2f(value.z)); + seed_1 = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -34,11 +34,11 @@ describe('ripple-cube example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randOnUnitSphere() -> vec3f { @@ -75,10 +75,10 @@ describe('ripple-cube example', () => { @group(0) @binding(1) var memoryBuffer: array; - var seed: vec2f; + var seed_1: vec2f; fn seed3(value: vec3f) { - seed = (value.xy + vec2f(value.z)); + seed_1 = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -86,11 +86,11 @@ describe('ripple-cube example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randOnUnitSphere() -> vec3f { @@ -190,10 +190,10 @@ describe('ripple-cube example', () => { return color; } - var seed: vec2f; + var seed_1: vec2f; fn seed3(value: vec3f) { - seed = (value.xy + vec2f(value.z)); + seed_1 = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -201,11 +201,11 @@ describe('ripple-cube example', () => { } fn sample_1() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randFloat01() -> f32 { @@ -305,10 +305,10 @@ describe('ripple-cube example', () => { @group(0) @binding(1) var timeUniform: f32; - var seed: vec2f; + var seed_1: vec2f; fn seed2(value: vec2f) { - seed = value; + seed_1 = value; } fn randSeed2(seed: vec2f) { diff --git a/packages/typegpu/tests/examples/individual/slime-mold-3d.test.ts b/packages/typegpu/tests/examples/individual/slime-mold-3d.test.ts index 0f1b46e97e..a4b16a680a 100644 --- a/packages/typegpu/tests/examples/individual/slime-mold-3d.test.ts +++ b/packages/typegpu/tests/examples/individual/slime-mold-3d.test.ts @@ -19,10 +19,10 @@ describe('slime mold 3d example', () => { expect(shaderCodes).toMatchInlineSnapshot(` "@group(0) @binding(0) var sizeUniform: vec3u; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -30,11 +30,11 @@ describe('slime mold 3d example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randUniformExclusive() -> f32 { @@ -126,10 +126,10 @@ describe('slime mold 3d example', () => { textureStore(newState, _arg_0.gid.xyz, vec4f(newValue, 0f, 0f, 1f)); } - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -199,11 +199,11 @@ describe('slime mold 3d example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randOnUnitSphere() -> vec3f { @@ -318,10 +318,10 @@ describe('slime mold 3d example', () => { return fullScreenTriangle_Output(vec4f(pos[in.vertexIndex], 0, 1), uv[in.vertexIndex]); } - var seed: vec2f; + var seed_1: vec2f; fn seed2(value: vec2f) { - seed = value; + seed_1 = value; } fn randSeed2(seed: vec2f) { @@ -355,11 +355,11 @@ describe('slime mold 3d example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/slime-mold.test.ts b/packages/typegpu/tests/examples/individual/slime-mold.test.ts index 9cdf638876..2aadb83f25 100644 --- a/packages/typegpu/tests/examples/individual/slime-mold.test.ts +++ b/packages/typegpu/tests/examples/individual/slime-mold.test.ts @@ -19,10 +19,10 @@ describe('slime mold example', () => { expect(shaderCodes).toMatchInlineSnapshot(` "@group(0) @binding(0) var sizeUniform: vec3u; - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -30,11 +30,11 @@ describe('slime mold example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randInUnitCircle() -> vec2f { @@ -109,10 +109,10 @@ describe('slime mold example', () => { textureStore(newState, _arg_0.gid.xy, vec4f(newColor, 1f)); } - var seed: vec2f; + var seed_2: vec2f; fn seed_1(value: f32) { - seed = vec2f(value, 0f); + seed_2 = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -129,11 +129,11 @@ describe('slime mold example', () => { @group(0) @binding(0) var agentsData: array; fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); + seed_2.x = fract((cos(a) * 136.8168f)); + seed_2.y = fract((cos(b) * 534.7645f)); + return seed_2.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/smoky-triangle.test.ts b/packages/typegpu/tests/examples/individual/smoky-triangle.test.ts index c5251d3c79..ed7b70f221 100644 --- a/packages/typegpu/tests/examples/individual/smoky-triangle.test.ts +++ b/packages/typegpu/tests/examples/individual/smoky-triangle.test.ts @@ -21,10 +21,10 @@ describe('smoky triangle', () => { @group(0) @binding(1) var memoryBuffer: array; - var seed: vec2f; + var seed_1: vec2f; fn seed3(value: vec3f) { - seed = (value.xy + vec2f(value.z)); + seed_1 = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -32,11 +32,11 @@ describe('smoky triangle', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randOnUnitSphere() -> vec3f { diff --git a/packages/typegpu/tests/examples/individual/tgsl-parsing-test.test.ts b/packages/typegpu/tests/examples/individual/tgsl-parsing-test.test.ts index 40a3b2632d..5d72e81ea4 100644 --- a/packages/typegpu/tests/examples/individual/tgsl-parsing-test.test.ts +++ b/packages/typegpu/tests/examples/individual/tgsl-parsing-test.test.ts @@ -208,7 +208,7 @@ describe('tgsl parsing test example', () => { return s; } - @group(0) @binding(0) var result: i32; + @group(0) @binding(0) var result_1: i32; @compute @workgroup_size(1) fn computeRunTests() { var s = true; @@ -218,10 +218,10 @@ describe('tgsl parsing test example', () => { s = (s && arrayAndStructConstructorsTest()); s = (s && pointersTest()); if (s) { - result = 1i; + result_1 = 1i; } else { - result = 0i; + result_1 = 0i; } }" `); diff --git a/packages/typegpu/tests/examples/individual/uniformity.test.ts b/packages/typegpu/tests/examples/individual/uniformity.test.ts index 33b84bd3a4..a135dfd7ff 100644 --- a/packages/typegpu/tests/examples/individual/uniformity.test.ts +++ b/packages/typegpu/tests/examples/individual/uniformity.test.ts @@ -40,10 +40,10 @@ describe('uniformity test example', () => { @group(0) @binding(1) var gridSizeUniform: f32; - var seed: vec2f; + var seed_1: vec2f; fn seed2(value: vec2f) { - seed = value; + seed_1 = value; } fn randSeed2(seed: vec2f) { @@ -51,11 +51,11 @@ describe('uniformity test example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randFloat01() -> f32 { @@ -73,14 +73,14 @@ describe('uniformity test example', () => { return vec4f(vec3f(randFloat01()), 1f); } - var seed_1: u32; + var seed_2: u32; fn seed2_1(value: vec2f) { - seed_1 = u32(((value.x * 32768f) + (value.y * 1024f))); + seed_2 = u32(((value.x * 32768f) + (value.y * 1024f))); } - fn randSeed2_1(seed_1: vec2f) { - seed2_1(seed_1); + fn randSeed2_1(seed: vec2f) { + seed2_1(seed); } fn u32To01Float(value: u32) -> f32 { @@ -91,8 +91,8 @@ describe('uniformity test example', () => { } fn sample_1() -> f32 { - seed_1 = ((seed_1 * 1664525u) + 1013904223u); - return u32To01Float(seed_1); + seed_2 = ((seed_2 * 1664525u) + 1013904223u); + return u32To01Float(seed_2); } fn randFloat01_1() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/vaporrave.test.ts b/packages/typegpu/tests/examples/individual/vaporrave.test.ts index c39d076d81..1ddc9d276b 100644 --- a/packages/typegpu/tests/examples/individual/vaporrave.test.ts +++ b/packages/typegpu/tests/examples/individual/vaporrave.test.ts @@ -21,10 +21,10 @@ describe('vaporrave example', () => { @group(0) @binding(1) var memoryBuffer: array; - var seed: vec2f; + var seed_1: vec2f; fn seed3(value: vec3f) { - seed = (value.xy + vec2f(value.z)); + seed_1 = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -32,11 +32,11 @@ describe('vaporrave example', () => { } fn sample() -> f32 { - let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); - seed.x = fract((cos(a) * 136.8168f)); - seed.y = fract((cos(b) * 534.7645f)); - return seed.y; + let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); + seed_1.x = fract((cos(a) * 136.8168f)); + seed_1.y = fract((cos(b) * 534.7645f)); + return seed_1.y; } fn randOnUnitSphere() -> vec3f { diff --git a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts index bbcba1dfe5..0b65bafd66 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'; @@ -797,6 +797,23 @@ describe('wgslGenerator', () => { `); }); + it('throws error when "for ... of ..." loop variable name is not correct in wgsl', () => { + const main = () => { + 'use gpu'; + const arr = [1, 2, 3]; + for (const __foo of arr) { + continue; + } + }; + + expect(() => tgpu.resolve([main])).toThrowErrorMatchingInlineSnapshot(` + [Error: Resolution of the following tree failed: + - + - fn*:main + - fn*:main(): Invalid identifier '__foo'. Choose an identifier without whitespaces or leading underscores.] + `); + }); + it('handles "for ... of ..." internal index variable when "i" is used by user', () => { const f1 = () => { 'use gpu'; From a89d840ec750e0c70c9717c0ba7ff64b7e9d9bfa Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Thu, 19 Feb 2026 12:54:07 +0100 Subject: [PATCH 03/14] we don't need allTimeUsedNames --- packages/typegpu/src/nameRegistry.ts | 23 +-- .../tests/examples/individual/3d-fish.test.ts | 14 +- .../examples/individual/caustics.test.ts | 14 +- .../tests/examples/individual/clouds.test.ts | 14 +- .../individual/fluid-double-buffering.test.ts | 28 +-- .../examples/individual/game-of-life.test.ts | 74 +------ .../examples/individual/jelly-slider.test.ts | 14 +- .../examples/individual/jelly-switch.test.ts | 4 +- .../individual/jump-flood-voronoi.test.ts | 14 +- .../examples/individual/perlin-noise.test.ts | 14 +- .../examples/individual/probability.test.ts | 182 +++++++++--------- .../examples/individual/ripple-cube.test.ts | 46 ++--- .../examples/individual/slime-mold-3d.test.ts | 42 ++-- .../examples/individual/slime-mold.test.ts | 28 +-- .../individual/smoky-triangle.test.ts | 14 +- .../individual/tgsl-parsing-test.test.ts | 6 +- .../examples/individual/uniformity.test.ts | 26 +-- .../examples/individual/vaporrave.test.ts | 14 +- 18 files changed, 246 insertions(+), 325 deletions(-) diff --git a/packages/typegpu/src/nameRegistry.ts b/packages/typegpu/src/nameRegistry.ts index 3c6b668900..db5f121752 100644 --- a/packages/typegpu/src/nameRegistry.ts +++ b/packages/typegpu/src/nameRegistry.ts @@ -445,10 +445,9 @@ type BlockScopeLayer = { type ScopeLayer = FunctionScopeLayer | BlockScopeLayer; abstract class NameRegistryImpl implements NameRegistry { - abstract getUniqueVariant(base: string, global: boolean): string; + abstract getUniqueVariant(base: string): string; readonly #usedNames: Set; - readonly #usedAllTimeBlockScopeNames: Set; readonly #scopeStack: ScopeLayer[]; constructor() { @@ -456,7 +455,6 @@ abstract class NameRegistryImpl implements NameRegistry { ...bannedTokens, ...builtins, ]); - this.#usedAllTimeBlockScopeNames = new Set(); this.#scopeStack = []; } @@ -467,12 +465,11 @@ abstract class NameRegistryImpl implements NameRegistry { makeUnique(primer: string | undefined, global: boolean): string { const sanitizedPrimer = sanitizePrimer(primer); - const name = this.getUniqueVariant(sanitizedPrimer, global); + const name = this.getUniqueVariant(sanitizedPrimer); if (global) { this.#usedNames.add(name); } else { - this.#usedAllTimeBlockScopeNames.add(name); this.#usedBlockScopeNames?.add(name); } @@ -493,18 +490,14 @@ abstract class NameRegistryImpl implements NameRegistry { isValidIdentifier(primer) && !this.#usedNames.has(primer) && !this.#isUsedInBlocksBefore(primer) ) { - this.#usedAllTimeBlockScopeNames.add(primer); this.#usedBlockScopeNames?.add(primer); return primer; } return this.makeUnique(primer, false); } - isUsed(name: string, global: boolean): boolean { - const varyingCond = global - ? this.#usedAllTimeBlockScopeNames.has(name) - : this.#isUsedInBlocksBefore(name); - return this.#usedNames.has(name) || varyingCond; + isUsed(name: string): boolean { + return this.#usedNames.has(name) || this.#isUsedInBlocksBefore(name); } pushFunctionScope(): void { @@ -545,9 +538,9 @@ abstract class NameRegistryImpl implements NameRegistry { export class RandomNameRegistry extends NameRegistryImpl { #lastUniqueId = 0; - getUniqueVariant(base: string, global: boolean): string { + getUniqueVariant(base: string): string { let name = `${base}_${this.#lastUniqueId++}`; - while (this.isUsed(name, global)) { + while (this.isUsed(name)) { name = `${base}_${this.#lastUniqueId++}`; } return name; @@ -555,10 +548,10 @@ export class RandomNameRegistry extends NameRegistryImpl { } export class StrictNameRegistry extends NameRegistryImpl { - getUniqueVariant(base: string, global: boolean): string { + getUniqueVariant(base: string): string { let index = 0; let name = base; - while (this.isUsed(name, global)) { + while (this.isUsed(name)) { index++; name = `${base}_${index}`; } diff --git a/packages/typegpu/tests/examples/individual/3d-fish.test.ts b/packages/typegpu/tests/examples/individual/3d-fish.test.ts index 107a074ec6..0f5f2cb656 100644 --- a/packages/typegpu/tests/examples/individual/3d-fish.test.ts +++ b/packages/typegpu/tests/examples/individual/3d-fish.test.ts @@ -31,10 +31,10 @@ describe('3d fish example', () => { @group(0) @binding(1) var seedUniform: f32; - var seed_1: vec2f; + var seed: vec2f; fn seed2(value: vec2f) { - seed_1 = value; + seed = value; } fn randSeed2(seed: vec2f) { @@ -42,11 +42,11 @@ describe('3d fish example', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/caustics.test.ts b/packages/typegpu/tests/examples/individual/caustics.test.ts index 33cd236b8e..cac8c27b83 100644 --- a/packages/typegpu/tests/examples/individual/caustics.test.ts +++ b/packages/typegpu/tests/examples/individual/caustics.test.ts @@ -43,10 +43,10 @@ describe('caustics example', () => { @group(0) @binding(1) var time: f32; - var seed_1: vec2f; + var seed: vec2f; fn seed3(value: vec3f) { - seed_1 = (value.xy + vec2f(value.z)); + seed = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -54,11 +54,11 @@ describe('caustics example', () => { } fn sample_1() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitSphere() -> vec3f { diff --git a/packages/typegpu/tests/examples/individual/clouds.test.ts b/packages/typegpu/tests/examples/individual/clouds.test.ts index e64f32f7de..df70cf0435 100644 --- a/packages/typegpu/tests/examples/individual/clouds.test.ts +++ b/packages/typegpu/tests/examples/individual/clouds.test.ts @@ -43,10 +43,10 @@ describe('clouds example', () => { @group(1) @binding(0) var params: CloudsParams; - var seed_1: vec2f; + var seed: vec2f; fn seed2(value: vec2f) { - seed_1 = value; + seed = value; } fn randSeed2(seed: vec2f) { @@ -56,11 +56,11 @@ describe('clouds example', () => { @group(0) @binding(0) var resolutionUniform: vec2f; fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/fluid-double-buffering.test.ts b/packages/typegpu/tests/examples/individual/fluid-double-buffering.test.ts index db9423ce72..1bc06bccb2 100644 --- a/packages/typegpu/tests/examples/individual/fluid-double-buffering.test.ts +++ b/packages/typegpu/tests/examples/individual/fluid-double-buffering.test.ts @@ -102,10 +102,10 @@ describe('fluid double buffering example', () => { @group(0) @binding(1) var time: f32; - var seed_1: vec2f; + var seed: vec2f; fn seed2(value: vec2f) { - seed_1 = value; + seed = value; } fn randSeed2(seed: vec2f) { @@ -160,11 +160,11 @@ describe('fluid double buffering example', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { @@ -282,10 +282,10 @@ describe('fluid double buffering example', () => { @group(0) @binding(1) var time: f32; - var seed_1: vec2f; + var seed: vec2f; fn seed2(value: vec2f) { - seed_1 = value; + seed = value; } fn randSeed2(seed: vec2f) { @@ -340,11 +340,11 @@ describe('fluid double buffering example', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/game-of-life.test.ts b/packages/typegpu/tests/examples/individual/game-of-life.test.ts index fd3be0ded4..2703291472 100644 --- a/packages/typegpu/tests/examples/individual/game-of-life.test.ts +++ b/packages/typegpu/tests/examples/individual/game-of-life.test.ts @@ -16,78 +16,6 @@ describe('game of life example', () => { expectedCalls: 2, }, device); - expect(shaderCodes).toMatchInlineSnapshot(` - "@group(0) @binding(0) var sizeUniform: vec3u; - - fn getIndex(x: u32, y: u32) -> u32 { - return (((y % 64u) * 64u) + (x % 64u)); - } - - @group(1) @binding(0) var current: array; - - fn getCell(x: u32, y: u32) -> u32 { - return current[getIndex(x, y)]; - } - - fn countNeighbors(x: u32, y: u32) -> u32 { - return (((((((getCell((x - 1u), (y - 1u)) + getCell(x, (y - 1u))) + getCell((x + 1u), (y - 1u))) + getCell((x - 1u), y)) + getCell((x + 1u), y)) + getCell((x - 1u), (y + 1u))) + getCell(x, (y + 1u))) + getCell((x + 1u), (y + 1u))); - } - - @group(1) @binding(1) var next: array; - - fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { - let n = countNeighbors(x, y); - next[getIndex(x, y)] = u32(select((n == 3u), ((n == 2u) || (n == 3u)), (getCell(x, y) == 1u))); - } - - struct mainCompute_Input { - @builtin(global_invocation_id) id: vec3u, - } - - @compute @workgroup_size(16, 16, 1) fn mainCompute(in: mainCompute_Input) { - if (any(in.id >= sizeUniform)) { - return; - } - wrappedCallback(in.id.x, in.id.y, in.id.z); - } - - struct vertexFn_Output { - @builtin(position) pos: vec4f, - @location(0) @interpolate(flat) cell: u32, - @location(1) uv: vec2f, - } - - struct vertexFn_Input { - @builtin(instance_index) iid: u32, - @location(0) cell: u32, - @location(1) pos: vec2u, - } - - @vertex fn vertexFn(_arg_0: vertexFn_Input) -> vertexFn_Output { - const w = 64u; - const h = 64u; - let col = (_arg_0.iid % w); - let row = u32((f32(_arg_0.iid) / f32(w))); - let gx = (col + _arg_0.pos.x); - let gy = (row + _arg_0.pos.y); - let maxWH = f32(max(w, h)); - let x = (((f32(gx) * 2f) - f32(w)) / maxWH); - let y = (((f32(gy) * 2f) - f32(h)) / maxWH); - return vertexFn_Output(vec4f(x, y, 0f, 1f), _arg_0.cell, vec2f(((x + 1f) * 0.5f), ((y + 1f) * 0.5f))); - } - - struct fragmentFn_Input { - @location(0) @interpolate(flat) cell: u32, - @location(1) uv: vec2f, - } - - @fragment fn fragmentFn(_arg_0: fragmentFn_Input) -> @location(0) vec4f { - if ((_arg_0.cell == 0u)) { - discard;; - } - var u = (_arg_0.uv / 1.5f); - return vec4f(u.x, u.y, (1f - u.x), 0.8f); - }" - `); + expect(shaderCodes).toMatchInlineSnapshot(`""`); }); }); diff --git a/packages/typegpu/tests/examples/individual/jelly-slider.test.ts b/packages/typegpu/tests/examples/individual/jelly-slider.test.ts index 8b600d72c2..4d8f6242eb 100644 --- a/packages/typegpu/tests/examples/individual/jelly-slider.test.ts +++ b/packages/typegpu/tests/examples/individual/jelly-slider.test.ts @@ -69,10 +69,10 @@ describe('jelly-slider example', () => { @group(0) @binding(0) var randomUniform: vec2f; - var seed_1: vec2f; + var seed: vec2f; fn seed2(value: vec2f) { - seed_1 = value; + seed = value; } fn randSeed2(seed: vec2f) { @@ -166,11 +166,11 @@ describe('jelly-slider example', () => { @group(0) @binding(6) var bezierTexture: texture_2d; fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/jelly-switch.test.ts b/packages/typegpu/tests/examples/individual/jelly-switch.test.ts index 62a934e3de..061c3e8411 100644 --- a/packages/typegpu/tests/examples/individual/jelly-switch.test.ts +++ b/packages/typegpu/tests/examples/individual/jelly-switch.test.ts @@ -43,10 +43,10 @@ describe('jelly switch example', () => { @group(0) @binding(0) var randomUniform: vec2f; - var seed_1: vec2f; + var seed: vec2f; fn seed2(value: vec2f) { - seed_1 = value; + seed = value; } fn randSeed2(seed: vec2f) { diff --git a/packages/typegpu/tests/examples/individual/jump-flood-voronoi.test.ts b/packages/typegpu/tests/examples/individual/jump-flood-voronoi.test.ts index 9987c5e464..fbb318b98c 100644 --- a/packages/typegpu/tests/examples/individual/jump-flood-voronoi.test.ts +++ b/packages/typegpu/tests/examples/individual/jump-flood-voronoi.test.ts @@ -25,10 +25,10 @@ describe('jump flood (voronoi) example', () => { @group(0) @binding(1) var timeUniform: f32; - var seed_1: vec2f; + var seed: vec2f; fn seed2(value: vec2f) { - seed_1 = value; + seed = value; } fn randSeed2(seed: vec2f) { @@ -36,11 +36,11 @@ describe('jump flood (voronoi) example', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/perlin-noise.test.ts b/packages/typegpu/tests/examples/individual/perlin-noise.test.ts index daa5f527af..cc90153c0c 100644 --- a/packages/typegpu/tests/examples/individual/perlin-noise.test.ts +++ b/packages/typegpu/tests/examples/individual/perlin-noise.test.ts @@ -23,10 +23,10 @@ describe('perlin noise example', () => { @group(1) @binding(1) var memory: array; - var seed_1: vec2f; + var seed: vec2f; fn seed3(value: vec3f) { - seed_1 = (value.xy + vec2f(value.z)); + seed = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -34,11 +34,11 @@ describe('perlin noise example', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitSphere() -> vec3f { diff --git a/packages/typegpu/tests/examples/individual/probability.test.ts b/packages/typegpu/tests/examples/individual/probability.test.ts index ddb31bd409..13a01bb952 100644 --- a/packages/typegpu/tests/examples/individual/probability.test.ts +++ b/packages/typegpu/tests/examples/individual/probability.test.ts @@ -22,10 +22,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -33,11 +33,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randUniformExclusive() -> f32 { @@ -74,10 +74,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -85,11 +85,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitSphere() -> vec3f { @@ -118,10 +118,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -129,11 +129,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randInUnitCircle() -> vec2f { @@ -163,10 +163,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -174,11 +174,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitCircle() -> vec2f { @@ -207,10 +207,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -218,11 +218,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randInUnitCube() -> vec3f { @@ -246,10 +246,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -257,11 +257,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitCube() -> vec3f { @@ -291,10 +291,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -302,11 +302,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randUniformExclusive() -> f32 { @@ -353,10 +353,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -364,11 +364,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitSphere() -> vec3f { @@ -407,10 +407,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -418,11 +418,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randBernoulli(p: f32) -> f32 { @@ -451,10 +451,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -462,11 +462,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { @@ -494,10 +494,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -505,11 +505,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randUniformExclusive() -> f32 { @@ -542,10 +542,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -553,11 +553,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randUniformExclusive() -> f32 { @@ -591,10 +591,10 @@ describe('probability distribution plot example', () => { @group(0) @binding(0) var seedBuffer: array; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -602,11 +602,11 @@ describe('probability distribution plot example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randUniformExclusive() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/ripple-cube.test.ts b/packages/typegpu/tests/examples/individual/ripple-cube.test.ts index 4cd0057425..dbe13f72fd 100644 --- a/packages/typegpu/tests/examples/individual/ripple-cube.test.ts +++ b/packages/typegpu/tests/examples/individual/ripple-cube.test.ts @@ -23,10 +23,10 @@ describe('ripple-cube example', () => { @group(0) @binding(1) var memoryBuffer: array; - var seed_1: vec2f; + var seed: vec2f; fn seed3(value: vec3f) { - seed_1 = (value.xy + vec2f(value.z)); + seed = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -34,11 +34,11 @@ describe('ripple-cube example', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitSphere() -> vec3f { @@ -75,10 +75,10 @@ describe('ripple-cube example', () => { @group(0) @binding(1) var memoryBuffer: array; - var seed_1: vec2f; + var seed: vec2f; fn seed3(value: vec3f) { - seed_1 = (value.xy + vec2f(value.z)); + seed = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -86,11 +86,11 @@ describe('ripple-cube example', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitSphere() -> vec3f { @@ -190,10 +190,10 @@ describe('ripple-cube example', () => { return color; } - var seed_1: vec2f; + var seed: vec2f; fn seed3(value: vec3f) { - seed_1 = (value.xy + vec2f(value.z)); + seed = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -201,11 +201,11 @@ describe('ripple-cube example', () => { } fn sample_1() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { @@ -305,10 +305,10 @@ describe('ripple-cube example', () => { @group(0) @binding(1) var timeUniform: f32; - var seed_1: vec2f; + var seed: vec2f; fn seed2(value: vec2f) { - seed_1 = value; + seed = value; } fn randSeed2(seed: vec2f) { diff --git a/packages/typegpu/tests/examples/individual/slime-mold-3d.test.ts b/packages/typegpu/tests/examples/individual/slime-mold-3d.test.ts index a4b16a680a..0f1b46e97e 100644 --- a/packages/typegpu/tests/examples/individual/slime-mold-3d.test.ts +++ b/packages/typegpu/tests/examples/individual/slime-mold-3d.test.ts @@ -19,10 +19,10 @@ describe('slime mold 3d example', () => { expect(shaderCodes).toMatchInlineSnapshot(` "@group(0) @binding(0) var sizeUniform: vec3u; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -30,11 +30,11 @@ describe('slime mold 3d example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randUniformExclusive() -> f32 { @@ -126,10 +126,10 @@ describe('slime mold 3d example', () => { textureStore(newState, _arg_0.gid.xyz, vec4f(newValue, 0f, 0f, 1f)); } - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -199,11 +199,11 @@ describe('slime mold 3d example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitSphere() -> vec3f { @@ -318,10 +318,10 @@ describe('slime mold 3d example', () => { return fullScreenTriangle_Output(vec4f(pos[in.vertexIndex], 0, 1), uv[in.vertexIndex]); } - var seed_1: vec2f; + var seed: vec2f; fn seed2(value: vec2f) { - seed_1 = value; + seed = value; } fn randSeed2(seed: vec2f) { @@ -355,11 +355,11 @@ describe('slime mold 3d example', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/slime-mold.test.ts b/packages/typegpu/tests/examples/individual/slime-mold.test.ts index 2aadb83f25..9cdf638876 100644 --- a/packages/typegpu/tests/examples/individual/slime-mold.test.ts +++ b/packages/typegpu/tests/examples/individual/slime-mold.test.ts @@ -19,10 +19,10 @@ describe('slime mold example', () => { expect(shaderCodes).toMatchInlineSnapshot(` "@group(0) @binding(0) var sizeUniform: vec3u; - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -30,11 +30,11 @@ describe('slime mold example', () => { } fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randInUnitCircle() -> vec2f { @@ -109,10 +109,10 @@ describe('slime mold example', () => { textureStore(newState, _arg_0.gid.xy, vec4f(newColor, 1f)); } - var seed_2: vec2f; + var seed: vec2f; fn seed_1(value: f32) { - seed_2 = vec2f(value, 0f); + seed = vec2f(value, 0f); } fn randSeed(seed: f32) { @@ -129,11 +129,11 @@ describe('slime mold example', () => { @group(0) @binding(0) var agentsData: array; fn sample() -> f32 { - let a = dot(seed_2, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_2, vec2f(54.47856521606445, 345.8415222167969)); - seed_2.x = fract((cos(a) * 136.8168f)); - seed_2.y = fract((cos(b) * 534.7645f)); - return seed_2.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/smoky-triangle.test.ts b/packages/typegpu/tests/examples/individual/smoky-triangle.test.ts index ed7b70f221..c5251d3c79 100644 --- a/packages/typegpu/tests/examples/individual/smoky-triangle.test.ts +++ b/packages/typegpu/tests/examples/individual/smoky-triangle.test.ts @@ -21,10 +21,10 @@ describe('smoky triangle', () => { @group(0) @binding(1) var memoryBuffer: array; - var seed_1: vec2f; + var seed: vec2f; fn seed3(value: vec3f) { - seed_1 = (value.xy + vec2f(value.z)); + seed = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -32,11 +32,11 @@ describe('smoky triangle', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitSphere() -> vec3f { diff --git a/packages/typegpu/tests/examples/individual/tgsl-parsing-test.test.ts b/packages/typegpu/tests/examples/individual/tgsl-parsing-test.test.ts index 5d72e81ea4..40a3b2632d 100644 --- a/packages/typegpu/tests/examples/individual/tgsl-parsing-test.test.ts +++ b/packages/typegpu/tests/examples/individual/tgsl-parsing-test.test.ts @@ -208,7 +208,7 @@ describe('tgsl parsing test example', () => { return s; } - @group(0) @binding(0) var result_1: i32; + @group(0) @binding(0) var result: i32; @compute @workgroup_size(1) fn computeRunTests() { var s = true; @@ -218,10 +218,10 @@ describe('tgsl parsing test example', () => { s = (s && arrayAndStructConstructorsTest()); s = (s && pointersTest()); if (s) { - result_1 = 1i; + result = 1i; } else { - result_1 = 0i; + result = 0i; } }" `); diff --git a/packages/typegpu/tests/examples/individual/uniformity.test.ts b/packages/typegpu/tests/examples/individual/uniformity.test.ts index a135dfd7ff..33b84bd3a4 100644 --- a/packages/typegpu/tests/examples/individual/uniformity.test.ts +++ b/packages/typegpu/tests/examples/individual/uniformity.test.ts @@ -40,10 +40,10 @@ describe('uniformity test example', () => { @group(0) @binding(1) var gridSizeUniform: f32; - var seed_1: vec2f; + var seed: vec2f; fn seed2(value: vec2f) { - seed_1 = value; + seed = value; } fn randSeed2(seed: vec2f) { @@ -51,11 +51,11 @@ describe('uniformity test example', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randFloat01() -> f32 { @@ -73,14 +73,14 @@ describe('uniformity test example', () => { return vec4f(vec3f(randFloat01()), 1f); } - var seed_2: u32; + var seed_1: u32; fn seed2_1(value: vec2f) { - seed_2 = u32(((value.x * 32768f) + (value.y * 1024f))); + seed_1 = u32(((value.x * 32768f) + (value.y * 1024f))); } - fn randSeed2_1(seed: vec2f) { - seed2_1(seed); + fn randSeed2_1(seed_1: vec2f) { + seed2_1(seed_1); } fn u32To01Float(value: u32) -> f32 { @@ -91,8 +91,8 @@ describe('uniformity test example', () => { } fn sample_1() -> f32 { - seed_2 = ((seed_2 * 1664525u) + 1013904223u); - return u32To01Float(seed_2); + seed_1 = ((seed_1 * 1664525u) + 1013904223u); + return u32To01Float(seed_1); } fn randFloat01_1() -> f32 { diff --git a/packages/typegpu/tests/examples/individual/vaporrave.test.ts b/packages/typegpu/tests/examples/individual/vaporrave.test.ts index 1ddc9d276b..c39d076d81 100644 --- a/packages/typegpu/tests/examples/individual/vaporrave.test.ts +++ b/packages/typegpu/tests/examples/individual/vaporrave.test.ts @@ -21,10 +21,10 @@ describe('vaporrave example', () => { @group(0) @binding(1) var memoryBuffer: array; - var seed_1: vec2f; + var seed: vec2f; fn seed3(value: vec3f) { - seed_1 = (value.xy + vec2f(value.z)); + seed = (value.xy + vec2f(value.z)); } fn randSeed3(seed: vec3f) { @@ -32,11 +32,11 @@ describe('vaporrave example', () => { } fn sample() -> f32 { - let a = dot(seed_1, vec2f(23.140779495239258, 232.6168975830078)); - let b = dot(seed_1, vec2f(54.47856521606445, 345.8415222167969)); - seed_1.x = fract((cos(a) * 136.8168f)); - seed_1.y = fract((cos(b) * 534.7645f)); - return seed_1.y; + let a = dot(seed, vec2f(23.140779495239258, 232.6168975830078)); + let b = dot(seed, vec2f(54.47856521606445, 345.8415222167969)); + seed.x = fract((cos(a) * 136.8168f)); + seed.y = fract((cos(b) * 534.7645f)); + return seed.y; } fn randOnUnitSphere() -> vec3f { From da9c104b5c5cdae1b6ab0c3791bac874ff865fed Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Thu, 19 Feb 2026 13:03:47 +0100 Subject: [PATCH 04/14] lost game of life --- .../examples/individual/game-of-life.test.ts | 74 ++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/packages/typegpu/tests/examples/individual/game-of-life.test.ts b/packages/typegpu/tests/examples/individual/game-of-life.test.ts index 2703291472..fd3be0ded4 100644 --- a/packages/typegpu/tests/examples/individual/game-of-life.test.ts +++ b/packages/typegpu/tests/examples/individual/game-of-life.test.ts @@ -16,6 +16,78 @@ describe('game of life example', () => { expectedCalls: 2, }, device); - expect(shaderCodes).toMatchInlineSnapshot(`""`); + expect(shaderCodes).toMatchInlineSnapshot(` + "@group(0) @binding(0) var sizeUniform: vec3u; + + fn getIndex(x: u32, y: u32) -> u32 { + return (((y % 64u) * 64u) + (x % 64u)); + } + + @group(1) @binding(0) var current: array; + + fn getCell(x: u32, y: u32) -> u32 { + return current[getIndex(x, y)]; + } + + fn countNeighbors(x: u32, y: u32) -> u32 { + return (((((((getCell((x - 1u), (y - 1u)) + getCell(x, (y - 1u))) + getCell((x + 1u), (y - 1u))) + getCell((x - 1u), y)) + getCell((x + 1u), y)) + getCell((x - 1u), (y + 1u))) + getCell(x, (y + 1u))) + getCell((x + 1u), (y + 1u))); + } + + @group(1) @binding(1) var next: array; + + fn wrappedCallback(x: u32, y: u32, _arg_2: u32) { + let n = countNeighbors(x, y); + next[getIndex(x, y)] = u32(select((n == 3u), ((n == 2u) || (n == 3u)), (getCell(x, y) == 1u))); + } + + struct mainCompute_Input { + @builtin(global_invocation_id) id: vec3u, + } + + @compute @workgroup_size(16, 16, 1) fn mainCompute(in: mainCompute_Input) { + if (any(in.id >= sizeUniform)) { + return; + } + wrappedCallback(in.id.x, in.id.y, in.id.z); + } + + struct vertexFn_Output { + @builtin(position) pos: vec4f, + @location(0) @interpolate(flat) cell: u32, + @location(1) uv: vec2f, + } + + struct vertexFn_Input { + @builtin(instance_index) iid: u32, + @location(0) cell: u32, + @location(1) pos: vec2u, + } + + @vertex fn vertexFn(_arg_0: vertexFn_Input) -> vertexFn_Output { + const w = 64u; + const h = 64u; + let col = (_arg_0.iid % w); + let row = u32((f32(_arg_0.iid) / f32(w))); + let gx = (col + _arg_0.pos.x); + let gy = (row + _arg_0.pos.y); + let maxWH = f32(max(w, h)); + let x = (((f32(gx) * 2f) - f32(w)) / maxWH); + let y = (((f32(gy) * 2f) - f32(h)) / maxWH); + return vertexFn_Output(vec4f(x, y, 0f, 1f), _arg_0.cell, vec2f(((x + 1f) * 0.5f), ((y + 1f) * 0.5f))); + } + + struct fragmentFn_Input { + @location(0) @interpolate(flat) cell: u32, + @location(1) uv: vec2f, + } + + @fragment fn fragmentFn(_arg_0: fragmentFn_Input) -> @location(0) vec4f { + if ((_arg_0.cell == 0u)) { + discard;; + } + var u = (_arg_0.uv / 1.5f); + return vec4f(u.x, u.y, (1f - u.x), 0.8f); + }" + `); }); }); From c90cdeb9a025f6c892c1c08662d07064a05d4ef8 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Thu, 19 Feb 2026 17:19:38 +0100 Subject: [PATCH 05/14] block externals with tests + more elegant for of --- packages/typegpu/src/resolutionCtx.ts | 36 +++++++++- .../typegpu/src/tgsl/generationHelpers.ts | 2 + packages/typegpu/src/tgsl/shaderGenerator.ts | 3 +- packages/typegpu/src/tgsl/wgslGenerator.ts | 28 +++++--- packages/typegpu/src/types.ts | 3 + .../typegpu/tests/tgsl/wgslGenerator.test.ts | 66 +++++++++++++++++++ 6 files changed, 126 insertions(+), 12 deletions(-) diff --git a/packages/typegpu/src/resolutionCtx.ts b/packages/typegpu/src/resolutionCtx.ts index 60a6372e85..9b531128ec 100644 --- a/packages/typegpu/src/resolutionCtx.ts +++ b/packages/typegpu/src/resolutionCtx.ts @@ -163,6 +163,7 @@ class ItemStateStackImpl implements ItemStateStack { this._stack.push({ type: 'blockScope', declarations: new Map(), + externals: new Map(), }); } @@ -232,7 +233,8 @@ class ItemStateStackImpl implements ItemStateStack { } if (layer?.type === 'blockScope') { - const snippet = layer.declarations.get(id); + // the order matters + const snippet = layer.declarations.get(id) ?? layer.externals.get(id); if (snippet !== undefined) { return snippet; } @@ -260,6 +262,30 @@ class ItemStateStackImpl implements ItemStateStack { throw new Error('No block scope found to define a variable in.'); } + + pushBlockExternals(externals: Record) { + for (let i = this._stack.length - 1; i >= 0; --i) { + const layer = this._stack[i]; + if (layer?.type === 'blockScope') { + Object.entries(externals).forEach(([id, snippet]) => { + layer.externals.set(id, snippet); + }); + return; + } + } + throw new Error('No block scope found to push externals in.'); + } + + popBlockExternals() { + for (let i = this._stack.length - 1; i >= 0; --i) { + const layer = this._stack[i]; + if (layer?.type === 'blockScope') { + layer.externals.clear(); + return; + } + } + throw new Error('No block scope found to pop overrides from.'); + } } const INDENT = [ @@ -427,6 +453,14 @@ export class ResolutionCtxImpl implements ResolutionCtx { this._itemStateStack.pop('blockScope'); } + pushBlockExternals(externals: Record) { + this._itemStateStack.pushBlockExternals(externals); + } + + popBlockExternals() { + this._itemStateStack.popBlockExternals(); + } + generateLog(op: string, args: Snippet[]): Snippet { return this.#logGenerator.generateLog(this, op, args); } diff --git a/packages/typegpu/src/tgsl/generationHelpers.ts b/packages/typegpu/src/tgsl/generationHelpers.ts index d655b02f35..135d0a7c9d 100644 --- a/packages/typegpu/src/tgsl/generationHelpers.ts +++ b/packages/typegpu/src/tgsl/generationHelpers.ts @@ -92,6 +92,8 @@ export type GenerationCtx = ResolutionCtx & { generateLog(op: string, args: Snippet[]): Snippet; getById(id: string): Snippet | null; defineVariable(id: string, snippet: Snippet): void; + pushBlockExternals(externals: Record): void; + popBlockExternals(): void; /** * Types that are used in `return` statements are diff --git a/packages/typegpu/src/tgsl/shaderGenerator.ts b/packages/typegpu/src/tgsl/shaderGenerator.ts index 5c467459d2..d80f890606 100644 --- a/packages/typegpu/src/tgsl/shaderGenerator.ts +++ b/packages/typegpu/src/tgsl/shaderGenerator.ts @@ -2,10 +2,11 @@ import type { Block, Expression, Statement } from 'tinyest'; import type { Snippet } from '../data/snippet.ts'; import type { GenerationCtx } from './generationHelpers.ts'; import type { BaseData } from '../data/wgslTypes.ts'; +import type { ExternalMap } from '../../src/core/resolve/externals.ts'; export interface ShaderGenerator { initGenerator(ctx: GenerationCtx): void; - block(body: Block): string; + block(body: Block, externalMap?: ExternalMap): string; identifier(id: string): Snippet; typedExpression(expression: Expression, expectedType: BaseData): Snippet; expression(expression: Expression): Snippet; diff --git a/packages/typegpu/src/tgsl/wgslGenerator.ts b/packages/typegpu/src/tgsl/wgslGenerator.ts index 409ba2d7c3..f4c7f72a9d 100644 --- a/packages/typegpu/src/tgsl/wgslGenerator.ts +++ b/packages/typegpu/src/tgsl/wgslGenerator.ts @@ -36,6 +36,7 @@ import { } from './conversion.ts'; import { ArrayExpression, + coerceToSnippet, concretize, type GenerationCtx, numericLiteralToSnippet, @@ -51,6 +52,7 @@ import type { AnyFn } from '../core/function/fnTypes.ts'; import { arrayLength } from '../std/array.ts'; import { AutoStruct } from '../data/autoStruct.ts'; import { mathToStd } from './math.ts'; +import { ExternalMap } from '../../src/core/resolve/externals.ts'; const { NodeTypeCatalog: NODE } = tinyest; @@ -200,8 +202,19 @@ class WgslGenerator implements ShaderGenerator { public block( [_, statements]: tinyest.Block, + externalMap?: ExternalMap, ): string { this.ctx.pushBlockScope(); + + if (externalMap) { + const externals = Object.fromEntries( + Object.entries(externalMap).map(( + [id, value], + ) => [id, coerceToSnippet(value)]), + ); + this.ctx.pushBlockExternals(externals); + } + try { this.ctx.indent(); const body = statements.map((statement) => this.statement(statement)) @@ -1186,6 +1199,7 @@ ${this.ctx.pre}else ${alternate}`; iterableSnippet, snip(index, u32, 'runtime'), ); + if (!elementSnippet) { throw new WgslTypeError( '`for ... of ...` loops only support array or vector iterables', @@ -1231,7 +1245,6 @@ ${this.ctx.pre}else ${alternate}`; // If it's ephemeral, it's a value that cannot change. If it's a reference, we take // an implicit pointer to it let loopVarKind = 'let'; - const loopVarName = this.ctx.makeNameValid(loopVar[1]); if (!isEphemeralSnippet(elementSnippet)) { if (elementSnippet.origin === 'constant-tgpu-const-ref') { @@ -1256,19 +1269,12 @@ ${this.ctx.pre}else ${alternate}`; } } - const loopVarSnippet = snip( - loopVarName, - elementType, - elementSnippet.origin, - ); - this.ctx.defineVariable(loopVarName, loopVarSnippet); - const forStr = stitch`${this.ctx.pre}for (var ${index} = 0u; ${index} < ${ tryConvertSnippet(this.ctx, elementCountSnippet, u32, false) }; ${index}++) {`; - this.ctx.indent(); + const loopVarName = this.ctx.makeNameValid(loopVar[1]); const loopVarDeclStr = stitch`${this.ctx.pre}${loopVarKind} ${loopVarName} = ${ tryConvertSnippet( @@ -1280,7 +1286,9 @@ ${this.ctx.pre}else ${alternate}`; };`; const bodyStr = `${this.ctx.pre}${ - this.block(blockifySingleStatement(body)) + this.block(blockifySingleStatement(body), { + [loopVar[1]]: snip(loopVarName, elementType, elementSnippet.origin), + }) }`; this.ctx.dedent(); diff --git a/packages/typegpu/src/types.ts b/packages/typegpu/src/types.ts index 6174abde71..35d4b36e94 100644 --- a/packages/typegpu/src/types.ts +++ b/packages/typegpu/src/types.ts @@ -124,6 +124,7 @@ export type SlotBindingLayer = { export type BlockScopeLayer = { type: 'blockScope'; declarations: Map; + externals: Map; }; export type StackLayer = @@ -151,6 +152,8 @@ export interface ItemStateStack { externalMap: Record, ): FunctionScopeLayer; pushBlockScope(): void; + pushBlockExternals(externals: Record): void; + popBlockExternals(): void; pop(type: T): Extract; pop(): StackLayer | undefined; diff --git a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts index bbcba1dfe5..f778fcb810 100644 --- a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts +++ b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts @@ -1602,4 +1602,70 @@ describe('wgslGenerator', () => { }" `); }); + + it('block externals do not override identifiers', () => { + const f = () => { + 'use gpu'; + const y = 100; + const x = y; + return x; + }; + + const parsed = getMetaData(f)?.ast?.body as tinyest.Block; + + provideCtx(ctx, () => { + ctx[$internal].itemStateStack.pushFunctionScope( + 'normal', + [], + {}, + d.u32, + {}, + ); + + const res = wgslGenerator.block( + parsed, + { x: 42 }, + ); + + expect(res).toMatchInlineSnapshot(` + "{ + const y = 100; + const x = y; + return u32(x); + }" + `); + }); + }); + + it('block externals are injected correctly', () => { + const f = () => { + 'use gpu'; + for (const x of []) { + const y = x; + } + }; + + const parsed = getMetaData(f)?.ast?.body as tinyest.Block; + + provideCtx(ctx, () => { + ctx[$internal].itemStateStack.pushFunctionScope( + 'normal', + [], + {}, + d.Void, + {}, + ); + + const res = wgslGenerator.block( + (parsed[1][0] as tinyest.ForOf)[3] as tinyest.Block, + { x: 67 }, + ); + + expect(res).toMatchInlineSnapshot(` + "{ + const y = 67; + }" + `); + }); + }); }); From 70f30709badef22ecc8ffdc903691d1df74b266a Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Fri, 20 Feb 2026 00:15:46 +0100 Subject: [PATCH 06/14] for ... of ... fixes + tests --- packages/typegpu/src/tgsl/wgslGenerator.ts | 90 ++++++------ .../typegpu/tests/tgsl/wgslGenerator.test.ts | 132 +++++++++++++++--- 2 files changed, 152 insertions(+), 70 deletions(-) diff --git a/packages/typegpu/src/tgsl/wgslGenerator.ts b/packages/typegpu/src/tgsl/wgslGenerator.ts index 32acbeebaf..91dc9de10c 100644 --- a/packages/typegpu/src/tgsl/wgslGenerator.ts +++ b/packages/typegpu/src/tgsl/wgslGenerator.ts @@ -1172,64 +1172,56 @@ ${this.ctx.pre}else ${alternate}`; '`for ... of ...` loops only support iterables stored in variables', ); } + try { + this.ctx.pushBlockScope(); - // Our index name will be some element from infinite sequence (i, ii, iii, ...). - // If user defines `i` and `ii` before `for ... of ...` loop, then our index name will be `iii`. - // If user defines `i` inside `for ... of ...` then it will be scoped to a new block, - // so we can safely use `i`. - let index = 'i'; // it will be valid name, no need to call this.ctx.makeNameValid - while (this.ctx.getById(index) !== null) { - index += 'i'; - } + const index = this.ctx.makeNameValid('i'); - const elementSnippet = accessIndex( - iterableSnippet, - snip(index, u32, 'runtime'), - ); - if (!elementSnippet) { - throw new WgslTypeError( - '`for ... of ...` loops only support array or vector iterables', + const elementSnippet = accessIndex( + iterableSnippet, + snip(index, u32, 'runtime'), ); - } + if (!elementSnippet) { + throw new WgslTypeError( + '`for ... of ...` loops only support array or vector iterables', + ); + } - const iterableDataType = iterableSnippet.dataType; - let elementCountSnippet: Snippet; - let elementType = elementSnippet.dataType; + const iterableDataType = iterableSnippet.dataType; + let elementCountSnippet: Snippet; + let elementType = elementSnippet.dataType; - if (elementType === UnknownData) { - throw new WgslTypeError( - stitch`The elements in iterable ${iterableSnippet} are of unknown type`, - ); - } + if (elementType === UnknownData) { + throw new WgslTypeError( + stitch`The elements in iterable ${iterableSnippet} are of unknown type`, + ); + } - if (wgsl.isWgslArray(iterableDataType)) { - elementCountSnippet = iterableDataType.elementCount > 0 - ? snip( - `${iterableDataType.elementCount}`, + if (wgsl.isWgslArray(iterableDataType)) { + elementCountSnippet = iterableDataType.elementCount > 0 + ? snip( + `${iterableDataType.elementCount}`, + u32, + 'constant', + ) + : arrayLength[$gpuCallable].call(this.ctx, [iterableSnippet]); + } else if (wgsl.isVec(iterableDataType)) { + elementCountSnippet = snip( + `${Number(iterableDataType.type.match(/\d/))}`, u32, 'constant', - ) - : arrayLength[$gpuCallable].call(this.ctx, [iterableSnippet]); - } else if (wgsl.isVec(iterableDataType)) { - elementCountSnippet = snip( - `${Number(iterableDataType.type.match(/\d/))}`, - u32, - 'constant', - ); - } else { - throw new WgslTypeError( - '`for ... of ...` loops only support array or vector iterables', - ); - } - - if (loopVar[0] !== NODE.const) { - throw new WgslTypeError( - 'Only `for (const ... of ... )` loops are supported', - ); - } + ); + } else { + throw new WgslTypeError( + '`for ... of ...` loops only support array or vector iterables', + ); + } - try { - this.ctx.pushBlockScope(); + if (loopVar[0] !== NODE.const) { + throw new WgslTypeError( + 'Only `for (const ... of ... )` loops are supported', + ); + } // If it's ephemeral, it's a value that cannot change. If it's a reference, we take // an implicit pointer to it diff --git a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts index 0b65bafd66..d7f2b6f709 100644 --- a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts +++ b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts @@ -450,7 +450,6 @@ describe('wgslGenerator', () => { 'use gpu'; const arr = [1, 2, 3]; for (const foo of arr) { - // biome-ignore lint/complexity/noUselessContinue: it's a part of the test continue; } }; @@ -458,9 +457,7 @@ describe('wgslGenerator', () => { const main2 = () => { 'use gpu'; const arr = [1, 2, 3]; - // biome-ignore lint/style/useConst: it's a part of the test for (let foo of arr) { - // biome-ignore lint/complexity/noUselessContinue: it's a part of the test continue; } }; @@ -483,7 +480,6 @@ describe('wgslGenerator', () => { let res = d.f32(); for (const foo of arr) { res += foo; - const i = res; // this is intentional, scoping `i` to a block separate from `arr` index } }; @@ -495,7 +491,6 @@ describe('wgslGenerator', () => { let foo = arr[i]; { res += foo; - let i = res; } } }" @@ -521,8 +516,8 @@ describe('wgslGenerator', () => { for (var i = 0u; i < 3; i++) { let foo = arr[i]; { - for (var i = 0u; i < 3; i++) { - let boo = arr[i]; + for (var i_1 = 0u; i_1 < 3; i_1++) { + let boo = arr[i_1]; { res += (foo * boo); } @@ -552,8 +547,8 @@ describe('wgslGenerator', () => { for (var i = 0u; i < 3; i++) { let foo = arr[i]; { - for (var i = 0u; i < 3; i++) { - let foo2 = arr[i]; + for (var i_1 = 0u; i_1 < 3; i_1++) { + let foo2 = arr[i_1]; { res += (foo2 * foo2); } @@ -588,7 +583,7 @@ describe('wgslGenerator', () => { `); }); - it('creates correct code for "for ... of ..." statement using runtime size array', ({ root }) => { + it('creates correct code for "for ... of ..." statement using runtime size array', () => { const layout = tgpu.bindGroupLayout({ arr: { storage: d.arrayOf(d.f32) }, }); @@ -623,13 +618,11 @@ describe('wgslGenerator', () => { 'use gpu'; const v1 = lazyV4u.$; for (const foo of v1) { - // biome-ignore lint/complexity/noUselessContinue: it's a part of the test continue; } const v2 = comptimeVec(); for (const foo of v2) { - // biome-ignore lint/complexity/noUselessContinue: it's a part of the test continue; } }; @@ -717,7 +710,6 @@ describe('wgslGenerator', () => { 'use gpu'; const testStruct = TestStruct({ arr: [1, 8, 8, 2] }); for (const foo of testStruct.arr) { - // biome-ignore lint/complexity/noUselessContinue: it's a part of the test continue; } }; @@ -743,7 +735,6 @@ describe('wgslGenerator', () => { const main = () => { 'use gpu'; for (const foo of [1, 2, 3]) { - // biome-ignore lint/complexity/noUselessContinue: it's a part of the test continue; } }; @@ -765,9 +756,8 @@ describe('wgslGenerator', () => { const main = () => { 'use gpu'; const testStruct = TestStruct({ x: 1, y: 2 }); - //@ts-expect-error: let's assume it has an iterator + // @ts-expect-error: let's assume it has an iterator for (const foo of testStruct) { - // biome-ignore lint/complexity/noUselessContinue: it's a part of the test continue; } }; @@ -784,8 +774,8 @@ describe('wgslGenerator', () => { const main = () => { 'use gpu'; const arr = [1, 2, 3]; - // biome-ignore lint/style/useConst: it's a part of the test for (let foo of arr) { + continue; } }; @@ -829,7 +819,7 @@ describe('wgslGenerator', () => { for (var i = 0u; i < 3; i++) { let foo = arr[i]; { - let i = foo; + let i_1 = foo; } } }" @@ -840,7 +830,6 @@ describe('wgslGenerator', () => { const i = 7; const arr = [1, 2, 3]; for (const foo of arr) { - // biome-ignore lint/complexity/noUselessContinue: it's a part of the test continue; } }; @@ -849,8 +838,109 @@ describe('wgslGenerator', () => { "fn f2() { const i = 7; var arr = array(1, 2, 3); - for (var ii = 0u; ii < 3; ii++) { - let foo = arr[ii]; + for (var i_1 = 0u; i_1 < 3; i_1++) { + let foo = arr[i_1]; + { + continue; + } + } + }" + `); + }); + + it('handles "for ... of ..." internal index variable when "i" is buffer used earlier', ({ root }) => { + const i = root.createUniform(d.u32, 7); + + const f = () => { + 'use gpu'; + const arr = [1, 2, 3, i.$]; + for (const foo of arr) { + continue; + } + }; + + expect(tgpu.resolve([f])).toMatchInlineSnapshot(` + "@group(0) @binding(0) var i: u32; + + fn f() { + var arr = array(1u, 2u, 3u, i); + for (var i_1 = 0u; i_1 < 4; i_1++) { + let foo = arr[i_1]; + { + continue; + } + } + }" + `); + }); + + it('handles "for ... of ..." internal index variable when "i" is buffer used later', ({ root }) => { + const i = root.createUniform(d.u32, 7); + const f = () => { + 'use gpu'; + const arr = [1, 2, 3]; + for (const foo of arr) { + const x = foo + i.$; + } + }; + + expect(tgpu.resolve([f])).toMatchInlineSnapshot(` + "@group(0) @binding(0) var i_1: u32; + + fn f() { + var arr = array(1, 2, 3); + for (var i = 0u; i < 3; i++) { + let foo = arr[i]; + { + let x = (foo + i32(i_1)); + } + } + }" + `); + }); + + it('handles "for ... of ..." internal index variable when "i" is buffer returned from accessor', ({ root }) => { + const i = root.createUniform(d.u32, 7); + + const acc = tgpu.accessor(d.u32, () => i.$); + + const f = () => { + 'use gpu'; + const arr = [1, 2, 3]; + for (const foo of arr) { + const x = foo + acc.$; + } + }; + + expect(tgpu.resolve([f])).toMatchInlineSnapshot(` + "@group(0) @binding(0) var i_1: u32; + + fn f() { + var arr = array(1, 2, 3); + for (var i = 0u; i < 3; i++) { + let foo = arr[i]; + { + let x = (foo + i32(i_1)); + } + } + }" + `); + }); + + it('handles "for ... of ..." internal index variable when "i" is loop variable', ({ root }) => { + const f = () => { + 'use gpu'; + const arr = [1, 2, 3]; + for (const i of arr) { + continue; + } + }; + + expect(tgpu.resolve([f])).toMatchInlineSnapshot(` + "fn f() { + var arr = array(1, 2, 3); + for (var i = 0u; i < 3; i++) { + let i_1 = arr[i]; { continue; } From b445d7ee66db3b3a9de4cdab6a320bf664cf741d Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Fri, 20 Feb 2026 00:22:29 +0100 Subject: [PATCH 07/14] cleanup --- packages/typegpu/tests/tgsl/wgslGenerator.test.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts index d7f2b6f709..27ca534e2c 100644 --- a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts +++ b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts @@ -874,7 +874,7 @@ describe('wgslGenerator', () => { `); }); - it('handles "for ... of ..." internal index variable when "i" is buffer used later', ({ root }) => { + it('handles "for ... of ..." internal index variable when "i" is the buffer used later', ({ root }) => { const i = root.createUniform(d.u32, 7); const f = () => { 'use gpu'; @@ -899,7 +899,7 @@ describe('wgslGenerator', () => { `); }); - it('handles "for ... of ..." internal index variable when "i" is buffer returned from accessor', ({ root }) => { + it('handles "for ... of ..." internal index variable when "i" is the buffer returned from accessor', ({ root }) => { const i = root.createUniform(d.u32, 7); const acc = tgpu.accessor(d.u32, () => i.$); @@ -927,22 +927,24 @@ describe('wgslGenerator', () => { `); }); - it('handles "for ... of ..." internal index variable when "i" is loop variable', ({ root }) => { + it('handles "for ... of ..." internal index variable when "i" is the loop variable', () => { const f = () => { 'use gpu'; const arr = [1, 2, 3]; + let res = 0; for (const i of arr) { - continue; + res += i; } }; expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { var arr = array(1, 2, 3); + var res = 0; for (var i = 0u; i < 3; i++) { let i_1 = arr[i]; { - continue; + res += i_1; } } }" From 3067577efc5327e4563c1a6d398a6979a252620f Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Fri, 20 Feb 2026 01:07:30 +0100 Subject: [PATCH 08/14] rolldown tests --- .../typegpu/tests/tgsl/nameClashes.test.ts | 47 +++++++++++++++++++ .../typegpu/tests/tgsl/wgslGenerator.test.ts | 29 ++++++++++++ 2 files changed, 76 insertions(+) diff --git a/packages/typegpu/tests/tgsl/nameClashes.test.ts b/packages/typegpu/tests/tgsl/nameClashes.test.ts index c913427436..f424e61724 100644 --- a/packages/typegpu/tests/tgsl/nameClashes.test.ts +++ b/packages/typegpu/tests/tgsl/nameClashes.test.ts @@ -186,3 +186,50 @@ test('should give new names to functions that collide with builtins', () => { }" `); }); + +// TODO: enable when we transition to `rolldown` +// test('should allow duplicate name after block end', () => { +// const main = () => { +// 'use gpu'; +// for (let i = 0; i < 3; i++) { +// const foo = i + 1; +// } +// const foo = d.u32(7); +// return foo; +// }; + +// expect(tgpu.resolve([main])).toMatchInlineSnapshot(` +// "fn main() -> u32 { +// for (var i = 0; (i < 3i); i++) { +// let foo = (i + 1i); +// } +// const foo = 7u; +// return foo; +// }" +// `); +// }); +// +// test('should give declarations new names when they are shadowed', () => { +// const main = () => { +// 'use gpu'; +// const i = 0; +// { +// const i = 1; +// { +// const i = 2; +// } +// } +// }; + +// expect(tgpu.resolve([main])).toMatchInlineSnapshot(` +// "fn main() { +// const i = 0; +// { +// const i_1 = 1; +// { +// const i_2 = 2; +// } +// } +// }" +// `); +// }); diff --git a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts index 27ca534e2c..19b6aaa6e6 100644 --- a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts +++ b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts @@ -951,6 +951,35 @@ describe('wgslGenerator', () => { `); }); + // TODO: enable when we transition to `rolldown` + // it('handles "for ... of ..." loop variable name when there is shadowning', ({ root }) => { + // const i = root.createUniform(d.u32, 7); + + // const f = () => { + // 'use gpu'; + // const arr = [1, 2, 3, i.$]; + // let res = 0; + // for (const i of arr) { + // res += i; + // } + // }; + + // expect(tgpu.resolve([f])).toMatchInlineSnapshot(` + // "@group(0) @binding(0) var i: u32; + + // fn f() { + // var arr = array(1u, 2u, 3u, i); + // var res = 0; + // for (var i_1 = 0u; i_1 < 4; i_1++) { + // let i_2 = arr[i_1]; + // { + // res += i32(i_2); + // } + // } + // }" + // `); + // }); + it('creates correct resources for lazy values and slots', () => { const testFn = tgpu.fn([], d.vec4u)(() => lazyV4u.$); From 49b57d6cd06d6aeff62a3cde6dbe4372ff392168 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Fri, 20 Feb 2026 10:46:12 +0100 Subject: [PATCH 09/14] more cleanup --- packages/typegpu/src/nameRegistry.ts | 5 +++-- packages/typegpu/tests/tgsl/wgslGenerator.test.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/typegpu/src/nameRegistry.ts b/packages/typegpu/src/nameRegistry.ts index db5f121752..15e3d71e61 100644 --- a/packages/typegpu/src/nameRegistry.ts +++ b/packages/typegpu/src/nameRegistry.ts @@ -459,8 +459,9 @@ abstract class NameRegistryImpl implements NameRegistry { } get #usedBlockScopeNames(): Set | undefined { - return this.#scopeStack.findLast((scope) => scope.type === 'blockScope') - ?.usedBlockScopeNames; + return (this.#scopeStack[this.#scopeStack.length - 1] as + | BlockScopeLayer + | undefined)?.usedBlockScopeNames; } makeUnique(primer: string | undefined, global: boolean): string { diff --git a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts index 19b6aaa6e6..4f70ebf29d 100644 --- a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts +++ b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts @@ -848,7 +848,7 @@ describe('wgslGenerator', () => { `); }); - it('handles "for ... of ..." internal index variable when "i" is buffer used earlier', ({ root }) => { + it('handles "for ... of ..." internal index variable when "i" is the buffer used earlier', ({ root }) => { const i = root.createUniform(d.u32, 7); const f = () => { From 8edf9b29b817fed2fe167d2d9955dbec7690ba83 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Fri, 20 Feb 2026 12:07:45 +0100 Subject: [PATCH 10/14] rename --- packages/typegpu/src/resolutionCtx.ts | 16 ++++++++-------- packages/typegpu/src/tgsl/generationHelpers.ts | 4 ++-- packages/typegpu/src/tgsl/wgslGenerator.ts | 4 ++-- packages/typegpu/src/types.ts | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/typegpu/src/resolutionCtx.ts b/packages/typegpu/src/resolutionCtx.ts index 9b531128ec..6261ddef35 100644 --- a/packages/typegpu/src/resolutionCtx.ts +++ b/packages/typegpu/src/resolutionCtx.ts @@ -263,7 +263,7 @@ class ItemStateStackImpl implements ItemStateStack { throw new Error('No block scope found to define a variable in.'); } - pushBlockExternals(externals: Record) { + setBlockExternals(externals: Record) { for (let i = this._stack.length - 1; i >= 0; --i) { const layer = this._stack[i]; if (layer?.type === 'blockScope') { @@ -273,10 +273,10 @@ class ItemStateStackImpl implements ItemStateStack { return; } } - throw new Error('No block scope found to push externals in.'); + throw new Error('No block scope found to set externals in.'); } - popBlockExternals() { + clearBlockExternals() { for (let i = this._stack.length - 1; i >= 0; --i) { const layer = this._stack[i]; if (layer?.type === 'blockScope') { @@ -284,7 +284,7 @@ class ItemStateStackImpl implements ItemStateStack { return; } } - throw new Error('No block scope found to pop overrides from.'); + throw new Error('No block scope found to clear externals in.'); } } @@ -453,12 +453,12 @@ export class ResolutionCtxImpl implements ResolutionCtx { this._itemStateStack.pop('blockScope'); } - pushBlockExternals(externals: Record) { - this._itemStateStack.pushBlockExternals(externals); + setBlockExternals(externals: Record) { + this._itemStateStack.setBlockExternals(externals); } - popBlockExternals() { - this._itemStateStack.popBlockExternals(); + clearBlockExternals() { + this._itemStateStack.clearBlockExternals(); } generateLog(op: string, args: Snippet[]): Snippet { diff --git a/packages/typegpu/src/tgsl/generationHelpers.ts b/packages/typegpu/src/tgsl/generationHelpers.ts index 135d0a7c9d..94b7a33489 100644 --- a/packages/typegpu/src/tgsl/generationHelpers.ts +++ b/packages/typegpu/src/tgsl/generationHelpers.ts @@ -92,8 +92,8 @@ export type GenerationCtx = ResolutionCtx & { generateLog(op: string, args: Snippet[]): Snippet; getById(id: string): Snippet | null; defineVariable(id: string, snippet: Snippet): void; - pushBlockExternals(externals: Record): void; - popBlockExternals(): void; + setBlockExternals(externals: Record): void; + clearBlockExternals(): void; /** * Types that are used in `return` statements are diff --git a/packages/typegpu/src/tgsl/wgslGenerator.ts b/packages/typegpu/src/tgsl/wgslGenerator.ts index f4c7f72a9d..6c3f034a70 100644 --- a/packages/typegpu/src/tgsl/wgslGenerator.ts +++ b/packages/typegpu/src/tgsl/wgslGenerator.ts @@ -52,7 +52,7 @@ import type { AnyFn } from '../core/function/fnTypes.ts'; import { arrayLength } from '../std/array.ts'; import { AutoStruct } from '../data/autoStruct.ts'; import { mathToStd } from './math.ts'; -import { ExternalMap } from '../../src/core/resolve/externals.ts'; +import type { ExternalMap } from '../../src/core/resolve/externals.ts'; const { NodeTypeCatalog: NODE } = tinyest; @@ -212,7 +212,7 @@ class WgslGenerator implements ShaderGenerator { [id, value], ) => [id, coerceToSnippet(value)]), ); - this.ctx.pushBlockExternals(externals); + this.ctx.setBlockExternals(externals); } try { diff --git a/packages/typegpu/src/types.ts b/packages/typegpu/src/types.ts index 35d4b36e94..082e408a3f 100644 --- a/packages/typegpu/src/types.ts +++ b/packages/typegpu/src/types.ts @@ -152,8 +152,8 @@ export interface ItemStateStack { externalMap: Record, ): FunctionScopeLayer; pushBlockScope(): void; - pushBlockExternals(externals: Record): void; - popBlockExternals(): void; + setBlockExternals(externals: Record): void; + clearBlockExternals(): void; pop(type: T): Extract; pop(): StackLayer | undefined; From 7a2901c4c3d7ab94c95bd3d88739e6b125ec7d7f Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Mon, 23 Feb 2026 11:30:48 +0100 Subject: [PATCH 11/14] regular for header in new block scope --- packages/typegpu/src/tgsl/wgslGenerator.ts | 29 +++++++++++-------- .../tests/examples/individual/3d-fish.test.ts | 8 ++--- .../tests/examples/individual/blur.test.ts | 6 ++-- .../examples/individual/jelly-slider.test.ts | 2 +- .../examples/individual/jelly-switch.test.ts | 2 +- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/packages/typegpu/src/tgsl/wgslGenerator.ts b/packages/typegpu/src/tgsl/wgslGenerator.ts index 91dc9de10c..381511ffd8 100644 --- a/packages/typegpu/src/tgsl/wgslGenerator.ts +++ b/packages/typegpu/src/tgsl/wgslGenerator.ts @@ -1140,18 +1140,23 @@ ${this.ctx.pre}else ${alternate}`; if (statement[0] === NODE.for) { const [_, init, condition, update, body] = statement; - const [initStatement, conditionExpr, updateStatement] = this.ctx - .withResetIndentLevel(() => [ - init ? this.statement(init) : undefined, - condition ? this.typedExpression(condition, bool) : undefined, - update ? this.statement(update) : undefined, - ]); - - const initStr = initStatement ? initStatement.slice(0, -1) : ''; - const updateStr = updateStatement ? updateStatement.slice(0, -1) : ''; - - const bodyStr = this.block(blockifySingleStatement(body)); - return stitch`${this.ctx.pre}for (${initStr}; ${conditionExpr}; ${updateStr}) ${bodyStr}`; + try { + this.ctx.pushBlockScope(); + const [initStatement, conditionExpr, updateStatement] = this.ctx + .withResetIndentLevel(() => [ + init ? this.statement(init) : undefined, + condition ? this.typedExpression(condition, bool) : undefined, + update ? this.statement(update) : undefined, + ]); + + const initStr = initStatement ? initStatement.slice(0, -1) : ''; + const updateStr = updateStatement ? updateStatement.slice(0, -1) : ''; + + const bodyStr = this.block(blockifySingleStatement(body)); + return stitch`${this.ctx.pre}for (${initStr}; ${conditionExpr}; ${updateStr}) ${bodyStr}`; + } finally { + this.ctx.popBlockScope(); + } } if (statement[0] === NODE.while) { diff --git a/packages/typegpu/tests/examples/individual/3d-fish.test.ts b/packages/typegpu/tests/examples/individual/3d-fish.test.ts index 0f5f2cb656..4c75b546b6 100644 --- a/packages/typegpu/tests/examples/individual/3d-fish.test.ts +++ b/packages/typegpu/tests/examples/individual/3d-fish.test.ts @@ -160,11 +160,11 @@ describe('3d fish example', () => { if ((cohesionCount > 0i)) { cohesion = (((1f / f32(cohesionCount)) * cohesion) - (*fishData).position); } - for (var i_1 = 0; (i_1 < 3i); i_1 += 1i) { + for (var i = 0; (i < 3i); i += 1i) { var repulsion = vec3f(); - repulsion[i_1] = 1f; - let axisAquariumSize = (vec3f(10, 4, 10)[i_1] / 2f); - let axisPosition = (*fishData).position[i_1]; + repulsion[i] = 1f; + let axisAquariumSize = (vec3f(10, 4, 10)[i] / 2f); + let axisPosition = (*fishData).position[i]; const distance_1 = 0.1; if ((axisPosition > (axisAquariumSize - distance_1))) { let str2 = (axisPosition - (axisAquariumSize - distance_1)); diff --git a/packages/typegpu/tests/examples/individual/blur.test.ts b/packages/typegpu/tests/examples/individual/blur.test.ts index 8732ae8e21..137c90c309 100644 --- a/packages/typegpu/tests/examples/individual/blur.test.ts +++ b/packages/typegpu/tests/examples/individual/blur.test.ts @@ -62,9 +62,9 @@ describe('blur example', () => { } } workgroupBarrier(); - for (var r_1 = 0; (r_1 < 4i); r_1++) { + for (var r = 0; (r < 4i); r++) { for (var c = 0; (c < 4i); c++) { - var writeIndex = (baseIndex + vec2i(c, r_1)); + var writeIndex = (baseIndex + vec2i(c, r)); if ((flip != 0u)) { writeIndex = writeIndex.yx; } @@ -73,7 +73,7 @@ describe('blur example', () => { var acc = vec3f(); for (var f = 0; (f < (*settings2).filterDim); f++) { let i = ((center + f) - filterOffset); - acc = (acc + (tileData[r_1][i] * (1f / f32((*settings2).filterDim)))); + acc = (acc + (tileData[r][i] * (1f / f32((*settings2).filterDim)))); } textureStore(outTexture, writeIndex, vec4f(acc, 1f)); } diff --git a/packages/typegpu/tests/examples/individual/jelly-slider.test.ts b/packages/typegpu/tests/examples/individual/jelly-slider.test.ts index 4d8f6242eb..544d5b5ae7 100644 --- a/packages/typegpu/tests/examples/individual/jelly-slider.test.ts +++ b/packages/typegpu/tests/examples/individual/jelly-slider.test.ts @@ -533,7 +533,7 @@ describe('jelly-slider example', () => { return background; } var distanceFromOrigin = max(0f, intersection.tMin); - for (var i_1 = 0; (i_1 < 64i); i_1++) { + for (var i = 0; (i < 64i); i++) { if ((totalSteps >= 64u)) { break; } diff --git a/packages/typegpu/tests/examples/individual/jelly-switch.test.ts b/packages/typegpu/tests/examples/individual/jelly-switch.test.ts index 061c3e8411..8b4760c223 100644 --- a/packages/typegpu/tests/examples/individual/jelly-switch.test.ts +++ b/packages/typegpu/tests/examples/individual/jelly-switch.test.ts @@ -337,7 +337,7 @@ describe('jelly switch example', () => { return background; } var distanceFromOrigin = max(0f, intersection.tMin); - for (var i_1 = 0; (i_1 < 64i); i_1++) { + for (var i = 0; (i < 64i); i++) { if ((totalSteps >= 64u)) { break; } From 994c57cdd8f871f57269a765f0533c7aa4641c72 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Mon, 23 Feb 2026 21:11:56 +0100 Subject: [PATCH 12/14] review changes --- packages/typegpu/src/tgsl/shaderGenerator.ts | 2 +- packages/typegpu/src/tgsl/wgslGenerator.ts | 2 +- .../typegpu/tests/tgsl/wgslGenerator.test.ts | 39 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/typegpu/src/tgsl/shaderGenerator.ts b/packages/typegpu/src/tgsl/shaderGenerator.ts index d80f890606..90531d294a 100644 --- a/packages/typegpu/src/tgsl/shaderGenerator.ts +++ b/packages/typegpu/src/tgsl/shaderGenerator.ts @@ -2,7 +2,7 @@ import type { Block, Expression, Statement } from 'tinyest'; import type { Snippet } from '../data/snippet.ts'; import type { GenerationCtx } from './generationHelpers.ts'; import type { BaseData } from '../data/wgslTypes.ts'; -import type { ExternalMap } from '../../src/core/resolve/externals.ts'; +import type { ExternalMap } from '../core/resolve/externals.ts'; export interface ShaderGenerator { initGenerator(ctx: GenerationCtx): void; diff --git a/packages/typegpu/src/tgsl/wgslGenerator.ts b/packages/typegpu/src/tgsl/wgslGenerator.ts index 25f30d1e58..66cbb7f0f1 100644 --- a/packages/typegpu/src/tgsl/wgslGenerator.ts +++ b/packages/typegpu/src/tgsl/wgslGenerator.ts @@ -52,7 +52,7 @@ import type { AnyFn } from '../core/function/fnTypes.ts'; import { arrayLength } from '../std/array.ts'; import { AutoStruct } from '../data/autoStruct.ts'; import { mathToStd } from './math.ts'; -import type { ExternalMap } from '../../src/core/resolve/externals.ts'; +import type { ExternalMap } from '../core/resolve/externals.ts'; const { NodeTypeCatalog: NODE } = tinyest; diff --git a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts index bc2593ad4c..52f669ff04 100644 --- a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts +++ b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts @@ -1668,4 +1668,43 @@ describe('wgslGenerator', () => { `); }); }); + + it('block externals are respected in nested blocks', () => { + const f = () => { + 'use gpu'; + let result = d.i32(0); + const list = d.arrayOf(d.i32, 3)([1, 2, 3]); + for (const elem of list) { + { + // We use the `elem` in a nested block + result += elem; + } + } + }; + + const parsed = getMetaData(f)?.ast?.body as tinyest.Block; + + provideCtx(ctx, () => { + ctx[$internal].itemStateStack.pushFunctionScope( + 'normal', + [], + {}, + d.Void, + {}, + ); + + const res = wgslGenerator.block( + (parsed[1][2] as tinyest.ForOf)[3] as tinyest.Block, + { result: snip('result', d.i32, 'function'), elem: 7 }, + ); + + expect(res).toMatchInlineSnapshot(` + "{ + { + result += 7i; + } + }" + `); + }); + }); }); From aa20cb3ded9d01801fd67cb015c6a117e88d97c3 Mon Sep 17 00:00:00 2001 From: Aleksander Katan <56294622+aleksanderkatan@users.noreply.github.com> Date: Tue, 24 Feb 2026 14:17:31 +0100 Subject: [PATCH 13/14] fix (#2208) --- apps/typegpu-docs/src/examples/simple/ripple-cube/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 eefe51461e..c54058f835 100644 --- a/apps/typegpu-docs/src/examples/simple/ripple-cube/index.ts +++ b/apps/typegpu-docs/src/examples/simple/ripple-cube/index.ts @@ -230,7 +230,9 @@ let lastTimestamp = 0; let isExtendedRipplesEnabled = false; function run(timestamp: number) { - const deltaTime = (timestamp - lastTimestamp) / 1000; + const deltaTime = lastTimestamp === 0 + ? 0 + : (timestamp - lastTimestamp) / 1000; lastTimestamp = timestamp; const maxTime = isExtendedRipplesEnabled ? 62 : 28; accumulatedTime = Math.min( From d12d6e37952028b22c79e4c4fccb9ee3af58fa15 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 24 Feb 2026 14:22:37 +0100 Subject: [PATCH 14/14] review changes --- packages/typegpu/src/nameRegistry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/typegpu/src/nameRegistry.ts b/packages/typegpu/src/nameRegistry.ts index 15e3d71e61..22eb6892eb 100644 --- a/packages/typegpu/src/nameRegistry.ts +++ b/packages/typegpu/src/nameRegistry.ts @@ -515,7 +515,7 @@ abstract class NameRegistryImpl implements NameRegistry { ); if (functionScopeIndex === -1) { - return; + throw new Error('Tried to pop function scope when no scope was present.'); } this.#scopeStack.splice(functionScopeIndex);