|
1 | 1 | import { attest } from '@ark/attest'; |
2 | 2 | import { BufferReader, BufferWriter } from 'typed-binary'; |
3 | | -import { describe, expect, expectTypeOf, it } from 'vitest'; |
| 3 | +import { describe, expect, expectTypeOf } from 'vitest'; |
4 | 4 | import { readData, writeData } from '../src/data/dataIO.ts'; |
5 | 5 | import { d, tgpu } from '../src/index.js'; |
6 | 6 | import { namespace } from '../src/core/resolve/namespace.ts'; |
7 | 7 | import { resolve } from '../src/resolutionCtx.ts'; |
8 | 8 | import type { Infer } from '../src/shared/repr.ts'; |
9 | 9 | import { arrayLength } from '../src/std/array.ts'; |
| 10 | +import { it } from 'typegpu-testing-utility'; |
10 | 11 |
|
11 | 12 | describe('array', () => { |
12 | 13 | it('produces a visually pleasant type', () => { |
@@ -443,6 +444,100 @@ describe('array', () => { |
443 | 444 | }" |
444 | 445 | `); |
445 | 446 | }); |
| 447 | + |
| 448 | + it('array expressions can be indexed into with a comptime-known index', () => { |
| 449 | + function foo() { |
| 450 | + 'use gpu'; |
| 451 | + const i = 2; |
| 452 | + const a = [i, 2][0]; |
| 453 | + const b = [i, 2][1]; |
| 454 | + } |
| 455 | + |
| 456 | + expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` |
| 457 | + "fn foo() { |
| 458 | + const i = 2; |
| 459 | + const a = i; |
| 460 | + const b = 2i; |
| 461 | + }" |
| 462 | + `); |
| 463 | + }); |
| 464 | + |
| 465 | + it('array expressions can be indexed into with a runtime-known index', () => { |
| 466 | + function foo() { |
| 467 | + 'use gpu'; |
| 468 | + const i = 0; |
| 469 | + const a = [1, 2][i]; |
| 470 | + } |
| 471 | + |
| 472 | + expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` |
| 473 | + "fn foo() { |
| 474 | + const i = 0; |
| 475 | + let a = array<i32, 2>(1, 2)[i]; |
| 476 | + }" |
| 477 | + `); |
| 478 | + }); |
| 479 | + |
| 480 | + it('allows picking among references using comptime-known indices', () => { |
| 481 | + function foo() { |
| 482 | + 'use gpu'; |
| 483 | + const x = d.vec3f(1, 2, 3); |
| 484 | + // `const y = [x, d.vec3f()]` would throw, but since |
| 485 | + // we're never constructing the array, it's equivalent |
| 486 | + // to writing `const y = x;` |
| 487 | + const y = [x, d.vec3f()][0]; |
| 488 | + return y; |
| 489 | + } |
| 490 | + |
| 491 | + expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` |
| 492 | + "fn foo() -> vec3f { |
| 493 | + var x = vec3f(1, 2, 3); |
| 494 | + let y = (&x); |
| 495 | + return (*y); |
| 496 | + }" |
| 497 | + `); |
| 498 | + }); |
| 499 | + |
| 500 | + it('resolves array expression elements when accessed with comptime-known index', () => { |
| 501 | + let n = 0; |
| 502 | + const next = tgpu.comptime(() => n++); |
| 503 | + |
| 504 | + function foo() { |
| 505 | + 'use gpu'; |
| 506 | + const a = [next(), next()][0]; |
| 507 | + const b = [next(), next()][1]; |
| 508 | + } |
| 509 | + |
| 510 | + expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` |
| 511 | + "fn foo() { |
| 512 | + const a = 0; |
| 513 | + const b = 3; |
| 514 | + }" |
| 515 | + `); |
| 516 | + }); |
| 517 | + |
| 518 | + it('prunes definitions in array expressions accessed with comptime-known index', ({ root }) => { |
| 519 | + const u1 = root.createUniform(d.u32, 1); |
| 520 | + const u2 = root.createUniform(d.u32, 2); |
| 521 | + const u3 = root.createUniform(d.u32, 3); |
| 522 | + const u4 = root.createUniform(d.u32, 4); |
| 523 | + |
| 524 | + function foo() { |
| 525 | + 'use gpu'; |
| 526 | + const a = [u1.$, u2.$][0]; |
| 527 | + const b = [u3.$, u4.$][1]; |
| 528 | + } |
| 529 | + |
| 530 | + expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` |
| 531 | + "@group(0) @binding(0) var<uniform> u1: u32; |
| 532 | +
|
| 533 | + @group(0) @binding(1) var<uniform> u4: u32; |
| 534 | +
|
| 535 | + fn foo() { |
| 536 | + let a = u1; |
| 537 | + let b = u4; |
| 538 | + }" |
| 539 | + `); |
| 540 | + }); |
446 | 541 | }); |
447 | 542 |
|
448 | 543 | describe('array.length', () => { |
|
0 commit comments