1
1
import { BufferReader , BufferWriter } from 'typed-binary' ;
2
2
import { describe , expect , it } from 'vitest' ;
3
- import { arrayOf , sizeOf , vec3f , vec3u } from '../src/data' ;
3
+ import tgpu from '../src' ;
4
+ import * as d from '../src/data' ;
4
5
import { readData , writeData } from '../src/data/dataIO' ;
5
6
import { StrictNameRegistry } from '../src/nameRegistry' ;
6
7
import { resolve } from '../src/resolutionCtx' ;
7
8
import type { Infer } from '../src/shared/repr' ;
9
+ import { parse , parseResolved } from './utils/parseResolved' ;
8
10
9
11
describe ( 'array' , ( ) => {
10
12
it ( 'takes element alignment into account when measuring' , ( ) => {
11
- const TestArray = arrayOf ( vec3u , 3 ) ;
12
- expect ( sizeOf ( TestArray ) ) . toEqual ( 48 ) ;
13
+ const TestArray = d . arrayOf ( d . vec3u , 3 ) ;
14
+ expect ( d . sizeOf ( TestArray ) ) . toEqual ( 48 ) ;
13
15
} ) ;
14
16
15
17
it ( 'aligns array elements when writing' , ( ) => {
16
- const TestArray = arrayOf ( vec3u , 3 ) ;
17
- const buffer = new ArrayBuffer ( sizeOf ( TestArray ) ) ;
18
+ const TestArray = d . arrayOf ( d . vec3u , 3 ) ;
19
+ const buffer = new ArrayBuffer ( d . sizeOf ( TestArray ) ) ;
18
20
const writer = new BufferWriter ( buffer ) ;
19
21
20
22
writeData ( writer , TestArray , [
21
- vec3u ( 1 , 2 , 3 ) ,
22
- vec3u ( 4 , 5 , 6 ) ,
23
- vec3u ( 7 , 8 , 9 ) ,
23
+ d . vec3u ( 1 , 2 , 3 ) ,
24
+ d . vec3u ( 4 , 5 , 6 ) ,
25
+ d . vec3u ( 7 , 8 , 9 ) ,
24
26
] ) ;
25
27
expect ( [ ...new Uint32Array ( buffer ) ] ) . toEqual ( [
26
28
1 , 2 , 3 , 0 , 4 , 5 , 6 , 0 , 7 , 8 , 9 , 0 ,
27
29
] ) ;
28
30
} ) ;
29
31
30
32
it ( 'aligns array elements when reading' , ( ) => {
31
- const TestArray = arrayOf ( vec3u , 3 ) ;
32
- const buffer = new ArrayBuffer ( sizeOf ( TestArray ) ) ;
33
+ const TestArray = d . arrayOf ( d . vec3u , 3 ) ;
34
+ const buffer = new ArrayBuffer ( d . sizeOf ( TestArray ) ) ;
33
35
const reader = new BufferReader ( buffer ) ;
34
36
35
37
new Uint32Array ( buffer ) . set ( [ 1 , 2 , 3 , 0 , 4 , 5 , 6 , 0 , 7 , 8 , 9 , 0 ] ) ;
36
38
37
39
expect ( readData ( reader , TestArray ) ) . toEqual ( [
38
- vec3u ( 1 , 2 , 3 ) ,
39
- vec3u ( 4 , 5 , 6 ) ,
40
- vec3u ( 7 , 8 , 9 ) ,
40
+ d . vec3u ( 1 , 2 , 3 ) ,
41
+ d . vec3u ( 4 , 5 , 6 ) ,
42
+ d . vec3u ( 7 , 8 , 9 ) ,
41
43
] ) ;
42
44
} ) ;
43
45
44
46
it ( 'encodes and decodes arrays properly' , ( ) => {
45
- const TestArray = arrayOf ( vec3f , 5 ) ;
47
+ const TestArray = d . arrayOf ( d . vec3f , 5 ) ;
46
48
47
- const buffer = new ArrayBuffer ( sizeOf ( TestArray ) ) ;
49
+ const buffer = new ArrayBuffer ( d . sizeOf ( TestArray ) ) ;
48
50
49
51
const value : Infer < typeof TestArray > = [
50
- vec3f ( 1.5 , 2 , 3.5 ) ,
51
- vec3f ( ) ,
52
- vec3f ( - 1.5 , 2 , 3.5 ) ,
53
- vec3f ( 1.5 , - 2 , 3.5 ) ,
54
- vec3f ( 1.5 , 2 , 15 ) ,
52
+ d . vec3f ( 1.5 , 2 , 3.5 ) ,
53
+ d . vec3f ( ) ,
54
+ d . vec3f ( - 1.5 , 2 , 3.5 ) ,
55
+ d . vec3f ( 1.5 , - 2 , 3.5 ) ,
56
+ d . vec3f ( 1.5 , 2 , 15 ) ,
55
57
] ;
56
58
57
59
writeData ( new BufferWriter ( buffer ) , TestArray , value ) ;
58
60
expect ( readData ( new BufferReader ( buffer ) , TestArray ) ) . toEqual ( value ) ;
59
61
} ) ;
60
62
61
63
it ( 'throws when trying to read/write a runtime-sized array' , ( ) => {
62
- const TestArray = arrayOf ( vec3f , 0 ) ;
64
+ const TestArray = d . arrayOf ( d . vec3f , 0 ) ;
63
65
64
- expect ( sizeOf ( TestArray ) ) . toBeNaN ( ) ;
66
+ expect ( d . sizeOf ( TestArray ) ) . toBeNaN ( ) ;
65
67
66
68
expect ( ( ) =>
67
69
writeData ( new BufferWriter ( new ArrayBuffer ( 0 ) ) , TestArray , [
68
- vec3f ( ) ,
69
- vec3f ( ) ,
70
+ d . vec3f ( ) ,
71
+ d . vec3f ( ) ,
70
72
] ) ,
71
73
) . toThrow ( ) ;
72
74
@@ -80,6 +82,70 @@ describe('array', () => {
80
82
} ) ;
81
83
82
84
it ( 'throws when trying to nest runtime sized arrays' , ( ) => {
83
- expect ( ( ) => arrayOf ( arrayOf ( vec3f , 0 ) , 0 ) ) . toThrow ( ) ;
85
+ expect ( ( ) => d . arrayOf ( d . arrayOf ( d . vec3f , 0 ) , 0 ) ) . toThrow ( ) ;
86
+ } ) ;
87
+ } ) ;
88
+
89
+ describe ( 'array.length' , ( ) => {
90
+ it ( 'works for dynamically-sized arrays in TGSL' , ( ) => {
91
+ const layout = tgpu . bindGroupLayout ( {
92
+ values : {
93
+ storage : ( n : number ) => d . arrayOf ( d . f32 , n ) ,
94
+ access : 'mutable' ,
95
+ } ,
96
+ } ) ;
97
+
98
+ const foo = tgpu [ '~unstable' ] . fn ( [ ] ) . does ( ( ) => {
99
+ let acc = d . f32 ( 1 ) ;
100
+ for ( let i = 0 ; i < layout . bound . values . value . length ; i ++ ) {
101
+ layout . bound . values . value [ i ] = acc ;
102
+ acc *= 2 ;
103
+ }
104
+ } ) ;
105
+
106
+ expect ( parseResolved ( { foo } ) ) . toEqual (
107
+ parse ( /* wgsl */ `
108
+ @group(0) @binding(0) var <storage, read_write> values: array<f32>;
109
+
110
+ fn foo() {
111
+ var acc = f32(1);
112
+ for (var i = 0; (i < arrayLength(&values)); i++) {
113
+ values[i] = acc;
114
+ acc *= 2;
115
+ }
116
+ }
117
+ ` ) ,
118
+ ) ;
119
+ } ) ;
120
+
121
+ it ( 'works for statically-sized arrays in TGSL' , ( ) => {
122
+ const layout = tgpu . bindGroupLayout ( {
123
+ values : {
124
+ storage : d . arrayOf ( d . f32 , 128 ) ,
125
+ access : 'mutable' ,
126
+ } ,
127
+ } ) ;
128
+
129
+ const foo = tgpu [ '~unstable' ] . fn ( [ ] ) . does ( ( ) => {
130
+ let acc = d . f32 ( 1 ) ;
131
+ for ( let i = 0 ; i < layout . bound . values . value . length ; i ++ ) {
132
+ layout . bound . values . value [ i ] = acc ;
133
+ acc *= 2 ;
134
+ }
135
+ } ) ;
136
+
137
+ expect ( parseResolved ( { foo } ) ) . toEqual (
138
+ parse ( /* wgsl */ `
139
+ @group(0) @binding(0) var <storage, read_write> values: array<f32, 128>;
140
+
141
+ fn foo() {
142
+ var acc = f32(1);
143
+ for (var i = 0; (i < 128); i++) {
144
+ values[i] = acc;
145
+ acc *= 2;
146
+ }
147
+ }
148
+ ` ) ,
149
+ ) ;
84
150
} ) ;
85
151
} ) ;
0 commit comments