diff --git a/apps/typegpu-docs/src/content/docs/apis/utils.mdx b/apps/typegpu-docs/src/content/docs/apis/utils.mdx index 819069d345..1989f949dc 100644 --- a/apps/typegpu-docs/src/content/docs/apis/utils.mdx +++ b/apps/typegpu-docs/src/content/docs/apis/utils.mdx @@ -231,18 +231,14 @@ Generates: fn processNeighbors(cell: vec2i) { // unrolled iteration #0 - { - // unrolled iteration #0 - { - processNeighbor(cell + vec2i(-1, -1)); - } - // unrolled iteration #1 - { - processNeighbor(cell + vec2i(0, -1)); - } - // (and so on...) - } - // (and so on ...) + // unrolled iteration #0 / #0 + processNeighbor(cell + vec2i(-1, -1)); + // unrolled iteration #0 / #1 + processNeighbor(cell + vec2i(0, -1)); + // unrolled iteration #0 / #2 + processNeighbor(cell + vec2i(1, -1)); + // --- + // (and so on...) } ``` @@ -275,17 +271,12 @@ Generates: fn fbm(pos: vec3f) -> f32 { var sum = 0f; // unrolled iteration #0 - { - sum += noise3d(pos * 1.4f) * 1f; - } + sum += noise3d(pos * 1.4f) * 1f; // unrolled iteration #1 - { - sum += noise3d(pos * 2.8f) * 0.5f; - } + sum += noise3d(pos * 2.8f) * 0.5f; // unrolled iteration #2 - { - sum += noise3d(pos * 5.6f) * 0.25f; - } + sum += noise3d(pos * 5.6f) * 0.25f; + // --- return sum; } ``` @@ -324,17 +315,12 @@ for (const foo of tgpu.unroll([1, 2, 3])) { Generates: ```wgsl // unrolled iteration #0 -{ - result += 1u; -} +result += 1u; // unrolled iteration #1 -{ - result += 2u; -} +result += 2u; // unrolled iteration #2 -{ - result += 3u; -} +result += 3u; +// --- ``` :::note `std.range` falls into the primitive array expression category. @@ -355,17 +341,14 @@ for (const foo of tgpu.unroll([b1, b2])) { Generates: ```wgsl // unrolled iteration #0 -{ - let boo = (&b1); - res = (res + b1.vel); - (*boo).pos = vec2i(); -} +let boo = (&b1); +res = (res + b1.vel); +(*boo).pos = vec2i(); // unrolled iteration #1 -{ - let boo = (&b2); - res = (res + b2.vel); - (*boo).pos = vec2i(); -} +let boo = (&b2); +res = (res + b2.vel); +(*boo).pos = vec2i(); +// --- ``` :::caution @@ -384,17 +367,12 @@ for (const foo of tgpu.unroll(d.vec3f(v))) { Generates: ```wgsl // unrolled iteration #0 -{ - res = res + v[0u]; -} +res = res + v[0u]; // unrolled iteration #1 -{ - res = res + v[1u]; -} +res = res + v[1u]; // unrolled iteration #2 -{ - res = res + v[2u]; -} +res = res + v[2u]; +// --- ``` **Array expression of struct field names** @@ -417,17 +395,12 @@ Generates: // ... // unrolled iteration #0 -{ - result += 1u; -} +result += 1u; // unrolled iteration #1 -{ - result += 2u; -} +result += 2u; // unrolled iteration #2 -{ - result += 3u; -} +result += 3u; +// --- // ... ``` @@ -452,17 +425,12 @@ Generates: var arr = array(1, 2, 3); var res = 0f; // unrolled iteration #0 -{ - res += f32(arr[0u]); -} +res += f32(arr[0u]); // unrolled iteration #1 -{ - res += f32(arr[1u]); -} +res += f32(arr[1u]); // unrolled iteration #2 -{ - res += f32(arr[2u]); -} +res += f32(arr[2u]); +// --- ``` **Buffer, `const`, `accessor`, `comptime`, `lazy`, etc.** @@ -490,17 +458,12 @@ Generates: fn f() -> u32 { var result = 0u; // unrolled iteration #0 - { - result += buffer[0u]; - } + result += buffer[0u]; // unrolled iteration #1 - { - result += buffer[1u]; - } + result += buffer[1u]; // unrolled iteration #2 - { - result += buffer[2u]; - } + result += buffer[2u]; + // --- return result; } ``` diff --git a/apps/typegpu-docs/tests/individual-example-tests/3d-fish.test.ts b/apps/typegpu-docs/tests/individual-example-tests/3d-fish.test.ts index 448deb3cd3..c7e29443d7 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/3d-fish.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/3d-fish.test.ts @@ -207,6 +207,7 @@ describe('3d fish example', () => { wallRepulsion = (wallRepulsion + (repulsion * str)); } } + // --- let proj = projectPointOnLine((*fishData).position, mouseRay); let diff = ((*fishData).position - proj); const limit = 1.2; diff --git a/apps/typegpu-docs/tests/individual-example-tests/blur.test.ts b/apps/typegpu-docs/tests/individual-example-tests/blur.test.ts index 6e9617f7c7..4db6c4623d 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/blur.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/blur.test.ts @@ -48,414 +48,408 @@ describe('blur example', () => { let dims = vec2i(textureDimensions(inTexture)); let baseIndex = (vec2i(((wid.xy * vec2u((*settings).blockDim, 4u)) + (lid.xy * vec2u(4, 1)))) - vec2i(filterOffset, 0i)); // unrolled iteration #0 + // unrolled iteration #0 / #0 { - // unrolled iteration #0 - { - var loadIndex = (baseIndex + vec2i()); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[0i][((lid.x * 4u) + 0u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + var loadIndex = (baseIndex + vec2i()); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #1 - { - var loadIndex = (baseIndex + vec2i(1, 0)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[0i][((lid.x * 4u) + 1u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[0i][((lid.x * 4u) + 0u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #0 / #1 + { + var loadIndex = (baseIndex + vec2i(1, 0)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #2 - { - var loadIndex = (baseIndex + vec2i(2, 0)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[0i][((lid.x * 4u) + 2u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[0i][((lid.x * 4u) + 1u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #0 / #2 + { + var loadIndex = (baseIndex + vec2i(2, 0)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #3 - { - var loadIndex = (baseIndex + vec2i(3, 0)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[0i][((lid.x * 4u) + 3u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[0i][((lid.x * 4u) + 2u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #0 / #3 + { + var loadIndex = (baseIndex + vec2i(3, 0)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } + tileData[0i][((lid.x * 4u) + 3u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; } + // --- // unrolled iteration #1 + // unrolled iteration #1 / #0 { - // unrolled iteration #0 - { - var loadIndex = (baseIndex + vec2i(0, 1)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[1i][((lid.x * 4u) + 0u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + var loadIndex = (baseIndex + vec2i(0, 1)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #1 - { - var loadIndex = (baseIndex + vec2i(1)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[1i][((lid.x * 4u) + 1u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[1i][((lid.x * 4u) + 0u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #1 / #1 + { + var loadIndex = (baseIndex + vec2i(1)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #2 - { - var loadIndex = (baseIndex + vec2i(2, 1)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[1i][((lid.x * 4u) + 2u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[1i][((lid.x * 4u) + 1u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #1 / #2 + { + var loadIndex = (baseIndex + vec2i(2, 1)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #3 - { - var loadIndex = (baseIndex + vec2i(3, 1)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[1i][((lid.x * 4u) + 3u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[1i][((lid.x * 4u) + 2u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #1 / #3 + { + var loadIndex = (baseIndex + vec2i(3, 1)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } + tileData[1i][((lid.x * 4u) + 3u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; } + // --- // unrolled iteration #2 + // unrolled iteration #2 / #0 { - // unrolled iteration #0 - { - var loadIndex = (baseIndex + vec2i(0, 2)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[2i][((lid.x * 4u) + 0u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + var loadIndex = (baseIndex + vec2i(0, 2)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #1 - { - var loadIndex = (baseIndex + vec2i(1, 2)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[2i][((lid.x * 4u) + 1u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[2i][((lid.x * 4u) + 0u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #2 / #1 + { + var loadIndex = (baseIndex + vec2i(1, 2)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #2 - { - var loadIndex = (baseIndex + vec2i(2)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[2i][((lid.x * 4u) + 2u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[2i][((lid.x * 4u) + 1u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #2 / #2 + { + var loadIndex = (baseIndex + vec2i(2)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #3 - { - var loadIndex = (baseIndex + vec2i(3, 2)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[2i][((lid.x * 4u) + 3u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[2i][((lid.x * 4u) + 2u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #2 / #3 + { + var loadIndex = (baseIndex + vec2i(3, 2)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } + tileData[2i][((lid.x * 4u) + 3u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; } + // --- // unrolled iteration #3 + // unrolled iteration #3 / #0 { - // unrolled iteration #0 - { - var loadIndex = (baseIndex + vec2i(0, 3)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[3i][((lid.x * 4u) + 0u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + var loadIndex = (baseIndex + vec2i(0, 3)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #1 - { - var loadIndex = (baseIndex + vec2i(1, 3)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[3i][((lid.x * 4u) + 1u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[3i][((lid.x * 4u) + 0u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #3 / #1 + { + var loadIndex = (baseIndex + vec2i(1, 3)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #2 - { - var loadIndex = (baseIndex + vec2i(2, 3)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[3i][((lid.x * 4u) + 2u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[3i][((lid.x * 4u) + 1u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #3 / #2 + { + var loadIndex = (baseIndex + vec2i(2, 3)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } - // unrolled iteration #3 - { - var loadIndex = (baseIndex + vec2i(3)); - if ((flip != 0u)) { - loadIndex = loadIndex.yx; - } - tileData[3i][((lid.x * 4u) + 3u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + tileData[3i][((lid.x * 4u) + 2u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; + } + // unrolled iteration #3 / #3 + { + var loadIndex = (baseIndex + vec2i(3)); + if ((flip != 0u)) { + loadIndex = loadIndex.yx; } + tileData[3i][((lid.x * 4u) + 3u)] = textureSampleLevel(inTexture, sampler_1, ((vec2f(loadIndex) + vec2f(0.5)) / vec2f(dims)), 0).rgb; } + // --- + // --- workgroupBarrier(); // unrolled iteration #0 + // unrolled iteration #0 / #0 { - // unrolled iteration #0 - { - var writeIndex = (baseIndex + vec2i()); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 0i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[0i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); - } + var writeIndex = (baseIndex + vec2i()); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; } - // unrolled iteration #1 - { - var writeIndex = (baseIndex + vec2i(1, 0)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 1i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[0i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + let center = (i32((4u * lid.x)) + 0i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[0i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); } - // unrolled iteration #2 - { - var writeIndex = (baseIndex + vec2i(2, 0)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 2i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[0i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + // unrolled iteration #0 / #1 + { + var writeIndex = (baseIndex + vec2i(1, 0)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; + } + let center = (i32((4u * lid.x)) + 1i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[0i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + } + // unrolled iteration #0 / #2 + { + var writeIndex = (baseIndex + vec2i(2, 0)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; } - // unrolled iteration #3 - { - var writeIndex = (baseIndex + vec2i(3, 0)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; + let center = (i32((4u * lid.x)) + 2i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[0i][i] * (1f / f32((*settings).filterDim)))); } - let center = (i32((4u * lid.x)) + 3i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[0i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + } + // unrolled iteration #0 / #3 + { + var writeIndex = (baseIndex + vec2i(3, 0)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; + } + let center = (i32((4u * lid.x)) + 3i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[0i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); } } + // --- // unrolled iteration #1 + // unrolled iteration #1 / #0 { - // unrolled iteration #0 - { - var writeIndex = (baseIndex + vec2i(0, 1)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 0i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[1i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); - } + var writeIndex = (baseIndex + vec2i(0, 1)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; } - // unrolled iteration #1 - { - var writeIndex = (baseIndex + vec2i(1)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 1i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[1i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + let center = (i32((4u * lid.x)) + 0i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[1i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); } - // unrolled iteration #2 - { - var writeIndex = (baseIndex + vec2i(2, 1)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 2i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[1i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + // unrolled iteration #1 / #1 + { + var writeIndex = (baseIndex + vec2i(1)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; + } + let center = (i32((4u * lid.x)) + 1i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[1i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + } + // unrolled iteration #1 / #2 + { + var writeIndex = (baseIndex + vec2i(2, 1)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; } - // unrolled iteration #3 - { - var writeIndex = (baseIndex + vec2i(3, 1)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; + let center = (i32((4u * lid.x)) + 2i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[1i][i] * (1f / f32((*settings).filterDim)))); } - let center = (i32((4u * lid.x)) + 3i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[1i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + } + // unrolled iteration #1 / #3 + { + var writeIndex = (baseIndex + vec2i(3, 1)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; + } + let center = (i32((4u * lid.x)) + 3i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[1i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); } } + // --- // unrolled iteration #2 + // unrolled iteration #2 / #0 { - // unrolled iteration #0 - { - var writeIndex = (baseIndex + vec2i(0, 2)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 0i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[2i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); - } + var writeIndex = (baseIndex + vec2i(0, 2)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; } - // unrolled iteration #1 - { - var writeIndex = (baseIndex + vec2i(1, 2)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 1i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[2i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + let center = (i32((4u * lid.x)) + 0i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[2i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); } - // unrolled iteration #2 - { - var writeIndex = (baseIndex + vec2i(2)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 2i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[2i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + // unrolled iteration #2 / #1 + { + var writeIndex = (baseIndex + vec2i(1, 2)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; + } + let center = (i32((4u * lid.x)) + 1i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[2i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + } + // unrolled iteration #2 / #2 + { + var writeIndex = (baseIndex + vec2i(2)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; } - // unrolled iteration #3 - { - var writeIndex = (baseIndex + vec2i(3, 2)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; + let center = (i32((4u * lid.x)) + 2i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[2i][i] * (1f / f32((*settings).filterDim)))); } - let center = (i32((4u * lid.x)) + 3i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[2i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + } + // unrolled iteration #2 / #3 + { + var writeIndex = (baseIndex + vec2i(3, 2)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; + } + let center = (i32((4u * lid.x)) + 3i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[2i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); } } + // --- // unrolled iteration #3 + // unrolled iteration #3 / #0 { - // unrolled iteration #0 - { - var writeIndex = (baseIndex + vec2i(0, 3)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 0i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[3i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); - } + var writeIndex = (baseIndex + vec2i(0, 3)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; } - // unrolled iteration #1 - { - var writeIndex = (baseIndex + vec2i(1, 3)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 1i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[3i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + let center = (i32((4u * lid.x)) + 0i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[3i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); } - // unrolled iteration #2 - { - var writeIndex = (baseIndex + vec2i(2, 3)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; - } - let center = (i32((4u * lid.x)) + 2i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[3i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + // unrolled iteration #3 / #1 + { + var writeIndex = (baseIndex + vec2i(1, 3)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; + } + let center = (i32((4u * lid.x)) + 1i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[3i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + } + // unrolled iteration #3 / #2 + { + var writeIndex = (baseIndex + vec2i(2, 3)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; } - // unrolled iteration #3 - { - var writeIndex = (baseIndex + vec2i(3)); - if ((flip != 0u)) { - writeIndex = writeIndex.yx; + let center = (i32((4u * lid.x)) + 2i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[3i][i] * (1f / f32((*settings).filterDim)))); } - let center = (i32((4u * lid.x)) + 3i); - if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { - var acc = vec3f(); - for (var f = 0; (f < (*settings).filterDim); f++) { - let i = ((center + f) - filterOffset); - acc = (acc + (tileData[3i][i] * (1f / f32((*settings).filterDim)))); - } - textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); + } + } + // unrolled iteration #3 / #3 + { + var writeIndex = (baseIndex + vec2i(3)); + if ((flip != 0u)) { + writeIndex = writeIndex.yx; + } + let center = (i32((4u * lid.x)) + 3i); + if ((((center >= filterOffset) && (center < (128i - filterOffset))) && all((writeIndex < dims)))) { + var acc = vec3f(); + for (var f = 0; (f < (*settings).filterDim); f++) { + let i = ((center + f) - filterOffset); + acc = (acc + (tileData[3i][i] * (1f / f32((*settings).filterDim)))); } + textureStore(outTexture, writeIndex, vec4f(acc, 1f)); } } + // --- + // --- } struct fullScreenTriangle_Output { diff --git a/apps/typegpu-docs/tests/individual-example-tests/clouds.test.ts b/apps/typegpu-docs/tests/individual-example-tests/clouds.test.ts index d7da120837..4e85b500ab 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/clouds.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/clouds.test.ts @@ -84,17 +84,12 @@ describe('clouds example', () => { fn fbm(pos: vec3f) -> f32 { var sum = 0f; // unrolled iteration #0 - { - sum += (noise3d((pos * 1.4f)) * 1f); - } + sum += (noise3d((pos * 1.4f)) * 1f); // unrolled iteration #1 - { - sum += (noise3d((pos * 2.8f)) * 0.5f); - } + sum += (noise3d((pos * 2.8f)) * 0.5f); // unrolled iteration #2 - { - sum += (noise3d((pos * 5.6f)) * 0.25f); - } + sum += (noise3d((pos * 5.6f)) * 0.25f); + // --- return sum; } diff --git a/apps/typegpu-docs/tests/individual-example-tests/cubemap-reflection.test.ts b/apps/typegpu-docs/tests/individual-example-tests/cubemap-reflection.test.ts index 53ff4f48c7..a4efd9aa27 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/cubemap-reflection.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/cubemap-reflection.test.ts @@ -237,6 +237,7 @@ describe('cubemap reflection example', () => { (*nextVertex).position = packVec2u((*reprojectedVertex)); (*nextVertex).normal = packVec2u(normal); } + // --- } struct Camera { diff --git a/apps/typegpu-docs/tests/individual-example-tests/fluid-double-buffering.test.ts b/apps/typegpu-docs/tests/individual-example-tests/fluid-double-buffering.test.ts index 440914a2c5..880ca4c5b2 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/fluid-double-buffering.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/fluid-double-buffering.test.ts @@ -249,6 +249,7 @@ describe('fluid double buffering example', () => { } } } + // --- let leastCostDir = (&dirChoices[u32((randFloat01() * f32(dirChoiceCount)))]); return (*leastCostDir); } @@ -476,6 +477,7 @@ describe('fluid double buffering example', () => { } } } + // --- let leastCostDir = (&dirChoices[u32((randFloat01() * f32(dirChoiceCount)))]); return (*leastCostDir); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/jelly-slider.test.ts b/apps/typegpu-docs/tests/individual-example-tests/jelly-slider.test.ts index fefdfc76f6..60c683943d 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/jelly-slider.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/jelly-slider.test.ts @@ -604,86 +604,84 @@ describe('jelly-slider example', () => { var maxColor = vec3f(-9999); let dimensions = textureDimensions(currentTexture); // unrolled iteration #0 + // unrolled iteration #0 / #0 { - // unrolled iteration #0 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(-1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #1 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 0)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #2 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } + let sampleCoord = (vec2i(gid.xy) + vec2i(-1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); } + // unrolled iteration #0 / #1 + { + let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // unrolled iteration #0 / #2 + { + let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // --- // unrolled iteration #1 + // unrolled iteration #1 / #0 { - // unrolled iteration #0 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(0, -1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #1 - { - let sampleCoord = (vec2i(gid.xy) + vec2i()); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #2 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(0, 1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } + let sampleCoord = (vec2i(gid.xy) + vec2i(0, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); } + // unrolled iteration #1 / #1 + { + let sampleCoord = (vec2i(gid.xy) + vec2i()); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // unrolled iteration #1 / #2 + { + let sampleCoord = (vec2i(gid.xy) + vec2i(0, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // --- // unrolled iteration #2 + // unrolled iteration #2 / #0 { - // unrolled iteration #0 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(1, -1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #1 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(1, 0)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #2 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } + let sampleCoord = (vec2i(gid.xy) + vec2i(1, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // unrolled iteration #2 / #1 + { + let sampleCoord = (vec2i(gid.xy) + vec2i(1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // unrolled iteration #2 / #2 + { + let sampleCoord = (vec2i(gid.xy) + vec2i(1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); } + // --- + // --- let historyColorClamped = clamp(historyColor.rgb, minColor, maxColor); let uv = (vec2f(gid.xy) / vec2f(dimensions.xy)); const textRegionMinX = 0.7099999785423279f; diff --git a/apps/typegpu-docs/tests/individual-example-tests/jelly-switch.test.ts b/apps/typegpu-docs/tests/individual-example-tests/jelly-switch.test.ts index 69a5feb0e3..126fe2ac88 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/jelly-switch.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/jelly-switch.test.ts @@ -407,86 +407,84 @@ describe('jelly switch example', () => { var maxColor = vec3f(-9999); let dimensions = textureDimensions(currentTexture); // unrolled iteration #0 + // unrolled iteration #0 / #0 { - // unrolled iteration #0 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(-1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #1 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 0)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #2 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } + let sampleCoord = (vec2i(gid.xy) + vec2i(-1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); } + // unrolled iteration #0 / #1 + { + let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // unrolled iteration #0 / #2 + { + let sampleCoord = (vec2i(gid.xy) + vec2i(-1, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // --- // unrolled iteration #1 + // unrolled iteration #1 / #0 { - // unrolled iteration #0 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(0, -1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #1 - { - let sampleCoord = (vec2i(gid.xy) + vec2i()); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #2 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(0, 1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } + let sampleCoord = (vec2i(gid.xy) + vec2i(0, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); } + // unrolled iteration #1 / #1 + { + let sampleCoord = (vec2i(gid.xy) + vec2i()); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // unrolled iteration #1 / #2 + { + let sampleCoord = (vec2i(gid.xy) + vec2i(0, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // --- // unrolled iteration #2 + // unrolled iteration #2 / #0 { - // unrolled iteration #0 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(1, -1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #1 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(1, 0)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } - // unrolled iteration #2 - { - let sampleCoord = (vec2i(gid.xy) + vec2i(1)); - let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); - let neighborColor = textureLoad(currentTexture, clampedCoord, 0); - minColor = min(minColor, neighborColor.rgb); - maxColor = max(maxColor, neighborColor.rgb); - } + let sampleCoord = (vec2i(gid.xy) + vec2i(1, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // unrolled iteration #2 / #1 + { + let sampleCoord = (vec2i(gid.xy) + vec2i(1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); + } + // unrolled iteration #2 / #2 + { + let sampleCoord = (vec2i(gid.xy) + vec2i(1)); + let clampedCoord = clamp(sampleCoord, vec2i(), (vec2i(dimensions.xy) - vec2i(1))); + let neighborColor = textureLoad(currentTexture, clampedCoord, 0); + minColor = min(minColor, neighborColor.rgb); + maxColor = max(maxColor, neighborColor.rgb); } + // --- + // --- let historyColorClamped = clamp(historyColor.rgb, minColor, maxColor); const blendFactor = 0.8999999761581421f; let resolvedColor = vec4f(mix(currentColor.rgb, historyColorClamped, blendFactor), 1f); diff --git a/apps/typegpu-docs/tests/individual-example-tests/jump-flood-distance.test.ts b/apps/typegpu-docs/tests/individual-example-tests/jump-flood-distance.test.ts index dbabdaa849..ddbdce02a1 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/jump-flood-distance.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/jump-flood-distance.test.ts @@ -80,176 +80,174 @@ describe('jump flood (distance) example', () => { var bestInsideDist = 3.4028234663852886e+38f; var bestOutsideDist = 3.4028234663852886e+38f; // unrolled iteration #0 + // unrolled iteration #0 / #0 { - // unrolled iteration #0 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (-1i * offset))); - if ((sample.inside.x >= 0f)) { - let dInside = distance(pos, (sample.inside * vec2f(size))); - if ((dInside < bestInsideDist)) { - bestInsideDist = dInside; - bestInsideCoord = sample.inside; - } + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (-1i * offset))); + if ((sample.inside.x >= 0f)) { + let dInside = distance(pos, (sample.inside * vec2f(size))); + if ((dInside < bestInsideDist)) { + bestInsideDist = dInside; + bestInsideCoord = sample.inside; } - if ((sample.outside.x >= 0f)) { - let dOutside = distance(pos, (sample.outside * vec2f(size))); - if ((dOutside < bestOutsideDist)) { - bestOutsideDist = dOutside; - bestOutsideCoord = sample.outside; - } + } + if ((sample.outside.x >= 0f)) { + let dOutside = distance(pos, (sample.outside * vec2f(size))); + if ((dOutside < bestOutsideDist)) { + bestOutsideDist = dOutside; + bestOutsideCoord = sample.outside; } } - // unrolled iteration #1 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (0i * offset))); - if ((sample.inside.x >= 0f)) { - let dInside = distance(pos, (sample.inside * vec2f(size))); - if ((dInside < bestInsideDist)) { - bestInsideDist = dInside; - bestInsideCoord = sample.inside; - } + } + // unrolled iteration #0 / #1 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (0i * offset))); + if ((sample.inside.x >= 0f)) { + let dInside = distance(pos, (sample.inside * vec2f(size))); + if ((dInside < bestInsideDist)) { + bestInsideDist = dInside; + bestInsideCoord = sample.inside; } - if ((sample.outside.x >= 0f)) { - let dOutside = distance(pos, (sample.outside * vec2f(size))); - if ((dOutside < bestOutsideDist)) { - bestOutsideDist = dOutside; - bestOutsideCoord = sample.outside; - } + } + if ((sample.outside.x >= 0f)) { + let dOutside = distance(pos, (sample.outside * vec2f(size))); + if ((dOutside < bestOutsideDist)) { + bestOutsideDist = dOutside; + bestOutsideCoord = sample.outside; } } - // unrolled iteration #2 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (1i * offset))); - if ((sample.inside.x >= 0f)) { - let dInside = distance(pos, (sample.inside * vec2f(size))); - if ((dInside < bestInsideDist)) { - bestInsideDist = dInside; - bestInsideCoord = sample.inside; - } + } + // unrolled iteration #0 / #2 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (1i * offset))); + if ((sample.inside.x >= 0f)) { + let dInside = distance(pos, (sample.inside * vec2f(size))); + if ((dInside < bestInsideDist)) { + bestInsideDist = dInside; + bestInsideCoord = sample.inside; } - if ((sample.outside.x >= 0f)) { - let dOutside = distance(pos, (sample.outside * vec2f(size))); - if ((dOutside < bestOutsideDist)) { - bestOutsideDist = dOutside; - bestOutsideCoord = sample.outside; - } + } + if ((sample.outside.x >= 0f)) { + let dOutside = distance(pos, (sample.outside * vec2f(size))); + if ((dOutside < bestOutsideDist)) { + bestOutsideDist = dOutside; + bestOutsideCoord = sample.outside; } } } + // --- // unrolled iteration #1 + // unrolled iteration #1 / #0 { - // unrolled iteration #0 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (-1i * offset))); - if ((sample.inside.x >= 0f)) { - let dInside = distance(pos, (sample.inside * vec2f(size))); - if ((dInside < bestInsideDist)) { - bestInsideDist = dInside; - bestInsideCoord = sample.inside; - } + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (-1i * offset))); + if ((sample.inside.x >= 0f)) { + let dInside = distance(pos, (sample.inside * vec2f(size))); + if ((dInside < bestInsideDist)) { + bestInsideDist = dInside; + bestInsideCoord = sample.inside; } - if ((sample.outside.x >= 0f)) { - let dOutside = distance(pos, (sample.outside * vec2f(size))); - if ((dOutside < bestOutsideDist)) { - bestOutsideDist = dOutside; - bestOutsideCoord = sample.outside; - } + } + if ((sample.outside.x >= 0f)) { + let dOutside = distance(pos, (sample.outside * vec2f(size))); + if ((dOutside < bestOutsideDist)) { + bestOutsideDist = dOutside; + bestOutsideCoord = sample.outside; } } - // unrolled iteration #1 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (0i * offset))); - if ((sample.inside.x >= 0f)) { - let dInside = distance(pos, (sample.inside * vec2f(size))); - if ((dInside < bestInsideDist)) { - bestInsideDist = dInside; - bestInsideCoord = sample.inside; - } + } + // unrolled iteration #1 / #1 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (0i * offset))); + if ((sample.inside.x >= 0f)) { + let dInside = distance(pos, (sample.inside * vec2f(size))); + if ((dInside < bestInsideDist)) { + bestInsideDist = dInside; + bestInsideCoord = sample.inside; } - if ((sample.outside.x >= 0f)) { - let dOutside = distance(pos, (sample.outside * vec2f(size))); - if ((dOutside < bestOutsideDist)) { - bestOutsideDist = dOutside; - bestOutsideCoord = sample.outside; - } + } + if ((sample.outside.x >= 0f)) { + let dOutside = distance(pos, (sample.outside * vec2f(size))); + if ((dOutside < bestOutsideDist)) { + bestOutsideDist = dOutside; + bestOutsideCoord = sample.outside; } } - // unrolled iteration #2 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (1i * offset))); - if ((sample.inside.x >= 0f)) { - let dInside = distance(pos, (sample.inside * vec2f(size))); - if ((dInside < bestInsideDist)) { - bestInsideDist = dInside; - bestInsideCoord = sample.inside; - } + } + // unrolled iteration #1 / #2 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (1i * offset))); + if ((sample.inside.x >= 0f)) { + let dInside = distance(pos, (sample.inside * vec2f(size))); + if ((dInside < bestInsideDist)) { + bestInsideDist = dInside; + bestInsideCoord = sample.inside; } - if ((sample.outside.x >= 0f)) { - let dOutside = distance(pos, (sample.outside * vec2f(size))); - if ((dOutside < bestOutsideDist)) { - bestOutsideDist = dOutside; - bestOutsideCoord = sample.outside; - } + } + if ((sample.outside.x >= 0f)) { + let dOutside = distance(pos, (sample.outside * vec2f(size))); + if ((dOutside < bestOutsideDist)) { + bestOutsideDist = dOutside; + bestOutsideCoord = sample.outside; } } } + // --- // unrolled iteration #2 + // unrolled iteration #2 / #0 { - // unrolled iteration #0 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (-1i * offset))); - if ((sample.inside.x >= 0f)) { - let dInside = distance(pos, (sample.inside * vec2f(size))); - if ((dInside < bestInsideDist)) { - bestInsideDist = dInside; - bestInsideCoord = sample.inside; - } + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (-1i * offset))); + if ((sample.inside.x >= 0f)) { + let dInside = distance(pos, (sample.inside * vec2f(size))); + if ((dInside < bestInsideDist)) { + bestInsideDist = dInside; + bestInsideCoord = sample.inside; } - if ((sample.outside.x >= 0f)) { - let dOutside = distance(pos, (sample.outside * vec2f(size))); - if ((dOutside < bestOutsideDist)) { - bestOutsideDist = dOutside; - bestOutsideCoord = sample.outside; - } + } + if ((sample.outside.x >= 0f)) { + let dOutside = distance(pos, (sample.outside * vec2f(size))); + if ((dOutside < bestOutsideDist)) { + bestOutsideDist = dOutside; + bestOutsideCoord = sample.outside; } } - // unrolled iteration #1 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (0i * offset))); - if ((sample.inside.x >= 0f)) { - let dInside = distance(pos, (sample.inside * vec2f(size))); - if ((dInside < bestInsideDist)) { - bestInsideDist = dInside; - bestInsideCoord = sample.inside; - } + } + // unrolled iteration #2 / #1 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (0i * offset))); + if ((sample.inside.x >= 0f)) { + let dInside = distance(pos, (sample.inside * vec2f(size))); + if ((dInside < bestInsideDist)) { + bestInsideDist = dInside; + bestInsideCoord = sample.inside; } - if ((sample.outside.x >= 0f)) { - let dOutside = distance(pos, (sample.outside * vec2f(size))); - if ((dOutside < bestOutsideDist)) { - bestOutsideDist = dOutside; - bestOutsideCoord = sample.outside; - } + } + if ((sample.outside.x >= 0f)) { + let dOutside = distance(pos, (sample.outside * vec2f(size))); + if ((dOutside < bestOutsideDist)) { + bestOutsideDist = dOutside; + bestOutsideCoord = sample.outside; } } - // unrolled iteration #2 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (1i * offset))); - if ((sample.inside.x >= 0f)) { - let dInside = distance(pos, (sample.inside * vec2f(size))); - if ((dInside < bestInsideDist)) { - bestInsideDist = dInside; - bestInsideCoord = sample.inside; - } + } + // unrolled iteration #2 / #2 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (1i * offset))); + if ((sample.inside.x >= 0f)) { + let dInside = distance(pos, (sample.inside * vec2f(size))); + if ((dInside < bestInsideDist)) { + bestInsideDist = dInside; + bestInsideCoord = sample.inside; } - if ((sample.outside.x >= 0f)) { - let dOutside = distance(pos, (sample.outside * vec2f(size))); - if ((dOutside < bestOutsideDist)) { - bestOutsideDist = dOutside; - bestOutsideCoord = sample.outside; - } + } + if ((sample.outside.x >= 0f)) { + let dOutside = distance(pos, (sample.outside * vec2f(size))); + if ((dOutside < bestOutsideDist)) { + bestOutsideDist = dOutside; + bestOutsideCoord = sample.outside; } } } + // --- + // --- textureStore(writeView, vec2i(i32(x), i32(y)), vec4f(bestInsideCoord, bestOutsideCoord)); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/jump-flood-voronoi.test.ts b/apps/typegpu-docs/tests/individual-example-tests/jump-flood-voronoi.test.ts index fa0e4cd1e5..79cc56a998 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/jump-flood-voronoi.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/jump-flood-voronoi.test.ts @@ -127,113 +127,111 @@ describe('jump flood (voronoi) example', () => { var minDist = 1e+20; var bestSample = SampleResult(vec4f(), vec2f(-1)); // unrolled iteration #0 + // unrolled iteration #0 / #0 { - // unrolled iteration #0 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (-1i * offset))); - if ((sample.coord.x >= 0f)) { - let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); - if ((dist < minDist)) { - minDist = dist; - bestSample = sample; - } + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (-1i * offset))); + if ((sample.coord.x >= 0f)) { + let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); + if ((dist < minDist)) { + minDist = dist; + bestSample = sample; } } - // unrolled iteration #1 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (-1i * offset))); - if ((sample.coord.x >= 0f)) { - let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); - if ((dist < minDist)) { - minDist = dist; - bestSample = sample; - } + } + // unrolled iteration #0 / #1 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (-1i * offset))); + if ((sample.coord.x >= 0f)) { + let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); + if ((dist < minDist)) { + minDist = dist; + bestSample = sample; } } - // unrolled iteration #2 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (-1i * offset))); - if ((sample.coord.x >= 0f)) { - let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); - if ((dist < minDist)) { - minDist = dist; - bestSample = sample; - } + } + // unrolled iteration #0 / #2 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (-1i * offset))); + if ((sample.coord.x >= 0f)) { + let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); + if ((dist < minDist)) { + minDist = dist; + bestSample = sample; } } } + // --- // unrolled iteration #1 + // unrolled iteration #1 / #0 { - // unrolled iteration #0 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (0i * offset))); - if ((sample.coord.x >= 0f)) { - let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); - if ((dist < minDist)) { - minDist = dist; - bestSample = sample; - } + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (0i * offset))); + if ((sample.coord.x >= 0f)) { + let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); + if ((dist < minDist)) { + minDist = dist; + bestSample = sample; } } - // unrolled iteration #1 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (0i * offset))); - if ((sample.coord.x >= 0f)) { - let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); - if ((dist < minDist)) { - minDist = dist; - bestSample = sample; - } + } + // unrolled iteration #1 / #1 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (0i * offset))); + if ((sample.coord.x >= 0f)) { + let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); + if ((dist < minDist)) { + minDist = dist; + bestSample = sample; } } - // unrolled iteration #2 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (0i * offset))); - if ((sample.coord.x >= 0f)) { - let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); - if ((dist < minDist)) { - minDist = dist; - bestSample = sample; - } + } + // unrolled iteration #1 / #2 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (0i * offset))); + if ((sample.coord.x >= 0f)) { + let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); + if ((dist < minDist)) { + minDist = dist; + bestSample = sample; } } } + // --- // unrolled iteration #2 + // unrolled iteration #2 / #0 { - // unrolled iteration #0 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (1i * offset))); - if ((sample.coord.x >= 0f)) { - let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); - if ((dist < minDist)) { - minDist = dist; - bestSample = sample; - } + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((-1i * offset), (1i * offset))); + if ((sample.coord.x >= 0f)) { + let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); + if ((dist < minDist)) { + minDist = dist; + bestSample = sample; } } - // unrolled iteration #1 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (1i * offset))); - if ((sample.coord.x >= 0f)) { - let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); - if ((dist < minDist)) { - minDist = dist; - bestSample = sample; - } + } + // unrolled iteration #2 / #1 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((0i * offset), (1i * offset))); + if ((sample.coord.x >= 0f)) { + let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); + if ((dist < minDist)) { + minDist = dist; + bestSample = sample; } } - // unrolled iteration #2 - { - let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (1i * offset))); - if ((sample.coord.x >= 0f)) { - let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); - if ((dist < minDist)) { - minDist = dist; - bestSample = sample; - } + } + // unrolled iteration #2 / #2 + { + let sample = sampleWithOffset(readView, vec2i(i32(x), i32(y)), vec2i((1i * offset), (1i * offset))); + if ((sample.coord.x >= 0f)) { + let dist = distance(vec2f(f32(x), f32(y)), (sample.coord * vec2f(size))); + if ((dist < minDist)) { + minDist = dist; + bestSample = sample; } } } + // --- + // --- textureStore(writeView, vec2i(i32(x), i32(y)), 0, bestSample.color); textureStore(writeView, vec2i(i32(x), i32(y)), 1, vec4f(bestSample.coord, 0f, 0f)); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/liquid-glass.test.ts b/apps/typegpu-docs/tests/individual-example-tests/liquid-glass.test.ts index c470fad45a..6d5100c366 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/liquid-glass.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/liquid-glass.test.ts @@ -121,6 +121,7 @@ describe('liquid-glass example', () => { let channelOffset = ((dir * 1f) * offset); samples[2i] = textureSampleBias(tex, sampler_2, (uv - channelOffset), blur).rgb; } + // --- return vec3f(samples[0i].x, samples[1i].y, samples[2i].z); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/log-test.test.ts b/apps/typegpu-docs/tests/individual-example-tests/log-test.test.ts index 86ba2283ac..430f4a5540 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/log-test.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/log-test.test.ts @@ -815,9 +815,7 @@ describe('console log example', () => { log26(mat3x3f(0, 0.25, 0.5, 1, 1.25, 1.5, 2, 2.25, 2.5)); log27(mat4x4f(0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75)); log28(); - { - log29(); - } + log29(); } @compute @workgroup_size(1, 1, 1) fn mainCompute(@builtin(global_invocation_id) id: vec3u) { diff --git a/apps/typegpu-docs/tests/individual-example-tests/ripple-cube.test.ts b/apps/typegpu-docs/tests/individual-example-tests/ripple-cube.test.ts index 6630a5e697..1cd4c470dc 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/ripple-cube.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/ripple-cube.test.ts @@ -466,13 +466,10 @@ describe('ripple-cube example', () => { let f0 = mix(vec3f(0.03999999910593033), (*material).albedo, (*material).metallic); var lo = vec3f(); // unrolled iteration #0 - { - lo += evaluateLight(p, n, v, lightsUniform[0i], (*material), f0); - } + lo += evaluateLight(p, n, v, lightsUniform[0i], (*material), f0); // unrolled iteration #1 - { - lo += evaluateLight(p, n, v, lightsUniform[1i], (*material), f0); - } + lo += evaluateLight(p, n, v, lightsUniform[1i], (*material), f0); + // --- let reflectDir = reflect(v, n); let pScaled = (p * 50f); let roughOffset = ((vec3f(sample(pScaled), sample((pScaled + 100f)), sample((pScaled + 200f))) * (*material).roughness) * 0.3f); @@ -548,86 +545,84 @@ describe('ripple-cube example', () => { var minColor = vec3f(9999); var maxColor = vec3f(-9999); // unrolled iteration #0 + // unrolled iteration #0 / #0 { - // unrolled iteration #0 - { - let sampleCoord = (coord + vec2i(-1)); - let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; - minColor = min(minColor, neighbor); - maxColor = max(maxColor, neighbor); - } - // unrolled iteration #1 - { - let sampleCoord = (coord + vec2i(-1, 0)); - let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; - minColor = min(minColor, neighbor); - maxColor = max(maxColor, neighbor); - } - // unrolled iteration #2 - { - let sampleCoord = (coord + vec2i(-1, 1)); - let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; - minColor = min(minColor, neighbor); - maxColor = max(maxColor, neighbor); - } + let sampleCoord = (coord + vec2i(-1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + minColor = min(minColor, neighbor); + maxColor = max(maxColor, neighbor); } + // unrolled iteration #0 / #1 + { + let sampleCoord = (coord + vec2i(-1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + minColor = min(minColor, neighbor); + maxColor = max(maxColor, neighbor); + } + // unrolled iteration #0 / #2 + { + let sampleCoord = (coord + vec2i(-1, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + minColor = min(minColor, neighbor); + maxColor = max(maxColor, neighbor); + } + // --- // unrolled iteration #1 + // unrolled iteration #1 / #0 { - // unrolled iteration #0 - { - let sampleCoord = (coord + vec2i(0, -1)); - let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; - minColor = min(minColor, neighbor); - maxColor = max(maxColor, neighbor); - } - // unrolled iteration #1 - { - let sampleCoord = (coord + vec2i()); - let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; - minColor = min(minColor, neighbor); - maxColor = max(maxColor, neighbor); - } - // unrolled iteration #2 - { - let sampleCoord = (coord + vec2i(0, 1)); - let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; - minColor = min(minColor, neighbor); - maxColor = max(maxColor, neighbor); - } + let sampleCoord = (coord + vec2i(0, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + minColor = min(minColor, neighbor); + maxColor = max(maxColor, neighbor); + } + // unrolled iteration #1 / #1 + { + let sampleCoord = (coord + vec2i()); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + minColor = min(minColor, neighbor); + maxColor = max(maxColor, neighbor); } + // unrolled iteration #1 / #2 + { + let sampleCoord = (coord + vec2i(0, 1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + minColor = min(minColor, neighbor); + maxColor = max(maxColor, neighbor); + } + // --- // unrolled iteration #2 + // unrolled iteration #2 / #0 { - // unrolled iteration #0 - { - let sampleCoord = (coord + vec2i(1, -1)); - let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; - minColor = min(minColor, neighbor); - maxColor = max(maxColor, neighbor); - } - // unrolled iteration #1 - { - let sampleCoord = (coord + vec2i(1, 0)); - let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; - minColor = min(minColor, neighbor); - maxColor = max(maxColor, neighbor); - } - // unrolled iteration #2 - { - let sampleCoord = (coord + vec2i(1)); - let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); - let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; - minColor = min(minColor, neighbor); - maxColor = max(maxColor, neighbor); - } + let sampleCoord = (coord + vec2i(1, -1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + minColor = min(minColor, neighbor); + maxColor = max(maxColor, neighbor); + } + // unrolled iteration #2 / #1 + { + let sampleCoord = (coord + vec2i(1, 0)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + minColor = min(minColor, neighbor); + maxColor = max(maxColor, neighbor); + } + // unrolled iteration #2 / #2 + { + let sampleCoord = (coord + vec2i(1)); + let clampedCoord = clamp(sampleCoord, vec2i(), vec2i(181)); + let neighbor = textureLoad(currentTexture, clampedCoord, 0).rgb; + minColor = min(minColor, neighbor); + maxColor = max(maxColor, neighbor); } + // --- + // --- let clampedHistory = clamp(historyColor.rgb, minColor, maxColor); let blended = mix(current.rgb, clampedHistory, 0.85f); textureStore(outputTexture, vec2u(x, y), vec4f(blended, 1f)); diff --git a/apps/typegpu-docs/tests/individual-example-tests/slime-mold-3d.test.ts b/apps/typegpu-docs/tests/individual-example-tests/slime-mold-3d.test.ts index 0acb522042..024a987a3b 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/slime-mold-3d.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/slime-mold-3d.test.ts @@ -267,6 +267,7 @@ describe('slime mold 3d example', () => { weightedDir = (weightedDir + (sensorDir * weight)); totalWeight = (totalWeight + weight); } + // --- return SenseResult(weightedDir, totalWeight); } diff --git a/apps/typegpu-docs/tests/individual-example-tests/slime-mold.test.ts b/apps/typegpu-docs/tests/individual-example-tests/slime-mold.test.ts index 0c40c13cb7..fd91e929b6 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/slime-mold.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/slime-mold.test.ts @@ -89,104 +89,102 @@ describe('slime mold example', () => { var sum = vec3f(); var count = 0f; // unrolled iteration #0 + // unrolled iteration #0 / #0 { - // unrolled iteration #0 - { - let samplePos = (vec2i(gid.xy) + vec2i(-1)); - let dimsi = vec2i(dims); - if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - let color = textureLoad(oldState, vec2u(samplePos)).rgb; - sum += color; - count += 1f; - } + let samplePos = (vec2i(gid.xy) + vec2i(-1)); + let dimsi = vec2i(dims); + if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { + let color = textureLoad(oldState, vec2u(samplePos)).rgb; + sum += color; + count += 1f; } - // unrolled iteration #1 - { - let samplePos = (vec2i(gid.xy) + vec2i(0, -1)); - let dimsi = vec2i(dims); - if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - let color = textureLoad(oldState, vec2u(samplePos)).rgb; - sum += color; - count += 1f; - } + } + // unrolled iteration #0 / #1 + { + let samplePos = (vec2i(gid.xy) + vec2i(0, -1)); + let dimsi = vec2i(dims); + if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { + let color = textureLoad(oldState, vec2u(samplePos)).rgb; + sum += color; + count += 1f; } - // unrolled iteration #2 - { - let samplePos = (vec2i(gid.xy) + vec2i(1, -1)); - let dimsi = vec2i(dims); - if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - let color = textureLoad(oldState, vec2u(samplePos)).rgb; - sum += color; - count += 1f; - } + } + // unrolled iteration #0 / #2 + { + let samplePos = (vec2i(gid.xy) + vec2i(1, -1)); + let dimsi = vec2i(dims); + if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { + let color = textureLoad(oldState, vec2u(samplePos)).rgb; + sum += color; + count += 1f; } } + // --- // unrolled iteration #1 + // unrolled iteration #1 / #0 { - // unrolled iteration #0 - { - let samplePos = (vec2i(gid.xy) + vec2i(-1, 0)); - let dimsi = vec2i(dims); - if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - let color = textureLoad(oldState, vec2u(samplePos)).rgb; - sum += color; - count += 1f; - } + let samplePos = (vec2i(gid.xy) + vec2i(-1, 0)); + let dimsi = vec2i(dims); + if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { + let color = textureLoad(oldState, vec2u(samplePos)).rgb; + sum += color; + count += 1f; } - // unrolled iteration #1 - { - let samplePos = (vec2i(gid.xy) + vec2i()); - let dimsi = vec2i(dims); - if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - let color = textureLoad(oldState, vec2u(samplePos)).rgb; - sum += color; - count += 1f; - } + } + // unrolled iteration #1 / #1 + { + let samplePos = (vec2i(gid.xy) + vec2i()); + let dimsi = vec2i(dims); + if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { + let color = textureLoad(oldState, vec2u(samplePos)).rgb; + sum += color; + count += 1f; } - // unrolled iteration #2 - { - let samplePos = (vec2i(gid.xy) + vec2i(1, 0)); - let dimsi = vec2i(dims); - if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - let color = textureLoad(oldState, vec2u(samplePos)).rgb; - sum += color; - count += 1f; - } + } + // unrolled iteration #1 / #2 + { + let samplePos = (vec2i(gid.xy) + vec2i(1, 0)); + let dimsi = vec2i(dims); + if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { + let color = textureLoad(oldState, vec2u(samplePos)).rgb; + sum += color; + count += 1f; } } + // --- // unrolled iteration #2 + // unrolled iteration #2 / #0 { - // unrolled iteration #0 - { - let samplePos = (vec2i(gid.xy) + vec2i(-1, 1)); - let dimsi = vec2i(dims); - if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - let color = textureLoad(oldState, vec2u(samplePos)).rgb; - sum += color; - count += 1f; - } + let samplePos = (vec2i(gid.xy) + vec2i(-1, 1)); + let dimsi = vec2i(dims); + if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { + let color = textureLoad(oldState, vec2u(samplePos)).rgb; + sum += color; + count += 1f; } - // unrolled iteration #1 - { - let samplePos = (vec2i(gid.xy) + vec2i(0, 1)); - let dimsi = vec2i(dims); - if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - let color = textureLoad(oldState, vec2u(samplePos)).rgb; - sum += color; - count += 1f; - } + } + // unrolled iteration #2 / #1 + { + let samplePos = (vec2i(gid.xy) + vec2i(0, 1)); + let dimsi = vec2i(dims); + if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { + let color = textureLoad(oldState, vec2u(samplePos)).rgb; + sum += color; + count += 1f; } - // unrolled iteration #2 - { - let samplePos = (vec2i(gid.xy) + vec2i(1)); - let dimsi = vec2i(dims); - if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { - let color = textureLoad(oldState, vec2u(samplePos)).rgb; - sum += color; - count += 1f; - } + } + // unrolled iteration #2 / #2 + { + let samplePos = (vec2i(gid.xy) + vec2i(1)); + let dimsi = vec2i(dims); + if (((((samplePos.x >= 0i) && (samplePos.x < dimsi.x)) && (samplePos.y >= 0i)) && (samplePos.y < dimsi.y))) { + let color = textureLoad(oldState, vec2u(samplePos)).rgb; + sum += color; + count += 1f; } } + // --- + // --- let blurred = (sum / count); let newColor = saturate((blurred - params.evaporationRate)); textureStore(newState, gid.xy, vec4f(newColor, 1f)); @@ -260,9 +258,7 @@ describe('slime mold example', () => { let weightLeft = sense((*agent).position, (*agent).angle, params.sensorAngle); let weightRight = sense((*agent).position, (*agent).angle, -(params.sensorAngle)); var angle = (*agent).angle; - if (((weightForward > weightLeft) && (weightForward > weightRight))) { - - } + if (((weightForward > weightLeft) && (weightForward > weightRight))) {} else { if (((weightForward < weightLeft) && (weightForward < weightRight))) { angle = (angle + ((((random * 2f) - 1f) * params.turnSpeed) * deltaTime)); diff --git a/apps/typegpu-docs/tests/individual-example-tests/stable-fluid.test.ts b/apps/typegpu-docs/tests/individual-example-tests/stable-fluid.test.ts index 27477efbed..483bb3f4c2 100644 --- a/apps/typegpu-docs/tests/individual-example-tests/stable-fluid.test.ts +++ b/apps/typegpu-docs/tests/individual-example-tests/stable-fluid.test.ts @@ -59,21 +59,14 @@ describe('stable-fluid example', () => { fn getNeighbors(coords: vec2i, bounds: vec2i) -> array { var adjacentOffsets = array(vec2i(-1, 0), vec2i(0, -1), vec2i(1, 0), vec2i(0, 1)); // unrolled iteration #0 - { - adjacentOffsets[0i] = clamp((coords + adjacentOffsets[0i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[0i] = clamp((coords + adjacentOffsets[0i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #1 - { - adjacentOffsets[1i] = clamp((coords + adjacentOffsets[1i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[1i] = clamp((coords + adjacentOffsets[1i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #2 - { - adjacentOffsets[2i] = clamp((coords + adjacentOffsets[2i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[2i] = clamp((coords + adjacentOffsets[2i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #3 - { - adjacentOffsets[3i] = clamp((coords + adjacentOffsets[3i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[3i] = clamp((coords + adjacentOffsets[3i]), vec2i(), (bounds - vec2i(1))); + // --- return adjacentOffsets; } @@ -108,21 +101,14 @@ describe('stable-fluid example', () => { fn getNeighbors(coords: vec2i, bounds: vec2i) -> array { var adjacentOffsets = array(vec2i(-1, 0), vec2i(0, -1), vec2i(1, 0), vec2i(0, 1)); // unrolled iteration #0 - { - adjacentOffsets[0i] = clamp((coords + adjacentOffsets[0i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[0i] = clamp((coords + adjacentOffsets[0i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #1 - { - adjacentOffsets[1i] = clamp((coords + adjacentOffsets[1i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[1i] = clamp((coords + adjacentOffsets[1i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #2 - { - adjacentOffsets[2i] = clamp((coords + adjacentOffsets[2i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[2i] = clamp((coords + adjacentOffsets[2i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #3 - { - adjacentOffsets[3i] = clamp((coords + adjacentOffsets[3i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[3i] = clamp((coords + adjacentOffsets[3i]), vec2i(), (bounds - vec2i(1))); + // --- return adjacentOffsets; } @@ -145,21 +131,14 @@ describe('stable-fluid example', () => { fn getNeighbors(coords: vec2i, bounds: vec2i) -> array { var adjacentOffsets = array(vec2i(-1, 0), vec2i(0, -1), vec2i(1, 0), vec2i(0, 1)); // unrolled iteration #0 - { - adjacentOffsets[0i] = clamp((coords + adjacentOffsets[0i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[0i] = clamp((coords + adjacentOffsets[0i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #1 - { - adjacentOffsets[1i] = clamp((coords + adjacentOffsets[1i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[1i] = clamp((coords + adjacentOffsets[1i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #2 - { - adjacentOffsets[2i] = clamp((coords + adjacentOffsets[2i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[2i] = clamp((coords + adjacentOffsets[2i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #3 - { - adjacentOffsets[3i] = clamp((coords + adjacentOffsets[3i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[3i] = clamp((coords + adjacentOffsets[3i]), vec2i(), (bounds - vec2i(1))); + // --- return adjacentOffsets; } @@ -185,21 +164,14 @@ describe('stable-fluid example', () => { fn getNeighbors(coords: vec2i, bounds: vec2i) -> array { var adjacentOffsets = array(vec2i(-1, 0), vec2i(0, -1), vec2i(1, 0), vec2i(0, 1)); // unrolled iteration #0 - { - adjacentOffsets[0i] = clamp((coords + adjacentOffsets[0i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[0i] = clamp((coords + adjacentOffsets[0i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #1 - { - adjacentOffsets[1i] = clamp((coords + adjacentOffsets[1i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[1i] = clamp((coords + adjacentOffsets[1i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #2 - { - adjacentOffsets[2i] = clamp((coords + adjacentOffsets[2i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[2i] = clamp((coords + adjacentOffsets[2i]), vec2i(), (bounds - vec2i(1))); // unrolled iteration #3 - { - adjacentOffsets[3i] = clamp((coords + adjacentOffsets[3i]), vec2i(), (bounds - vec2i(1))); - } + adjacentOffsets[3i] = clamp((coords + adjacentOffsets[3i]), vec2i(), (bounds - vec2i(1))); + // --- return adjacentOffsets; } diff --git a/packages/typegpu-gl/src/glslGenerator.ts b/packages/typegpu-gl/src/glslGenerator.ts index 82850c284e..61531b8c81 100644 --- a/packages/typegpu-gl/src/glslGenerator.ts +++ b/packages/typegpu-gl/src/glslGenerator.ts @@ -155,6 +155,7 @@ export class GlslGenerator extends WgslGenerator { const block = super._block( [NODE.block, [...transformed.map((t) => t.assignment), [NODE.return]]], + /* allowInlining */ true, Object.fromEntries( transformed.map(({ name, snippet }) => { return [name, snippet.$] as const; @@ -162,7 +163,7 @@ export class GlslGenerator extends WgslGenerator { ), ); - return `${this.ctx.pre}${block}`; + return `${this.ctx.pre}${block.code}`; } else { // Resolving the expression to inspect it's type // We will resolve it again as part of the modifed statement @@ -178,10 +179,11 @@ export class GlslGenerator extends WgslGenerator { if (expr.dataType.type.startsWith('vec')) { const block = super._block( [NODE.block, [[NODE.assignmentExpr, 'gl_Position', '=', exprNode], [NODE.return]]], + /* allowInlining */ true, { gl_Position: gl_PositionSnippet.$ }, ); - return `${this.ctx.pre}${block}`; + return `${this.ctx.pre}${block.code}`; } } } @@ -205,7 +207,7 @@ export class GlslGenerator extends WgslGenerator { } try { - const body = this._block(options.body); + const body = this._block(options.body, /* allowInlining */ false).code; // Only after generating the body can we determine the return type const returnType = options.determineReturnType(); @@ -224,7 +226,7 @@ export class GlslGenerator extends WgslGenerator { } } } - return `void main() ${body}`; + return `void main() ${body || '{}'}`; } const argList = options.args diff --git a/packages/typegpu-gl/tests/glslGenerator.test.ts b/packages/typegpu-gl/tests/glslGenerator.test.ts index e72a8d7d03..1691995e0d 100644 --- a/packages/typegpu-gl/tests/glslGenerator.test.ts +++ b/packages/typegpu-gl/tests/glslGenerator.test.ts @@ -210,11 +210,8 @@ describe('GlslGenerator - entry point generation with JS functions', () => { void main() { vec4 position = vec4(); vec2 uv = vec2(); - { - gl_Position = position; - uv_1 = uv; - return; - } + gl_Position = position; + uv_1 = uv; }" `); }); @@ -238,10 +235,7 @@ describe('GlslGenerator - entry point generation with JS functions', () => { expect(result.code).toMatchInlineSnapshot(` "void main() { int gl_Position_1 = 1; - { - gl_Position = vec4(1, 0, 0, 1); - return; - } + gl_Position = vec4(1, 0, 0, 1); }" `); }); diff --git a/packages/typegpu/src/resolutionCtx.ts b/packages/typegpu/src/resolutionCtx.ts index 4d234a8eb6..368e20335f 100644 --- a/packages/typegpu/src/resolutionCtx.ts +++ b/packages/typegpu/src/resolutionCtx.ts @@ -110,6 +110,21 @@ class ItemStateStackImpl implements ItemStateStack { return this._stack.findLast((e) => e.type === 'blockScope'); } + get blockDepth(): number { + let depth = 0; + for (let i = this._stack.length - 1; i >= 0; --i) { + const layer = this._stack[i]; + if (layer?.type === 'functionScope') { + break; + } + if (layer?.type === 'blockScope') { + depth++; + } + } + + return depth; + } + pushItem() { this._itemDepth++; this._stack.push({ @@ -495,6 +510,10 @@ export class ResolutionCtxImpl implements ResolutionCtx { return this.#namespaceInternal.shelllessRepo; } + get blockDepth(): number { + return this._itemStateStack.blockDepth; + } + indent(): string { return this._indentController.indent(); } diff --git a/packages/typegpu/src/tgsl/generationHelpers.ts b/packages/typegpu/src/tgsl/generationHelpers.ts index 3eb4d37b56..f37fdc4c98 100644 --- a/packages/typegpu/src/tgsl/generationHelpers.ts +++ b/packages/typegpu/src/tgsl/generationHelpers.ts @@ -75,6 +75,7 @@ export type GenerationCtx = ResolutionCtx & { readonly topFunctionScope: FunctionScopeLayer | undefined; readonly topFunctionReturnType: BaseData | undefined; + readonly blockDepth: number; indent(): string; dedent(): string; diff --git a/packages/typegpu/src/tgsl/wgslGenerator.ts b/packages/typegpu/src/tgsl/wgslGenerator.ts index 60a3cdb723..12fe1d96c4 100644 --- a/packages/typegpu/src/tgsl/wgslGenerator.ts +++ b/packages/typegpu/src/tgsl/wgslGenerator.ts @@ -208,10 +208,26 @@ const usageToVarTemplateMap: Record readonly: 'storage, read', }; +interface ResolvedStatement { + code: string; + /** + * True if the statement (or statements) in `code` define variables that would + * be scoped to the nearest block. + */ + definesInNearestScope?: boolean | undefined; + /** + * If not undefined, the execution of the statement (or statements) in `code` + * results in jumping to another part of the code. This information can be + * used to prune unreachable statements. + */ + controlFlow?: 'return' | 'break' | 'continue' | undefined; +} + export class WgslGenerator implements ShaderGenerator { #ctx: GenerationCtx | undefined = undefined; - // used to detect `continue` and `break` nodes in loop body - #unrolling = false; + // used to detect `continue` and `break` nodes in loop body, as well as label + // unrolled blocks with comments + #unrollingChain: number[] = []; public initGenerator(ctx: GenerationCtx) { this.#ctx = ctx; @@ -226,33 +242,71 @@ export class WgslGenerator implements ShaderGenerator { return this.#ctx; } - protected _block([_, statements]: tinyest.Block, externalMap?: ExternalMap): string { + protected _block( + [_, statementNodes]: tinyest.Block, + allowInlining: boolean, + externalMap?: ExternalMap, + ): ResolvedStatement { this.ctx.pushBlockScope(); - if (externalMap) { - const externals = Object.fromEntries( - Object.entries(externalMap).map(([id, value]) => [id, coerceToSnippet(value)]), - ); - this.ctx.setBlockExternals(externals); - } - try { + if (externalMap) { + const externals = Object.fromEntries( + Object.entries(externalMap).map(([id, value]) => [id, coerceToSnippet(value)]), + ); + this.ctx.setBlockExternals(externals); + } + + let body = ''; + /** + * True if any of the statements in the block define variables that would + * be scoped to the currently generated block. If not, we can safely inline it. + */ + let definesInNearestScope = false; + let controlFlow: ResolvedStatement['controlFlow']; this.ctx.indent(); - const body = statements - .map((statement) => this._statement(statement)) - .filter((statement) => statement.length > 0) - .join('\n'); + for (const statementNode of statementNodes) { + const statement = this._statement(statementNode); + if (statement.code.length > 0) { + body += `${statement.code}\n`; + } + definesInNearestScope ||= statement.definesInNearestScope ?? false; + if (statement.controlFlow !== undefined) { + controlFlow = statement.controlFlow; + break; + } + } this.ctx.dedent(); - return `{ -${body} -${this.ctx.pre}}`; + + const willInline = allowInlining && !definesInNearestScope; + + if (willInline ? this.ctx.blockDepth <= 3 : this.ctx.blockDepth <= 2) { + body = body.replace(/[ ]*return;\s*$/, ''); + } + + if (body === '') { + return { code: '', controlFlow }; + } + + if (willInline) { + return { code: body.trim().replaceAll('\n ', '\n'), controlFlow }; + } + + return { + code: `{\n${body}${this.ctx.pre}}`, + controlFlow, + }; } finally { this.ctx.popBlockScope(); } } - protected _blockStatement(block: tinyest.Block, externalMap?: ExternalMap): string { - return `${this.ctx.pre}${this._block(block, externalMap)}`; + protected _blockStatement(block: tinyest.Block, externalMap?: ExternalMap): ResolvedStatement { + const { code, controlFlow } = this._block(block, /* allowInlining */ true, externalMap); + if (code === '') { + return { code: '', controlFlow }; + } + return { code: `${this.ctx.pre}${code}`, controlFlow }; } public refVariable(id: string, dataType: wgsl.StorableData): string { @@ -949,7 +1003,8 @@ ${this.ctx.pre}}`; public functionDefinition(options: FunctionDefinitionOptions): string { // Function body - let body = this._block(options.body); + invariant(this.ctx.blockDepth === 1, 'Expecting only one block at the start of a function'); + let body = this._block(options.body, /* allowInlining */ false); const scope = this.ctx.topFunctionScope; invariant(scope, 'Expected function scope to be present'); const replacements = Object.fromEntries( @@ -960,7 +1015,7 @@ ${this.ctx.pre}}`; ); if (Object.keys(replacements).length > 0) { const regex = new RegExp(Object.keys(replacements).join('|'), 'gi'); - body = body.replace( + body.code = body.code.replace( regex, (match) => replacements[match as keyof typeof replacements] ?? '#ERR', ); @@ -994,7 +1049,7 @@ ${this.ctx.pre}}`; attributes = `@fragment `; } - return `${attributes}fn ${options.name}${head}${body}`; + return `${attributes}fn ${options.name}${head}${body.code || '{}'}`; } /** @@ -1130,7 +1185,7 @@ Try 'return ${typeStr}(${str});' instead. return `${this.ctx.pre}return;`; } - protected _letStatement(statement: tinyest.Let): string { + protected _letStatement(statement: tinyest.Let): ResolvedStatement { const [_, rawId, eqNode] = statement; if (eqNode === undefined) { @@ -1197,10 +1252,13 @@ Try 'return ${typeStr}(${str});' instead. const emittedVarType = `#VAR_${scope.placeholderForVariable.size}#` as const; scope.placeholderForVariable.set(snippet, emittedVarType); - return this._emitVarDecl(emittedVarType, snippet.value, concreteType, rhsStr); + return { + code: this._emitVarDecl(emittedVarType, snippet.value, concreteType, rhsStr), + definesInNearestScope: true, + }; } - protected _constStatement(statement: tinyest.Const) { + protected _constStatement(statement: tinyest.Const): ResolvedStatement { const [_, rawId, eqNode] = statement; if (eqNode === undefined) { @@ -1223,12 +1281,15 @@ Try 'return ${typeStr}(${str});' instead. rawId, concretize(refSnippet.dataType as wgsl.BaseData) as wgsl.StorableData, ); - return stitch`${this.ctx.pre}var ${varName} = ${tryConvertSnippet( - this.ctx, - refSnippet, - refSnippet.dataType as wgsl.AnyWgslData, - false, - )};`; + return { + code: stitch`${this.ctx.pre}var ${varName} = ${tryConvertSnippet( + this.ctx, + refSnippet, + refSnippet.dataType as wgsl.AnyWgslData, + false, + )};`, + definesInNearestScope: true, + }; } const rhsNaturallyEphemeral = wgsl.isNaturallyEphemeral(eq.dataType); @@ -1314,23 +1375,26 @@ Try 'return ${typeStr}(${str});' instead. emittedVarType = varType; } - return this._emitVarDecl(emittedVarType, snippet.value, concreteType, rhsStr); + return { + code: this._emitVarDecl(emittedVarType, snippet.value, concreteType, rhsStr), + definesInNearestScope: true, + }; } - protected _statement(statement: tinyest.Statement): string { + protected _statement(statement: tinyest.Statement): ResolvedStatement { if (typeof statement === 'string') { const id = this._identifier(statement); const resolved = id.value !== undefined && id.value !== null ? this.ctx.resolveSnippet(id).value : ''; - return resolved ? `${this.ctx.pre}${resolved};` : ''; + return { code: resolved ? `${this.ctx.pre}${resolved};` : '' }; } if (typeof statement === 'boolean') { - return `${this.ctx.pre}${statement ? 'true' : 'false'};`; + return { code: `${this.ctx.pre}${statement ? 'true' : 'false'};` }; } if (statement[0] === NODE.return) { - return this._return(statement); + return { code: this._return(statement), controlFlow: 'return' }; } if (statement[0] === NODE.if) { @@ -1341,7 +1405,7 @@ Try 'return ${typeStr}(${str});' instead. // the condition is known at comptime let node = condition.value ? consNode : altNode; if (node === undefined) { - return ''; + return { code: '' }; } if (!Array.isArray(node)) { node = blockifySingleStatement(node); @@ -1358,16 +1422,20 @@ Try 'return ${typeStr}(${str});' instead. return this._blockStatement(blockifySingleStatement(node)); } - const consequent = this._block(blockifySingleStatement(consNode)); - const alternate = !altNode ? undefined : this._block(blockifySingleStatement(altNode)); + const consequent = this._block(blockifySingleStatement(consNode), /* allowInlining */ false); + const alternate = !altNode + ? undefined + : this._block(blockifySingleStatement(altNode), /* allowInlining */ false).code; if (!alternate) { - return stitch`${this.ctx.pre}if (${condition}) ${consequent}`; + return { code: stitch`${this.ctx.pre}if (${condition}) ${consequent.code || '{}'}` }; } - return stitch`\ -${this.ctx.pre}if (${condition}) ${consequent} -${this.ctx.pre}else ${alternate}`; + return { + code: stitch`\ +${this.ctx.pre}if (${condition}) ${consequent.code || '{}'} +${this.ctx.pre}else ${alternate}`, + }; } if (statement[0] === NODE.let) { @@ -1384,42 +1452,44 @@ ${this.ctx.pre}else ${alternate}`; if (statement[0] === NODE.for) { const [_, init, condition, update, body] = statement; - const prevUnrollingFlag = this.#unrolling; - this.#unrolling = false; + const prevUnrollingChain = this.#unrollingChain; + this.#unrollingChain = []; try { this.ctx.pushBlockScope(); const [initStatement, conditionExpr, updateStatement] = this.ctx.withResetIndentLevel( () => [ - init ? this._statement(init) : undefined, + init ? this._statement(init).code : undefined, condition ? this._typedExpression(condition, bool) : undefined, - update ? this._statement(update) : undefined, + update ? this._statement(update).code : 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}`; + const bodyStr = this._block(blockifySingleStatement(body), /* allowInlining */ false).code; + return { + code: stitch`${this.ctx.pre}for (${initStr}; ${conditionExpr}; ${updateStr}) ${bodyStr || '{}'}`, + }; } finally { - this.#unrolling = prevUnrollingFlag; + this.#unrollingChain = prevUnrollingChain; this.ctx.popBlockScope(); } } if (statement[0] === NODE.while) { - const prevUnrollingFlag = this.#unrolling; - this.#unrolling = false; + const prevUnrollingChain = this.#unrollingChain; + this.#unrollingChain = []; try { const [_, condition, body] = statement; const condSnippet = this._typedExpression(condition, bool); const conditionStr = this.ctx.resolveSnippet(condSnippet).value; - const bodyStr = this._block(blockifySingleStatement(body)); - return `${this.ctx.pre}while (${conditionStr}) ${bodyStr}`; + const bodyStr = this._block(blockifySingleStatement(body), /* allowInlining */ false).code; + return { code: `${this.ctx.pre}while (${conditionStr}) ${bodyStr || '{}'}` }; } finally { - this.#unrolling = prevUnrollingFlag; + this.#unrollingChain = prevUnrollingChain; } } @@ -1433,7 +1503,7 @@ ${this.ctx.pre}else ${alternate}`; this.tryMarkModified(iterable); // overly-defensive, but let's not tempt fate let ctxIndent = false; - const prevUnrollingFlag = this.#unrolling; + const prevUnrollingChain = this.#unrollingChain; try { this.ctx.pushBlockScope(); @@ -1449,11 +1519,9 @@ ${this.ctx.pre}else ${alternate}`; throw new Error('Cannot unroll loop. Length of iterable is unknown at comptime.'); } - this.#unrolling = true; - const length = range.end.value as number; if (length === 0) { - return ''; + return { code: '' }; } const { value } = iterableSnippet; @@ -1473,17 +1541,30 @@ ${this.ctx.pre}else ${alternate}`; ); } - const blocks = elements.map( - (e, i) => - `${this.ctx.pre}// unrolled iteration #${i}\n${this._blockStatement(blockified, { - [originalLoopVarName]: e, - })}`, - ); + let blocksCode = ''; + let controlFlow: ResolvedStatement['controlFlow']; + for (let i = 0; i < elements.length; i++) { + const e = elements[i]; + this.#unrollingChain = [...prevUnrollingChain, i]; + + const resolvedBlock = this._blockStatement(blockified, { + [originalLoopVarName]: e, + }); + + blocksCode += `${this.ctx.pre}// unrolled iteration ${this.#unrollingChain.map((idx) => `#${idx}`).join(' / ')}\n${ + resolvedBlock.code + }\n`; - return blocks.join('\n'); + if (resolvedBlock.controlFlow !== undefined) { + controlFlow = resolvedBlock.controlFlow; + break; + } + } + + return { code: `${blocksCode}${this.ctx.pre}// ---`, controlFlow }; } - this.#unrolling = false; + this.#unrollingChain = []; const index = this.ctx.makeUniqueIdentifier('i', 'block'); @@ -1492,9 +1573,9 @@ ${this.ctx.pre}else ${alternate}`; let bodyStr = ''; if (isTgpuRange(iterableSnippet.value)) { - bodyStr = this._block(blockified, { + bodyStr = this._block(blockified, /* allowInlining */ false, { [originalLoopVarName]: snip(index, range.start.dataType, 'runtime', false), // range.start, .end , .step have the same dataType - }); + }).code; } else { this.ctx.indent(); ctxIndent = true; @@ -1512,20 +1593,22 @@ ${this.ctx.pre}else ${alternate}`; false, )};`; - bodyStr = `{\n${loopVarDeclStr}\n${this._blockStatement(blockified, { - [originalLoopVarName]: snip(loopVarName, elementType, elementSnippet.origin, false), - })}\n`; + bodyStr = `{\n${loopVarDeclStr}\n${ + this._blockStatement(blockified, { + [originalLoopVarName]: snip(loopVarName, elementType, elementSnippet.origin, false), + }).code + }\n`; this.ctx.dedent(); bodyStr += `${this.ctx.pre}}`; ctxIndent = false; } - return stitch`${forHeaderStr} ${bodyStr.trim()}`; + return { code: stitch`${forHeaderStr} ${bodyStr.trim() || '{}'}` }; } finally { if (ctxIndent) { this.ctx.dedent(); } - this.#unrolling = prevUnrollingFlag; + this.#unrollingChain = prevUnrollingChain; this.ctx.popBlockScope(); } } @@ -1539,27 +1622,27 @@ ${this.ctx.pre}else ${alternate}`; validateSnippetMutation(argExpr, statement); this.tryMarkModified(arg); - return `${this.ctx.pre}${argStr}${op};`; + return { code: `${this.ctx.pre}${argStr}${op};` }; } if (statement[0] === NODE.continue) { - if (this.#unrolling) { + if (this.#unrollingChain.length > 0) { throw new WgslTypeError('Cannot unroll loop containing `continue`'); } - return `${this.ctx.pre}continue;`; + return { code: `${this.ctx.pre}continue;`, controlFlow: 'continue' }; } if (statement[0] === NODE.break) { - if (this.#unrolling) { + if (this.#unrollingChain.length > 0) { throw new WgslTypeError('Cannot unroll loop containing `break`'); } - return `${this.ctx.pre}break;`; + return { code: `${this.ctx.pre}break;`, controlFlow: 'break' }; } const expr = this._expression(statement); const resolved = expr.value !== undefined && expr.value !== null ? this.ctx.resolveSnippet(expr).value : ''; - return resolved ? `${this.ctx.pre}${resolved};` : ''; + return { code: resolved ? `${this.ctx.pre}${resolved};` : '' }; } /** diff --git a/packages/typegpu/tests/array.test.ts b/packages/typegpu/tests/array.test.ts index 6388ac0cfd..f3a4cdb6ef 100644 --- a/packages/typegpu/tests/array.test.ts +++ b/packages/typegpu/tests/array.test.ts @@ -213,7 +213,6 @@ describe('array', () => { let myClone = myArray; let myExternal = array(3u); f(myArray); - return; }" `); }); @@ -231,7 +230,6 @@ describe('array', () => { "fn testFn() { let myArrays = array, 1>(array(10i)); let myClone = myArrays[0i]; - return; }" `); }); @@ -246,7 +244,6 @@ describe('array', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { let arr = array(6f, 7f); - return; }" `); }); @@ -275,7 +272,6 @@ describe('array', () => { fn main() { let v1 = vec4f(7); f(v1); - return; }" `); }); @@ -290,7 +286,6 @@ describe('array', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() { let arr = array(5f, 6.7f, 8f); - return; }" `); }); diff --git a/packages/typegpu/tests/computePipeline.test.ts b/packages/typegpu/tests/computePipeline.test.ts index e39927a5a7..60ee7e4e2f 100644 --- a/packages/typegpu/tests/computePipeline.test.ts +++ b/packages/typegpu/tests/computePipeline.test.ts @@ -53,11 +53,9 @@ describe('TgpuComputePipeline', () => { compute: main, }); - expect(tgpu.resolve([computePipeline])).toMatchInlineSnapshot(` - "@compute @workgroup_size(32) fn main() { - - }" - `); + expect(tgpu.resolve([computePipeline])).toMatchInlineSnapshot( + `"@compute @workgroup_size(32) fn main() {}"`, + ); }); it('type checks passed bind groups', ({ root }) => { @@ -263,12 +261,8 @@ describe('TgpuComputePipeline', () => { @compute @workgroup_size(1) fn fn_1(@builtin(global_invocation_id) gid: vec3u) { var a = array(); - { - a[0i] = f16(gid.x); - } - { - a[1i] = 1h; - } + a[0i] = f16(gid.x); + a[1i] = 1h; }" `); }); diff --git a/packages/typegpu/tests/lazy.test.ts b/packages/typegpu/tests/lazy.test.ts index 39c9ae2d85..e61b52a412 100644 --- a/packages/typegpu/tests/lazy.test.ts +++ b/packages/typegpu/tests/lazy.test.ts @@ -93,17 +93,11 @@ describe('TgpuLazy', () => { .with(gridSizeSlot, 1); expect(tgpu.resolve([main])).toMatchInlineSnapshot(` - "fn fill(arr: array) { + "fn fill(arr: array) {} - } - - fn fill_1(arr: array) { - - } - - fn fill_2(arr: array) { + fn fill_1(arr: array) {} - } + fn fill_2(arr: array) {} fn main() { fill(array(1f)); diff --git a/packages/typegpu/tests/mutabilityTracking.test.ts b/packages/typegpu/tests/mutabilityTracking.test.ts index 513dad90cd..635d3ae132 100644 --- a/packages/typegpu/tests/mutabilityTracking.test.ts +++ b/packages/typegpu/tests/mutabilityTracking.test.ts @@ -132,9 +132,6 @@ describe('mutability tracking', () => { var a = arg.x; if ((a < 1u)) { a = 1u; - } - else { - } return a; }" @@ -291,12 +288,8 @@ describe('mutability tracking', () => { const resolved = tgpu.resolve([fn]); expect(resolved).toMatchInlineSnapshot(` "fn item(arg: vec4u) -> u32 { - for (var i = 0u; i < 3u; i += 1u) { - - } - for (var j = 0; (j < 3i); j++) { - - } + for (var i = 0u; i < 3u; i += 1u) {} + for (var j = 0; (j < 3i); j++) {} return 0u; }" `); @@ -542,9 +535,8 @@ describe('mutability tracking', () => { "fn item(arg: vec4u) -> u32 { var a = vec2u(); // unrolled iteration #0 - { - a.x += 1u; - } + a.x += 1u; + // --- return 0u; }" `); @@ -590,9 +582,7 @@ describe('mutability tracking', () => { var result = vec2f(); for (var i = 0u; i < 1u; i += 1u) { let v = (&t[i]); - { - result += (*v); - } + result += (*v); } }" `); diff --git a/packages/typegpu/tests/pipelineInit.test.ts b/packages/typegpu/tests/pipelineInit.test.ts index 5d76b08c7a..eba1e04279 100644 --- a/packages/typegpu/tests/pipelineInit.test.ts +++ b/packages/typegpu/tests/pipelineInit.test.ts @@ -12,11 +12,9 @@ describe('pipeline initialization', () => { pipeline.initSync(); expect(device.mock.createComputePipeline).toHaveBeenCalled(); - expect(tgpu.resolve([pipeline])).toMatchInlineSnapshot(` - "@compute @workgroup_size(1, 1, 1) fn computeFn() { - - }" - `); + expect(tgpu.resolve([pipeline])).toMatchInlineSnapshot( + `"@compute @workgroup_size(1, 1, 1) fn computeFn() {}"`, + ); }); }); @@ -28,11 +26,9 @@ describe('pipeline initialization', () => { expect(device.mock.createComputePipelineAsync).toHaveBeenCalled(); expect(() => root.unwrap(pipeline)).not.toThrow(); // this means that memo already exists - expect(tgpu.resolve([pipeline])).toMatchInlineSnapshot(` - "@compute @workgroup_size(1, 1, 1) fn computeFn() { - - }" - `); + expect(tgpu.resolve([pipeline])).toMatchInlineSnapshot( + `"@compute @workgroup_size(1, 1, 1) fn computeFn() {}"`, + ); expect(device.mock.createComputePipeline).not.toHaveBeenCalled(); }); @@ -81,9 +77,7 @@ describe('pipeline initialization', () => { expect(tgpu.resolve([pipeline.pipeline])).toMatchInlineSnapshot(` "@group(0) @binding(0) var sizeUniform: vec3u; - fn wrappedCallback(_arg_0: u32, _arg_1: u32, _arg_2: u32) { - - } + fn wrappedCallback(_arg_0: u32, _arg_1: u32, _arg_2: u32) {} @compute @workgroup_size(1, 1, 1) fn mainCompute(@builtin(global_invocation_id) id: vec3u) { if (any(id >= sizeUniform)) { @@ -108,9 +102,7 @@ describe('pipeline initialization', () => { expect(tgpu.resolve([pipeline.pipeline])).toMatchInlineSnapshot(` "@group(0) @binding(0) var sizeUniform: vec3u; - fn wrappedCallback(_arg_0: u32, _arg_1: u32, _arg_2: u32) { - - } + fn wrappedCallback(_arg_0: u32, _arg_1: u32, _arg_2: u32) {} @compute @workgroup_size(1, 1, 1) fn mainCompute(@builtin(global_invocation_id) id: vec3u) { if (any(id >= sizeUniform)) { diff --git a/packages/typegpu/tests/slot.test.ts b/packages/typegpu/tests/slot.test.ts index b8dc9283ec..c8a0691a7f 100644 --- a/packages/typegpu/tests/slot.test.ts +++ b/packages/typegpu/tests/slot.test.ts @@ -327,9 +327,7 @@ describe('tgpu.slot', () => { expect(tgpu.resolve([main.with(gammaCorrectionSlot, true)])).toMatchInlineSnapshot(` "fn main(uv: vec2f) -> vec3f { var color = vec3f(1, 0, 1); - { - color = pow(color, vec3f(0.4545454680919647)); - } + color = pow(color, vec3f(0.4545454680919647)); return color; }" `); @@ -438,9 +436,7 @@ describe('tgpu.slot', () => { expect(tgpu.resolve([getFloat])).toMatchInlineSnapshot(` "fn getFloat() -> f16 { - { - return 0h; - } + return 0h; }" `); }); diff --git a/packages/typegpu/tests/std/environment.test.ts b/packages/typegpu/tests/std/environment.test.ts index d47c26a4cd..36b5e639e2 100644 --- a/packages/typegpu/tests/std/environment.test.ts +++ b/packages/typegpu/tests/std/environment.test.ts @@ -20,9 +20,7 @@ describe('isBeingTranspiled', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { - { - return 7; - } + return 7; }" `); }); @@ -104,9 +102,7 @@ describe('getTargetShaderLanguage', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { - { - return 7; - } + return 7; }" `); }); diff --git a/packages/typegpu/tests/struct.test.ts b/packages/typegpu/tests/struct.test.ts index 142f9d995e..c5c48a4bf9 100644 --- a/packages/typegpu/tests/struct.test.ts +++ b/packages/typegpu/tests/struct.test.ts @@ -337,7 +337,6 @@ describe('struct', () => { fn testFn() { let myStruct = TestStruct(1u, 2f); let myClone = myStruct; - return; }" `); }); @@ -363,7 +362,6 @@ describe('struct', () => { fn testFn() { let myStructs = array(TestStruct(1u, 2f)); let myClone = myStructs[0i]; - return; }" `); }); @@ -632,9 +630,7 @@ describe('struct', () => { id: u32, } - fn helper(bird: Bird) { - - } + fn helper(bird: Bird) {} fn main() { let boid = Boid(); diff --git a/packages/typegpu/tests/tgsl/entryFnParamPruning.test.ts b/packages/typegpu/tests/tgsl/entryFnParamPruning.test.ts index b1928207a3..b73f0fc688 100644 --- a/packages/typegpu/tests/tgsl/entryFnParamPruning.test.ts +++ b/packages/typegpu/tests/tgsl/entryFnParamPruning.test.ts @@ -27,9 +27,7 @@ describe('entry function parameter pruning', () => { "@group(0) @binding(0) var output: array; @compute @workgroup_size(64) fn mainCompute(@builtin(global_invocation_id) gid: vec3u) { - { - output[gid.x] = 1f; - } + output[gid.x] = 1f; }" `); @@ -39,9 +37,7 @@ describe('entry function parameter pruning', () => { @group(0) @binding(0) var output: array; @compute @workgroup_size(64) fn mainCompute(@builtin(global_invocation_id) gid: vec3u, @builtin(subgroup_invocation_id) sgId: u32, @builtin(subgroup_size) sgSize: u32) { - { - output[((gid.x * sgSize) + sgId)] = 1f; - } + output[((gid.x * sgSize) + sgId)] = 1f; }" `); }); diff --git a/packages/typegpu/tests/tgsl/extensionEnabled.test.ts b/packages/typegpu/tests/tgsl/extensionEnabled.test.ts index 770e8a8574..8252871bdb 100644 --- a/packages/typegpu/tests/tgsl/extensionEnabled.test.ts +++ b/packages/typegpu/tests/tgsl/extensionEnabled.test.ts @@ -19,17 +19,13 @@ describe('extension based pruning', () => { "enable f16; fn someFn() -> f32 { - { - return 6.599609375f; - } + return 6.599609375f; }" `); expect(tgpu.resolve([someFn])).toMatchInlineSnapshot(` "fn someFn() -> f32 { - { - return 16.5f; - } + return 16.5f; }" `); }); diff --git a/packages/typegpu/tests/tgsl/ternaryOperator.test.ts b/packages/typegpu/tests/tgsl/ternaryOperator.test.ts index f6fa6bf61b..f370a38ca7 100644 --- a/packages/typegpu/tests/tgsl/ternaryOperator.test.ts +++ b/packages/typegpu/tests/tgsl/ternaryOperator.test.ts @@ -125,11 +125,7 @@ describe('ternary operator', () => { const myFunction = tgpu.fn([])(() => { false ? counter.$++ : undefined; }); - expect(tgpu.resolve([myFunction])).toMatchInlineSnapshot(` - "fn myFunction() { - - }" - `); + expect(tgpu.resolve([myFunction])).toMatchInlineSnapshot(`"fn myFunction() {}"`); }); it('should generate select() when branches are scalars', () => { diff --git a/packages/typegpu/tests/tgsl/typeInference.test.ts b/packages/typegpu/tests/tgsl/typeInference.test.ts index 63508d2bd8..2b4864868e 100644 --- a/packages/typegpu/tests/tgsl/typeInference.test.ts +++ b/packages/typegpu/tests/tgsl/typeInference.test.ts @@ -183,9 +183,7 @@ describe('wgsl generator type inference', () => { vel: vec2f, } - fn nop(p: Pos, b: Boid, a: array) { - return; - } + fn nop(p: Pos, b: Boid, a: array) {} fn myFn() { nop(Pos(1u, 2u), Boid(Pos(3u, 4u), vec2f()), array(Boid(Pos(5u, 6u), vec2f()))); @@ -357,9 +355,7 @@ describe('wgsl generator js type inference', () => { v: vec2f, } - fn myFn(_arg_0: MyStruct) { - return; - } + fn myFn(_arg_0: MyStruct) {} fn testFn() { myFn(MyStruct(vec2f(1, 2))); @@ -556,9 +552,7 @@ describe('wgsl generator js type inference', () => { vel: vec2f, } - fn nop(p: Pos, b: Boid, a: array) { - return; - } + fn nop(p: Pos, b: Boid, a: array) {} fn myFn() { nop(Pos(1u, 2u), Boid(Pos(3u, 4u), vec2f()), array(Boid(Pos(5u, 6u), vec2f()))); diff --git a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts index 828f40646c..8e6fe1eab1 100644 --- a/packages/typegpu/tests/tgsl/wgslGenerator.test.ts +++ b/packages/typegpu/tests/tgsl/wgslGenerator.test.ts @@ -174,9 +174,7 @@ describe('wgslGenerator', () => { var arr = array(1, 2, 3); for (var i = 0u; i < 3u; i += 1u) { let foo = arr[i]; - { - continue; - } + continue; } }" `); @@ -205,9 +203,7 @@ describe('wgslGenerator', () => { var res = 0f; for (var i = 0u; i < 3u; i += 1u) { let foo = arr[i]; - { - res += foo; - } + res += foo; } }" `); @@ -231,13 +227,9 @@ describe('wgslGenerator', () => { var res = 0f; for (var i = 0u; i < 3u; i += 1u) { let foo = arr[i]; - { - for (var i_1 = 0u; i_1 < 3u; i_1 += 1u) { - let boo = arr[i_1]; - { - res += (foo * boo); - } - } + for (var i_1 = 0u; i_1 < 3u; i_1 += 1u) { + let boo = arr[i_1]; + res += (foo * boo); } } }" @@ -262,13 +254,9 @@ describe('wgslGenerator', () => { var res = 0f; for (var i = 0u; i < 3u; i += 1u) { let foo = arr[i]; - { - for (var i_1 = 0u; i_1 < 3u; i_1 += 1u) { - let foo_1 = arr[i_1]; - { - res += (foo_1 * foo_1); - } - } + for (var i_1 = 0u; i_1 < 3u; i_1 += 1u) { + let foo_1 = arr[i_1]; + res += (foo_1 * foo_1); } } }" @@ -291,9 +279,7 @@ describe('wgslGenerator', () => { var res = 0; for (var i = 0u; i < 3u; i += 1u) { let foo = (&arr[i]); - { - res += i32((*foo).x); - } + res += i32((*foo).x); } }" `); @@ -319,9 +305,7 @@ describe('wgslGenerator', () => { var res = 0f; for (var i = 0u; i < arrayLength((&arr)); i += 1u) { let foo = arr[i]; - { - res += foo; - } + res += foo; } }" `); @@ -348,16 +332,12 @@ describe('wgslGenerator', () => { var v1 = vec4u(44, 88, 132, 176); for (var i = 0u; i < 4u; i += 1u) { let foo = v1[i]; - { - continue; - } + continue; } var v2 = vec2f(1, 2); for (var i = 0u; i < 2u; i += 1u) { let foo = v2[i]; - { - continue; - } + continue; } }" `); @@ -384,9 +364,7 @@ describe('wgslGenerator', () => { var result = 0u; for (var i = 0u; i < 7u; i += 1u) { let foo = b[i]; - { - result += foo; - } + result += foo; } return result; }" @@ -427,21 +405,15 @@ describe('wgslGenerator', () => { var res3 = false; for (var i = 0u; i < 4u; i += 1u) { let foo = v1[i]; - { - res1 += foo; - } + res1 += foo; } for (var i = 0u; i < 3u; i += 1u) { let foo = v2[i]; - { - res2 *= foo; - } + res2 *= foo; } for (var i = 0u; i < 2u; i += 1u) { let foo = v3[i]; - { - res3 = (foo != res3); - } + res3 = (foo != res3); } }" `); @@ -469,9 +441,7 @@ describe('wgslGenerator', () => { var testStruct = TestStruct(array(1f, 8f, 8f, 2f)); for (var i = 0u; i < 4u; i += 1u) { let foo = testStruct.arr[i]; - { - continue; - } + continue; } }" `); @@ -550,9 +520,7 @@ describe('wgslGenerator', () => { var arr = array(1, 2, 3); for (var i = 0u; i < 3u; i += 1u) { let item = arr[i]; - { - continue; - } + continue; } }" `); @@ -594,9 +562,7 @@ describe('wgslGenerator', () => { var arr = array(1, 2, 3); for (var i_1 = 0u; i_1 < 3u; i_1 += 1u) { let foo = arr[i_1]; - { - continue; - } + continue; } }" `); @@ -622,9 +588,7 @@ describe('wgslGenerator', () => { var arr = array(1u, 2u, 3u, i); for (var i_1 = 0u; i_1 < 4u; i_1 += 1u) { let foo = arr[i_1]; - { - continue; - } + continue; } }" `); @@ -703,9 +667,7 @@ describe('wgslGenerator', () => { var res = 0; for (var i = 0u; i < 3u; i += 1u) { let i_1 = arr[i]; - { - res += i_1; - } + res += i_1; } }" `); @@ -731,9 +693,7 @@ describe('wgslGenerator', () => { var res = 0; for (var i_1 = 0u; i_1 < 4u; i_1 += 1u) { let i_2 = arr[i_1]; - { - res += i32(i_2); - } + res += i32(i_2); } }" `); @@ -1215,11 +1175,9 @@ describe('wgslGenerator', () => { it('does not cause identifier clashes when renaming parameters', () => { const main = tgpu.fn([d.u32, d.u32])((extern, extern_1) => {}); - expect(tgpu.resolve([main])).toMatchInlineSnapshot(` - "fn main(extern_1: u32, extern_1_1: u32) { - - }" - `); + expect(tgpu.resolve([main])).toMatchInlineSnapshot( + `"fn main(extern_1: u32, extern_1_1: u32) {}"`, + ); }); it('generates correct code for pow expression', () => { @@ -1474,6 +1432,7 @@ describe('wgslGenerator', () => { let x = y; return x; } + // --- }" `); }); @@ -1492,6 +1451,7 @@ describe('wgslGenerator', () => { { const y = 1; } + // --- }" `); }); @@ -1514,11 +1474,8 @@ describe('wgslGenerator', () => { var result = 0i; var list = array(1); // unrolled iteration #0 - { - { - result += list[0u]; - } - } + result += list[0u]; + // --- }" `); }); @@ -1606,9 +1563,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([fn.with(vAccess, 0)])).toMatchInlineSnapshot(` "fn fn_1() -> i32 { var a = -1; - { - a = 0i; - } + a = 0i; return a; }" `); @@ -1616,9 +1571,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([fn.with(vAccess, 1)])).toMatchInlineSnapshot(` "fn fn_1() -> i32 { var a = -1; - { - a = 1i; - } + a = 1i; return a; }" `); @@ -1669,9 +1622,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([fn])).toMatchInlineSnapshot(` "fn fn_1() -> i32 { var a = -1; - { - a = 2i; - } + a = 2i; return a; }" `); @@ -1695,9 +1646,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([fn])).toMatchInlineSnapshot(` "fn fn_1() { var a = -1; - { - a = 2i; - } + a = 2i; }" `); }); @@ -1725,9 +1674,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([fn])).toMatchInlineSnapshot(` "fn fn_1() -> vec2f { var rayDir = vec2f(); - { - rayDir = vec2f(1, 0); - } + rayDir = vec2f(1, 0); return rayDir; }" `); @@ -1755,9 +1702,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([fn])).toMatchInlineSnapshot(` "fn fn_1() { var a = -1; - { - a = 3i; - } + a = 3i; }" `); }); @@ -1832,10 +1777,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { - { - return 1; - } - return -1; + return 1; }" `); }); @@ -1859,10 +1801,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { - { - return 1; - } - return -1; + return 1; }" `); }); @@ -2017,9 +1956,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { var res = -1; - { - res = 1i; - } + res = 1i; return res; }" `); @@ -2062,9 +1999,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { var res = -1; - { - res = 1i; - } + res = 1i; return res; }" `); @@ -2105,9 +2040,7 @@ describe('wgslGenerator', () => { expect(tgpu.resolve([f])).toMatchInlineSnapshot(` "fn f() -> i32 { var res = -1; - { - res = 1i; - } + res = 1i; return res; }" `); @@ -2185,4 +2118,72 @@ describe('wgslGenerator', () => { }" `); }); + + it('prunes based on early return', ({ root }) => { + const counter = tgpu.privateVar(d.u32); + function main() { + 'use gpu'; + const hello = 1 + 2; + if (true) { + return; + } + // This line will never be generated, meaning the private + // var `counter` will never be declared + counter.$++; + } + + expect(tgpu.resolve([main])).toMatchInlineSnapshot(` + "fn main() { + const hello = 3; + }" + `); + }); + + it('prunes based on early break', () => { + function main() { + 'use gpu'; + let value = d.u32(0); + for (let i = 0; i < 10; i++) { + value += i; + break; + value *= 2; + } + return value; + } + + expect(tgpu.resolve([main])).toMatchInlineSnapshot(` + "fn main() -> u32 { + var value = 0u; + for (var i = 0; (i < 10i); i++) { + value += u32(i); + break; + } + return value; + }" + `); + }); + + it('prunes based on early continue', () => { + function main() { + 'use gpu'; + let value = d.u32(0); + for (let i = 0; i < 10; i++) { + value += i; + continue; + value *= 2; + } + return value; + } + + expect(tgpu.resolve([main])).toMatchInlineSnapshot(` + "fn main() -> u32 { + var value = 0u; + for (var i = 0; (i < 10i); i++) { + value += u32(i); + continue; + } + return value; + }" + `); + }); }); diff --git a/packages/typegpu/tests/tgslFn.test.ts b/packages/typegpu/tests/tgslFn.test.ts index 2f71e3de9f..0012d3128f 100644 --- a/packages/typegpu/tests/tgslFn.test.ts +++ b/packages/typegpu/tests/tgslFn.test.ts @@ -1219,9 +1219,7 @@ describe('tgsl fn when using plugin', () => { }; expect(tgpu.resolve([fn])).toMatchInlineSnapshot(` - "fn item() { - - } + "fn item() {} fn fn_1() { item(); diff --git a/packages/typegpu/tests/unroll.test.ts b/packages/typegpu/tests/unroll.test.ts index 7eeed94fd0..7a9898f1d5 100644 --- a/packages/typegpu/tests/unroll.test.ts +++ b/packages/typegpu/tests/unroll.test.ts @@ -52,17 +52,12 @@ describe('tgpu.unroll', () => { "fn f() -> i32 { var res = 0; // unrolled iteration #0 - { - res += 1i; - } + res += 1i; // unrolled iteration #1 - { - res += 2i; - } + res += 2i; // unrolled iteration #2 - { - res += 3i; - } + res += 3i; + // --- return res; }" `); @@ -88,6 +83,7 @@ describe('tgpu.unroll', () => { { const boo = 2; } + // --- }" `); }); @@ -129,6 +125,7 @@ describe('tgpu.unroll', () => { } const bar = 2; } + // --- return fooResult; }" `); @@ -176,6 +173,7 @@ describe('tgpu.unroll', () => { res = (res + b2.vel); (*boo).pos = vec2i(); } + // --- return res; }" `); @@ -219,17 +217,12 @@ describe('tgpu.unroll', () => { "fn f() -> u32 { var result = 0u; // unrolled iteration #0 - { - result += 1u; - } + result += 1u; // unrolled iteration #1 - { - result += 2u; - } + result += 2u; // unrolled iteration #2 - { - result += 3u; - } + result += 3u; + // --- return result; }" `); @@ -284,13 +277,10 @@ describe('tgpu.unroll', () => { fn computeWeight(weights: Weights) -> f32 { var p = 0f; // unrolled iteration #0 - { - p += (weights.foo * foo(p)); - } + p += (weights.foo * foo(p)); // unrolled iteration #1 - { - p += (weights.boo * boo(p)); - } + p += (weights.boo * boo(p)); + // --- return p; }" `); @@ -328,6 +318,7 @@ describe('tgpu.unroll', () => { res = (res + v2); (*boo).x = 6f; } + // --- return res; }" `); @@ -348,21 +339,14 @@ describe('tgpu.unroll', () => { "fn f() -> u32 { var res = 0u; // unrolled iteration #0 - { - res += 1u; - } + res += 1u; // unrolled iteration #1 - { - res += 2u; - } + res += 2u; // unrolled iteration #2 - { - res += 3u; - } + res += 3u; // unrolled iteration #3 - { - res += 4u; - } + res += 4u; + // --- return res; }" `); @@ -387,17 +371,12 @@ describe('tgpu.unroll', () => { let v = vec3f(7); var res = 0; // unrolled iteration #0 - { - res = i32((f32(res) + v[0u])); - } + res = i32((f32(res) + v[0u])); // unrolled iteration #1 - { - res = i32((f32(res) + v[1u])); - } + res = i32((f32(res) + v[1u])); // unrolled iteration #2 - { - res = i32((f32(res) + v[2u])); - } + res = i32((f32(res) + v[2u])); + // --- return res; }" `); @@ -420,17 +399,12 @@ describe('tgpu.unroll', () => { "fn f() -> i32 { var result = 0; // unrolled iteration #0 - { - result += 1i; - } + result += 1i; // unrolled iteration #1 - { - result += 2i; - } + result += 2i; // unrolled iteration #2 - { - result += 3i; - } + result += 3i; + // --- return result; }" `); @@ -455,13 +429,10 @@ describe('tgpu.unroll', () => { fn f() -> vec3f { var result = vec3f(); // unrolled iteration #0 - { - result += arr[0u]; - } + result += arr[0u]; // unrolled iteration #1 - { - result += arr[1u]; - } + result += arr[1u]; + // --- return result; }" `); @@ -505,17 +476,12 @@ describe('tgpu.unroll', () => { var arr = array(1, 2, 3); var res = 0f; // unrolled iteration #0 - { - res += f32(arr[0u]); - } + res += f32(arr[0u]); // unrolled iteration #1 - { - res += f32(arr[1u]); - } + res += f32(arr[1u]); // unrolled iteration #2 - { - res += f32(arr[2u]); - } + res += f32(arr[2u]); + // --- return res; }" `); @@ -547,25 +513,18 @@ describe('tgpu.unroll', () => { var arr = array(v1, v2, v2, v3); var res = vec2f(); // unrolled iteration #0 - { - res = (res + arr[0u]); - arr[0u].x = 7f; - } + res = (res + arr[0u]); + arr[0u].x = 7f; // unrolled iteration #1 - { - res = (res + arr[1u]); - arr[1u].x = 7f; - } + res = (res + arr[1u]); + arr[1u].x = 7f; // unrolled iteration #2 - { - res = (res + arr[2u]); - arr[2u].x = 7f; - } + res = (res + arr[2u]); + arr[2u].x = 7f; // unrolled iteration #3 - { - res = (res + arr[3u]); - arr[3u].x = 7f; - } + res = (res + arr[3u]); + arr[3u].x = 7f; + // --- return res; }" `); @@ -604,15 +563,12 @@ describe('tgpu.unroll', () => { var arr = array(b1, b2); var res = vec2f(); // unrolled iteration #0 - { - res = (res + arr[0u].vel); - arr[0u].pos.x = 7i; - } + res = (res + arr[0u].vel); + arr[0u].pos.x = 7i; // unrolled iteration #1 - { - res = (res + arr[1u].vel); - arr[1u].pos.x = 7i; - } + res = (res + arr[1u].vel); + arr[1u].pos.x = 7i; + // --- return res; }" `); @@ -638,33 +594,20 @@ describe('tgpu.unroll', () => { fn f() -> u32 { var result = 0u; // unrolled iteration #0 - { - result += b[0u]; - } + result += b[0u]; // unrolled iteration #1 - { - result += b[1u]; - } + result += b[1u]; // unrolled iteration #2 - { - result += b[2u]; - } + result += b[2u]; // unrolled iteration #3 - { - result += b[3u]; - } + result += b[3u]; // unrolled iteration #4 - { - result += b[4u]; - } + result += b[4u]; // unrolled iteration #5 - { - result += b[5u]; - } + result += b[5u]; // unrolled iteration #6 - { - result += b[6u]; - } + result += b[6u]; + // --- return result; }" `); @@ -687,17 +630,12 @@ describe('tgpu.unroll', () => { var arr = array(1, 2, 3); var r = 0f; // unrolled iteration #0 - { - r += f32(arr[0u]); - } + r += f32(arr[0u]); // unrolled iteration #1 - { - r += f32(arr[1u]); - } + r += f32(arr[1u]); // unrolled iteration #2 - { - r += f32(arr[2u]); - } + r += f32(arr[2u]); + // --- }" `); expect(tgpu.resolve([tgpu.fn(f).with(unroll, false)])).toMatchInlineSnapshot(` @@ -706,9 +644,7 @@ describe('tgpu.unroll', () => { var r = 0f; for (var i = 0u; i < 3u; i += 1u) { let foo = arr[i]; - { - r += f32(foo); - } + r += f32(foo); } }" `); @@ -805,9 +741,7 @@ describe('tgpu.unroll', () => { } for (var i_1 = 0u; i_1 < 3u; i_1 += 1u) { let boo = arr[i_1]; - { - continue; - } + continue; } } // unrolled iteration #1 @@ -824,11 +758,10 @@ describe('tgpu.unroll', () => { } for (var i_1 = 0u; i_1 < 3u; i_1 += 1u) { let boo = arr[i_1]; - { - continue; - } + continue; } } + // --- }" `); }); @@ -887,21 +820,14 @@ describe('tgpu.unroll', () => { "fn f() -> f32 { var a = 0f; // unrolled iteration #0 - { - a += 1f; - } + a += 1f; // unrolled iteration #1 - { - a += 3f; - } + a += 3f; // unrolled iteration #2 - { - a += 5f; - } + a += 5f; // unrolled iteration #3 - { - a += 7f; - } + a += 7f; + // --- return a; }" `); @@ -954,21 +880,16 @@ describe('tgpu.unroll', () => { fn dynamicDispatch(fnIdx: i32, color: vec3f) -> vec3f { // unrolled iteration #0 - { - } // unrolled iteration #1 - { - if ((fnIdx == 1i)) { - return power(color); - } + if ((fnIdx == 1i)) { + return power(color); } // unrolled iteration #2 - { - if ((fnIdx == 2i)) { - return tanh_1(color); - } + if ((fnIdx == 2i)) { + return tanh_1(color); } + // --- return color; } @@ -977,4 +898,33 @@ describe('tgpu.unroll', () => { }" `); }); + + it('stops generating blocks when an early return is encountered', () => { + function main() { + 'use gpu'; + let result = d.u32(0); + for (const elem of tgpu.unroll(std.range(1, 10))) { + result += elem; + if (elem >= 3) { + return result; + } + } + // Should be unreachable + return result * 2; + } + + expect(tgpu.resolve([main])).toMatchInlineSnapshot(` + "fn main() -> u32 { + var result = 0u; + // unrolled iteration #0 + result += 1u; + // unrolled iteration #1 + result += 2u; + // unrolled iteration #2 + result += 3u; + return result; + // --- + }" + `); + }); }); diff --git a/packages/typegpu/tests/vector.test.ts b/packages/typegpu/tests/vector.test.ts index 772439ba98..2fe428b3f2 100644 --- a/packages/typegpu/tests/vector.test.ts +++ b/packages/typegpu/tests/vector.test.ts @@ -985,15 +985,11 @@ describe('type predicates', () => { expect(tgpu.resolve([main])).toMatchInlineSnapshot(` "fn ceil_1(input: vec3f) -> vec3i { - { - return vec3i(ceil(input)); - } + return vec3i(ceil(input)); } fn ceil_2(input: vec3i) -> vec3i { - { - return input; - } + return input; } fn main() {