11import { describe , expect , it } from 'vitest' ;
22import tgpu , { d } from 'typegpu' ;
3- import glslGenerator , { translateWgslTypeToGlsl } from '../src/glslGenerator.ts' ;
3+ import { GLOptions } from '@typegpu/gl' ;
4+ import { translateWgslTypeToGlsl } from '../src/glslGenerator.ts' ;
45
56describe ( 'translateWgslTypeToGlsl' , ( ) => {
67 it ( 'translates scalar types' , ( ) => {
@@ -48,18 +49,14 @@ describe('translateWgslTypeToGlsl', () => {
4849
4950describe ( 'GlslGenerator - variable declarations' , ( ) => {
5051 it ( 'generates GLSL-style variable declarations for JS function' , ( ) => {
51- // 'use gpu' function - uses the TGSL code generation path, which calls functionDefinition
52- const fragFn = tgpu . fragmentFn ( {
53- in : { uv : d . vec2f } ,
54- out : d . vec4f ,
55- } ) ( ( input ) => {
52+ const main = ( ) => {
5653 'use gpu' ;
5754 // A variable that uses a vector type
58- const color = d . vec4f ( input . uv [ 0 ] , input . uv [ 1 ] , 0 , 1 ) ;
55+ const color = d . vec4f ( 1 , 0 , 0 , 1 ) ;
5956 return color ;
60- } ) ;
57+ } ;
6158
62- const result = tgpu . resolveWithContext ( [ fragFn ] , { unstable_shaderGenerator : glslGenerator } ) ;
59+ const result = tgpu . resolveWithContext ( [ main ] , GLOptions ( ) ) ;
6360 // Should contain the resolved function code
6461 expect ( result . code ) . toBeDefined ( ) ;
6562 expect ( result . code . length ) . toBeGreaterThan ( 0 ) ;
@@ -78,28 +75,38 @@ describe('GlslGenerator - variable declarations', () => {
7875 return d . vec4f ( x , 0 , 0 , 1 ) ;
7976 } ) ;
8077
81- const result = tgpu . resolveWithContext ( [ fragFn ] , { unstable_shaderGenerator : glslGenerator } ) ;
78+ const result = tgpu . resolveWithContext ( [ fragFn ] , GLOptions ( ) ) ;
8279 expect ( result . code ) . toBeDefined ( ) ;
8380 // Variable declaration for f32 should be `float`
8481 expect ( result . code ) . toContain ( 'float ' ) ;
8582 } ) ;
8683} ) ;
8784
88- describe ( 'GlslGenerator - functionDefinition post-processing' , ( ) => {
89- it ( 'translates WGSL type constructor calls in JS function body to GLSL' , ( ) => {
90- const fragFn = tgpu . fragmentFn ( {
91- in : { uv : d . vec2f } ,
92- out : d . vec4f ,
93- } ) ( ( input ) => {
85+ describe ( 'GlslGenerator - function definitions' , ( ) => {
86+ it ( 'generates proper function signatures' , ( ) => {
87+ function add ( a : number , b : number ) {
9488 'use gpu' ;
95- return d . vec4f ( input . uv [ 0 ] , 0.0 , 0.0 , 1.0 ) ;
96- } ) ;
89+ return a + b ;
90+ }
9791
98- const result = tgpu . resolveWithContext ( [ fragFn ] , { unstable_shaderGenerator : glslGenerator } ) ;
99- // vec4f(...) in the body should become vec4(...)
100- expect ( result . code ) . toContain ( 'vec4(' ) ;
101- // Should not contain the WGSL-style constructor in the body
102- expect ( result . code ) . not . toMatch ( / \b v e c 4 f \s * \( / ) ;
92+ function main ( ) {
93+ 'use gpu' ;
94+ return add ( 1.5 , 1.2 ) ;
95+ }
96+
97+ const result = tgpu . resolveWithContext ( [ main ] , GLOptions ( ) ) ;
98+
99+ expect ( result . code ) . toMatchInlineSnapshot ( `
100+ "#version 300 es
101+
102+ float add(float a, float b) {
103+ return (a + b);
104+ }
105+
106+ float main() {
107+ return add(1.5f, 1.2f);
108+ }"
109+ ` ) ;
103110 } ) ;
104111
105112 it ( 'translates vec3f to vec3 in function body' , ( ) => {
@@ -111,11 +118,46 @@ describe('GlslGenerator - functionDefinition post-processing', () => {
111118 return d . vec4f ( color [ 0 ] , color [ 1 ] , color [ 2 ] , 1.0 ) ;
112119 } ) ;
113120
114- const result = tgpu . resolveWithContext ( [ fragFn ] , { unstable_shaderGenerator : glslGenerator } ) ;
121+ const result = tgpu . resolveWithContext ( [ fragFn ] , GLOptions ( ) ) ;
115122 expect ( result . code ) . toContain ( 'vec3(' ) ;
116123 expect ( result . code ) . not . toMatch ( / \b v e c 3 f \s * \( / ) ;
117124 expect ( result . code ) . toContain ( 'vec4(' ) ;
118125 } ) ;
126+
127+ it ( 'generates proper struct definition' , ( ) => {
128+ const Boid = d . struct ( {
129+ pos : d . vec3f ,
130+ vel : d . vec3f ,
131+ } ) ;
132+
133+ function createBoid ( ) {
134+ 'use gpu' ;
135+ return Boid ( { pos : d . vec3f ( ) , vel : d . vec3f ( 0 , 1 , 0 ) } ) ;
136+ }
137+
138+ function main ( ) {
139+ 'use gpu' ;
140+ const boid = createBoid ( ) ;
141+ }
142+
143+ const result = tgpu . resolve ( [ main ] , GLOptions ( ) ) ;
144+ expect ( result ) . toMatchInlineSnapshot ( `
145+ "#version 300 es
146+
147+ struct Boid {
148+ vec3 pos;
149+ vec3 vel;
150+ };
151+
152+ Boid createBoid() {
153+ return Boid(vec3(), vec3(0, 1, 0));
154+ }
155+
156+ void main() {
157+ Boid boid = createBoid();
158+ }"
159+ ` ) ;
160+ } ) ;
119161} ) ;
120162
121163describe ( 'GlslGenerator - entry point generation with JS functions' , ( ) => {
@@ -127,41 +169,76 @@ describe('GlslGenerator - entry point generation with JS functions', () => {
127169 return Out ( { pos : d . vec4f ( 0.0 , 0.0 , 0.0 , 1.0 ) } ) ;
128170 } ) ;
129171
130- const result = tgpu . resolveWithContext ( [ vertFn ] , { unstable_shaderGenerator : glslGenerator } ) ;
172+ const result = tgpu . resolveWithContext ( [ vertFn ] , GLOptions ( ) ) ;
131173 expect ( result . code ) . toBeDefined ( ) ;
132174 expect ( result . code . length ) . toBeGreaterThan ( 0 ) ;
133175 // The body should have translated type names
134176 expect ( result . code ) . toContain ( 'vec4(' ) ;
135177 expect ( result . code ) . not . toMatch ( / \b v e c 4 f \s * \( / ) ;
136178
137179 expect ( result . code ) . toMatchInlineSnapshot ( `
138- "struct vertFn_Output {
139- @builtin(position) pos: vec4,
140- }
180+ "#version 300 es
141181
142- @vertex fn vertFn() -> vertFn_Output {
182+ struct vertFn_Output {
183+ vec4 pos;
184+ };
185+
186+ void main() {
143187 return vertFn_Output(vec4(0, 0, 0, 1));
144188 }"
145189 ` ) ;
146190 } ) ;
147191
192+ // it('resolves a vertex function returning a position', () => {
193+ // const vertFn = tgpu.vertexFn({
194+ // out: { position: d.builtin.position },
195+ // })(() => {
196+ // 'use gpu';
197+ // return {
198+ // position: d.vec4f(1.0, 0.0, 0.0, 1.0),
199+ // };
200+ // });
201+
202+ // const result = tgpu.resolveWithContext([vertFn], GLOptions());
203+ // expect(result.code).toBeDefined();
204+ // expect(result.code).toContain('vec4(');
205+ // expect(result.code).not.toMatch(/\bvec4f\s*\(/);
206+
207+ // expect(result.code).toMatchInlineSnapshot(`
208+ // "#version 300 es
209+
210+ // void main() {
211+ // gl_Position = vec4(1, 0, 0, 1);
212+ // return;
213+ // }"
214+ // `);
215+ // });
216+
148217 it ( 'resolves a fragment function returning a color using GLSL generator' , ( ) => {
149218 const fragFn = tgpu . fragmentFn ( {
150219 out : d . vec4f ,
151220 } ) ( ( ) => {
152221 'use gpu' ;
222+ // This variable should get renamed to not conflict with
223+ // the global.
224+ const gl_Position = 1 ;
153225 return d . vec4f ( 1.0 , 0.0 , 0.0 , 1.0 ) ;
154226 } ) ;
155227
156- const result = tgpu . resolveWithContext ( [ fragFn ] , { unstable_shaderGenerator : glslGenerator } ) ;
228+ const result = tgpu . resolveWithContext ( [ fragFn ] , GLOptions ( ) ) ;
157229 expect ( result . code ) . toBeDefined ( ) ;
158- // The body should have translated vec4f → vec4
159230 expect ( result . code ) . toContain ( 'vec4(' ) ;
160231 expect ( result . code ) . not . toMatch ( / \b v e c 4 f \s * \( / ) ;
161232
162233 expect ( result . code ) . toMatchInlineSnapshot ( `
163- "@fragment fn fragFn() -> @location(0) vec4 {
164- return vec4(1, 0, 0, 1);
234+ "#version 300 es
235+
236+ void main() {
237+ int gl_Position_1 = 1;
238+ {
239+ gl_Position = vec4(1, 0, 0, 1);
240+ return;
241+ }
165242 }"
166243 ` ) ;
167244 } ) ;
0 commit comments