makepad_shader_compiler/
generate_glsl.rs

1use {
2    std::{
3        fmt,
4        fmt::Write,
5        collections::BTreeSet,
6    },
7    crate::{
8        makepad_live_id::{
9            live_id,
10            LiveId,
11        },
12        generate::*,
13        swizzle::Swizzle,
14        shader_ast::*,
15        shader_registry::ShaderRegistry
16    }
17};
18
19pub fn generate_vertex_shader(draw_shader_def: &DrawShaderDef, const_table: &DrawShaderConstTable, shader_registry: &ShaderRegistry, options:GlslOptions) -> String {
20    let mut string = String::new();
21    DrawShaderGenerator {
22        draw_shader_def,
23        const_table,
24        shader_registry,
25        string: &mut string,
26        options,
27        backend_writer: &GlslBackendWriter {
28            options,
29            draw_shader_def,
30            shader_registry,
31            const_table
32        }
33    }
34    .generate_vertex_shader();
35    string
36}
37
38pub fn generate_pixel_shader(draw_shader_def: &DrawShaderDef, const_table: &DrawShaderConstTable, shader_registry: &ShaderRegistry, options:GlslOptions) -> String {
39    let mut string = String::new();
40    DrawShaderGenerator {
41        draw_shader_def,
42        const_table,
43        shader_registry,
44        string: &mut string,
45        options,
46        backend_writer: &GlslBackendWriter {
47            shader_registry, 
48            draw_shader_def,
49            const_table, 
50            options
51        }
52    }
53    .generate_pixel_shader();
54    string
55}
56
57struct DrawShaderGenerator<'a> {
58    draw_shader_def: &'a DrawShaderDef,
59    shader_registry: &'a ShaderRegistry,
60    string: &'a mut String,
61    const_table: &'a DrawShaderConstTable,
62    backend_writer: &'a dyn BackendWriter,
63    options: GlslOptions,
64}
65
66impl<'a> DrawShaderGenerator<'a> {
67    fn write_ty_init(&mut self, ty: &Ty) {
68        write!(
69            self.string,
70            "{}",
71            match ty {
72                Ty::Bool => "false",
73                Ty::Int => "0",
74                Ty::Float => "0.0",
75                Ty::Bvec2 => "bvec2(0)",
76                Ty::Bvec3 => "bvec3(0)",
77                Ty::Bvec4 => "bvec4(0)",
78                Ty::Ivec2 => "ivec2(0)",
79                Ty::Ivec3 => "ivec3(0)",
80                Ty::Ivec4 => "ivec4(0)",
81                Ty::Vec2 => "vec2(0.0)",
82                Ty::Vec3 => "vec3(0.0)",
83                Ty::Vec4 => "vec4(0.0)",
84                Ty::Mat2 => "mat2(0.0)",
85                Ty::Mat3 => "mat3(0.0)",
86                Ty::Mat4 => "mat4(0.0)",
87                Ty::Enum {..} => "0.0",
88                _ => panic!("unexpected as initializeable type {:?}", ty),
89            }
90        )
91            .unwrap()
92    }
93    
94    
95    fn generate_vertex_shader(&mut self) {
96        let packed_geometries_slots = self.compute_packed_geometries_slots();
97        let packed_instances_slots = self.compute_packed_instances_slots();
98        let packed_varyings_slots = self.compute_packed_varyings_slots();
99        self.generate_decls(
100            Some(packed_geometries_slots),
101            Some(packed_instances_slots),
102            packed_varyings_slots,
103            true
104        );
105        for field in &self.draw_shader_def.fields {
106            match field.kind {
107                DrawShaderFieldKind::Geometry {..} => {
108                    self.write_var_decl(
109                        &DisplayDsIdent(field.ident),
110                        field.ty_expr.ty.borrow().as_ref().unwrap(),
111                    );
112                    write!(self.string, "=").unwrap();
113                    self.write_ty_init(field.ty_expr.ty.borrow().as_ref().unwrap());
114                    writeln!(self.string, ";").unwrap();
115                }
116                DrawShaderFieldKind::Instance {..} => {
117                    self.write_var_decl(
118                        &DisplayDsIdent(field.ident),
119                        field.ty_expr.ty.borrow().as_ref().unwrap(),
120                    );
121                    write!(self.string, "=").unwrap();
122                    self.write_ty_init(field.ty_expr.ty.borrow().as_ref().unwrap());
123                    writeln!(self.string, ";").unwrap();
124                }
125                DrawShaderFieldKind::Varying {..} => {
126                    self.write_var_decl(
127                        &DisplayDsIdent(field.ident),
128                        field.ty_expr.ty.borrow().as_ref().unwrap(),
129                    );
130                    write!(self.string, "=").unwrap();
131                    self.write_ty_init(field.ty_expr.ty.borrow().as_ref().unwrap());
132                    writeln!(self.string, ";").unwrap();
133                }
134                _ => {}
135            }
136        }
137        
138        // we need to use the all_fns to compute our const table offsets.
139        
140        self.generate_shader_body(&self.draw_shader_def.vertex_fns.borrow(), &self.draw_shader_def.vertex_structs.borrow());
141        
142        writeln!(self.string, "void main() {{").unwrap();
143        
144        self.generate_uniform_block_unpack();
145        self.generate_live_unpack();
146        
147        let mut geometry_unpacker = VarUnpacker::new(
148            "packed_geometry",
149            packed_geometries_slots,
150            &mut self.string,
151        );
152        
153        for decl in &self.draw_shader_def.fields {
154            match decl.kind {
155                DrawShaderFieldKind::Geometry {..} => {
156                    geometry_unpacker
157                        .unpack_var(decl.ident, decl.ty_expr.ty.borrow().as_ref().unwrap());
158                }
159                _ => {}
160            }
161        }
162        
163        let mut instance_unpacker = VarUnpacker::new(
164            "packed_instance",
165            packed_instances_slots,
166            &mut self.string,
167        );
168        for decl in &self.draw_shader_def.fields {
169            match decl.kind {
170                DrawShaderFieldKind::Instance {..} => {
171                    instance_unpacker
172                        .unpack_var(decl.ident, decl.ty_expr.ty.borrow().as_ref().unwrap());
173                }
174                _ => {}
175            }
176        }
177        write!(self.string, "\n").unwrap();
178        let vertex_def = self.shader_registry.draw_shader_method_decl_from_ident(self.draw_shader_def, Ident(live_id!(vertex))).unwrap();
179        
180        writeln!(self.string, "    gl_Position = {}();", DisplayFnName(vertex_def.fn_ptr, vertex_def.ident)).unwrap();
181        write!(self.string, "\n").unwrap();
182        let mut varying_packer = VarPacker::new(
183            "packed_varying",
184            packed_varyings_slots,
185            &mut self.string,
186        );
187        for decl in &self.draw_shader_def.fields {
188            match &decl.kind {
189                DrawShaderFieldKind::Geometry {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
190                    varying_packer.pack_var(decl.ident, decl.ty_expr.ty.borrow().as_ref().unwrap());
191                }
192                DrawShaderFieldKind::Instance {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
193                    varying_packer.pack_var(decl.ident, decl.ty_expr.ty.borrow().as_ref().unwrap());
194                }
195                DrawShaderFieldKind::Varying {..} => {
196                    varying_packer.pack_var(decl.ident, decl.ty_expr.ty.borrow().as_ref().unwrap());
197                }
198                _ => {}
199            }
200        }
201        writeln!(self.string, "}}").unwrap();
202    }
203    
204    pub fn generate_shader_body(&mut self, fn_deps: &Vec<FnPtr>, struct_deps: &Vec<StructPtr>) {
205        
206        // alright so. we have our fn deps which have struct deps
207        // and we have struct deps in our struct deps.
208        let mut all_constructor_fns = BTreeSet::new();
209        
210        for callee in fn_deps.iter().rev() {
211            let decl = self.shader_registry.all_fns.get(callee).unwrap();
212            all_constructor_fns.extend(decl.constructor_fn_deps.borrow().as_ref().unwrap().iter().cloned());
213        }
214        
215        // all our live ref uniforms
216        //for (live_ref, ty) in self.draw_shader_def.all_live_refs.borrow().iter() {
217        //    self.generate_live_decl(*live_ref, ty);
218        //}
219        
220        // we have all the structs already from analyse
221        for struct_ptr in struct_deps.iter().rev() {
222            let struct_def = self.shader_registry.structs.get(struct_ptr).unwrap();
223            self.generate_struct_def(*struct_ptr, struct_def);
224        }
225        
226        for (ty_lit, param_tys) in all_constructor_fns {
227            generate_cons_fn(self.backend_writer, self.string, ty_lit, &param_tys);
228        }
229        write!(self.string, "\n").unwrap();
230        for fn_iter in fn_deps.iter().rev() {
231            let const_table_offset = self.const_table.offsets.get(fn_iter).cloned();
232            let fn_def = self.shader_registry.all_fns.get(fn_iter).unwrap();
233            if fn_def.has_closure_args() {
234                for call_iter in fn_deps.iter().rev() {
235                    // any function that depends on us, will have the closures we need
236                    let call_def = self.shader_registry.all_fns.get(call_iter).unwrap();
237                    if call_def.callees.borrow().as_ref().unwrap().contains(&fn_iter) {
238                        FnDefWithClosureArgsGenerator::generate_fn_def_with_all_closures(
239                            &mut self.string,
240                            self.shader_registry,
241                            fn_def,
242                            call_def,
243                            self.backend_writer,
244                            const_table_offset
245                        );
246                    }
247                }
248                continue
249            }
250            FnDefGenerator {
251                fn_def,
252                const_table_offset,
253                shader_registry: self.shader_registry,
254                backend_writer: self.backend_writer,
255                string: self.string,
256            }
257            .generate_fn_def();
258            write!(self.string, "\n").unwrap();
259        }
260    }
261    
262    pub fn generate_pixel_shader(&mut self) {
263        let packed_varyings_slots = self.compute_packed_varyings_slots();
264        self.generate_decls(None, None, packed_varyings_slots, false);
265        for field in &self.draw_shader_def.fields {
266            match &field.kind {
267                DrawShaderFieldKind::Geometry {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
268                    self.write_var_decl(
269                        &DisplayDsIdent(field.ident),
270                        field.ty_expr.ty.borrow().as_ref().unwrap(),
271                    );
272                    write!(self.string, "=").unwrap();
273                    self.write_ty_init(field.ty_expr.ty.borrow().as_ref().unwrap());
274                    writeln!(self.string, ";").unwrap();
275                }
276                DrawShaderFieldKind::Instance {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
277                    self.write_var_decl(
278                        &DisplayDsIdent(field.ident),
279                        field.ty_expr.ty.borrow().as_ref().unwrap(),
280                    );
281                    write!(self.string, "=").unwrap();
282                    self.write_ty_init(field.ty_expr.ty.borrow().as_ref().unwrap());
283                    writeln!(self.string, ";").unwrap();
284                }
285                DrawShaderFieldKind::Varying {..} => {
286                    self.write_var_decl(
287                        &DisplayDsIdent(field.ident),
288                        field.ty_expr.ty.borrow().as_ref().unwrap(),
289                    );
290                    write!(self.string, "=").unwrap();
291                    self.write_ty_init(field.ty_expr.ty.borrow().as_ref().unwrap());
292                    writeln!(self.string, ";").unwrap();
293                }
294                _ => {}
295            }
296        }
297        
298        self.generate_shader_body(&self.draw_shader_def.pixel_fns.borrow(), &self.draw_shader_def.pixel_structs.borrow());
299        
300        writeln!(self.string, "void main() {{").unwrap();
301        
302        self.generate_uniform_block_unpack();
303        self.generate_live_unpack();
304        
305        let mut varying_unpacker = VarUnpacker::new(
306            "packed_varying",
307            packed_varyings_slots,
308            &mut self.string,
309        );
310        
311        for decl in &self.draw_shader_def.fields {
312            match &decl.kind {
313                DrawShaderFieldKind::Geometry {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
314                    varying_unpacker
315                        .unpack_var(decl.ident, decl.ty_expr.ty.borrow().as_ref().unwrap());
316                }
317                DrawShaderFieldKind::Instance {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
318                    varying_unpacker
319                        .unpack_var(decl.ident, decl.ty_expr.ty.borrow().as_ref().unwrap());
320                }
321                DrawShaderFieldKind::Varying {..} => {
322                    varying_unpacker
323                        .unpack_var(decl.ident, decl.ty_expr.ty.borrow().as_ref().unwrap());
324                }
325                _ => {}
326            }
327        }
328        // we need to collect all consts
329        let pixel_decl = self.shader_registry.draw_shader_method_decl_from_ident(self.draw_shader_def, Ident(live_id!(fragment))).unwrap();
330        write!(self.string, "\n").unwrap();
331        if self.options.use_inout{
332            writeln!(self.string, "    fragColor = {}();", DisplayFnName(pixel_decl.fn_ptr, pixel_decl.ident)).unwrap();
333        }
334        else{
335            writeln!(self.string, "    gl_FragColor = {}();", DisplayFnName(pixel_decl.fn_ptr, pixel_decl.ident)).unwrap();
336        }
337        writeln!(self.string, "}}").unwrap();
338    }
339    
340    fn generate_uniform_block_unpack(
341        &mut self,
342    ) {
343        if self.options.use_uniform_buffers{
344            return
345        }
346        for (ident, vec) in self.draw_shader_def.fields_as_uniform_blocks() {
347            
348            let mut slots = 0;
349            
350            let table = format!("{}_table", ident);
351            
352            for (index, _item) in vec {
353                let field = &self.draw_shader_def.fields[index];
354                let ty_expr = field.ty_expr.ty.borrow();
355                if !self.draw_shader_def.ignore_idents.contains(&field.ident){
356                    // check if we have to unpack something else.
357                    write!(self.string, "    {} = ", &DisplayDsIdent(field.ident)).unwrap();
358                    self.write_uniform_ty_unpack(ty_expr.as_ref().unwrap(), &table, "", slots);
359                    write!(self.string, ";\n").unwrap();
360                }
361                slots += ty_expr.as_ref().unwrap().slots();
362            }
363            write!(self.string, "\n").unwrap();
364        }
365    }
366    
367    fn generate_live_unpack(
368        &mut self,
369    ) {
370        if self.options.use_uniform_buffers{
371            return
372        }
373        let mut slots = 0;
374        for (live_ref, ty) in self.draw_shader_def.all_live_refs.borrow().iter() {
375            
376            write!(self.string, "    {} = ", &live_ref).unwrap();
377            self.write_uniform_ty_unpack(ty, "live_table", "", slots);
378            write!(self.string, ";\n").unwrap();
379            slots += ty.slots();
380        }
381    }
382    
383    fn generate_decls(
384        &mut self,
385        packed_attributes_size: Option<usize>,
386        packed_instances_size: Option<usize>,
387        packed_varyings_size: usize,
388        is_vertex_shader: bool,
389    ) {
390        if self.const_table.table.len()>0 {
391            writeln!(self.string, "uniform float const_table[{}];", self.const_table.table.len()).unwrap()
392        }
393        write!(self.string, "\n").unwrap();
394        
395        let live_slots = self.calc_live_slots();
396        if live_slots >0 {
397            if self.options.use_uniform_buffers{
398                writeln!(self.string, "layout (std140) uniform liveUniforms{{").unwrap();
399                for (live_ref, ty) in self.draw_shader_def.all_live_refs.borrow().iter() {
400                    write!(self.string,"    ").unwrap();
401                    self.write_var_decl(live_ref, ty);
402                    writeln!(self.string, ";").unwrap();
403                    /*
404                    write!(self.string, " = ").unwrap();
405                    self.write_ty_init(ty);
406                    writeln!(self.string, ";").unwrap();
407                    */
408                }
409                writeln!(self.string, "}} lt;").unwrap();
410            }
411            else{
412                writeln!(self.string, "uniform float live_table[{}];", live_slots).unwrap();
413                        
414                for (live_ref, ty) in self.draw_shader_def.all_live_refs.borrow().iter() {
415                    self.write_var_decl(live_ref, ty);
416                    write!(self.string, " = ").unwrap();
417                    self.write_ty_init(ty);
418                    writeln!(self.string, ";").unwrap();
419                }
420            }
421        }
422        
423        for (ident, vec) in self.draw_shader_def.fields_as_uniform_blocks() {
424            let mut slots = 0;
425            
426            for (index, _item) in &vec {
427                let field = &self.draw_shader_def.fields[*index];
428                slots += field.ty_expr.ty.borrow().as_ref().unwrap().slots();
429            }
430            if self.options.use_uniform_buffers{
431                writeln!(self.string, "layout (std140) uniform {}Uniforms{{", ident).unwrap();
432                
433                for (index, _item) in vec {
434                    let field = &self.draw_shader_def.fields[index];
435                    if let DrawShaderFieldKind::Uniform {..} = &field.kind {
436                        //if !self.draw_shader_def.ignore_idents.contains(&field.ident){
437                            self.generate_uniform_block_decl(field);
438                            
439                        //}
440                    }
441                    else {
442                        panic!()
443                    }
444                }
445                writeln!(self.string, "}}{};", ident).unwrap();
446            }
447            else{
448                writeln!(self.string, "uniform float {}_table[{}];", ident, slots).unwrap();
449                                
450                for (index, _item) in vec {
451                    let field = &self.draw_shader_def.fields[index];
452                    if let DrawShaderFieldKind::Uniform {..} = &field.kind {
453                        if !self.draw_shader_def.ignore_idents.contains(&field.ident){
454                            self.generate_uniform_decl(field);
455                        }
456                    }
457                    else {
458                        panic!()
459                    }
460                }
461            }
462            write!(self.string, "\n").unwrap();
463        }
464        
465        for decl in &self.draw_shader_def.fields {
466            match decl.kind {
467                DrawShaderFieldKind::Texture {..} => self.generate_texture_decl(decl),
468                _ => {}
469            }
470        }
471        write!(self.string, "\n").unwrap();
472        
473        if let Some(packed_attributes_size) = packed_attributes_size {
474            self.generate_packed_var_decls(
475                if self.options.use_inout{"in"}else{"attribute"},
476                "packed_geometry",
477                packed_attributes_size,
478            );
479        }
480        write!(self.string, "\n").unwrap();
481        if let Some(packed_instances_size) = packed_instances_size {
482            self.generate_packed_var_decls(
483                if self.options.use_inout{"in"}else{"attribute"},
484                "packed_instance",
485                packed_instances_size,
486            );
487        }
488        write!(self.string, "\n").unwrap();
489        self.generate_packed_var_decls(
490            if self.options.use_inout{if is_vertex_shader{"out"}else{"in"}}else{"varying"},
491            "packed_varying", packed_varyings_size);
492        write!(self.string, "\n").unwrap();
493    }
494    
495    fn generate_struct_def(&mut self, struct_ptr: StructPtr, struct_def: &StructDef) {
496        write!(self.string, "struct {} {{", struct_ptr).unwrap();
497        if !struct_def.fields.is_empty() {
498            writeln!(self.string).unwrap();
499            for field in &struct_def.fields {
500                write!(self.string, "    ").unwrap();
501                self.write_var_decl(
502                    &DisplayStructField(field.ident),
503                    field.ty_expr.ty.borrow().as_ref().unwrap(),
504                );
505                writeln!(self.string, ";").unwrap();
506            }
507        }
508        writeln!(self.string, "}};").unwrap();
509    }
510    
511    fn generate_uniform_block_decl(&mut self, decl: &DrawShaderFieldDef) {
512        write!(self.string, "    ").unwrap();
513        if self.options.use_ovr_multiview{
514            if decl.ident == Ident(live_id!(camera_projection)) ||
515                decl.ident == Ident(live_id!(camera_view)) || 
516                decl.ident == Ident(live_id!(depth_projection)) || 
517                decl.ident == Ident(live_id!(depth_view)) 
518                {
519                self.write_var_decl(
520                    &decl.ident,//&DisplayDsIdent(decl.ident),e
521                    decl.ty_expr.ty.borrow().as_ref().unwrap(),
522                );
523                writeln!(self.string, "[2];").unwrap();
524                return
525            }
526            if decl.ident == Ident(live_id!(camera_projection_r)) ||
527                decl.ident == Ident(live_id!(camera_view_r)) || 
528                decl.ident == Ident(live_id!(depth_projection_r)) ||
529                decl.ident == Ident(live_id!(depth_view_r)){
530                return
531            }
532        }
533            
534        self.write_var_decl(
535            &decl.ident,//&DisplayDsIdent(decl.ident),
536            decl.ty_expr.ty.borrow().as_ref().unwrap(),
537        );
538        writeln!(self.string, ";").unwrap();
539    }
540    
541    fn generate_uniform_decl(&mut self, decl: &DrawShaderFieldDef) {
542        //write!(self.string, "uniform ").unwrap();
543        self.write_var_decl(
544            &DisplayDsIdent(decl.ident),
545            decl.ty_expr.ty.borrow().as_ref().unwrap(),
546        );
547        write!(self.string, " = ").unwrap();
548        self.write_ty_init(decl.ty_expr.ty.borrow().as_ref().unwrap());
549        writeln!(self.string, ";").unwrap();
550    }
551    
552    
553    pub fn calc_live_slots(&self) -> usize {
554        let mut slots = 0;
555        for (_, ty) in self.draw_shader_def.all_live_refs.borrow().iter() {
556            slots += ty.slots();
557        }
558        slots
559    }
560    
561    fn generate_texture_decl(&mut self, decl: &DrawShaderFieldDef) {
562        write!(self.string, "uniform ").unwrap();
563        self.write_var_decl(
564            &DisplayDsIdent(decl.ident),
565            decl.ty_expr.ty.borrow().as_ref().unwrap(),
566        );
567        writeln!(self.string, ";").unwrap();
568    }
569    
570    fn compute_packed_geometries_slots(&self) -> usize {
571        let mut packed_attributes_size = 0;
572        for field in &self.draw_shader_def.fields {
573            packed_attributes_size += match field.kind {
574                DrawShaderFieldKind::Geometry {..} => field.ty_expr.ty.borrow().as_ref().unwrap().slots(),
575                _ => 0,
576            }
577        }
578        packed_attributes_size
579    }
580    
581    fn compute_packed_instances_slots(&self) -> usize {
582        let mut packed_instances_size = 0;
583        for field in &self.draw_shader_def.fields {
584            packed_instances_size += match field.kind {
585                DrawShaderFieldKind::Instance {..} => field.ty_expr.ty.borrow().as_ref().unwrap().slots(),
586                _ => 0,
587            }
588        }
589        packed_instances_size
590    }
591    
592    fn compute_packed_varyings_slots(&self) -> usize {
593        let mut packed_varyings_size = 0;
594        for field in &self.draw_shader_def.fields {
595            packed_varyings_size += match &field.kind {
596                DrawShaderFieldKind::Geometry {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
597                    field.ty_expr.ty.borrow().as_ref().unwrap().slots()
598                }
599                DrawShaderFieldKind::Instance {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
600                    field.ty_expr.ty.borrow().as_ref().unwrap().slots()
601                }
602                DrawShaderFieldKind::Varying {..} => field.ty_expr.ty.borrow().as_ref().unwrap().slots(),
603                _ => 0,
604            }
605        }
606        packed_varyings_size
607    }
608    
609    fn generate_packed_var_decls(
610        &mut self,
611        packed_var_qualifier: &'a str,
612        packed_var_name: &'a str,
613        mut packed_vars_size: usize,
614    ) {
615        let mut packed_var_index = 0;
616        loop {
617            let packed_var_size = packed_vars_size.min(4);
618            writeln!(
619                self.string,
620                "{} {} {}_{};",
621                packed_var_qualifier,
622                match packed_var_size {
623                    0 => break,
624                    1 => "float",
625                    2 => "vec2",
626                    3 => "vec3",
627                    4 => "vec4",
628                    _ => panic!(),
629                },
630                packed_var_name,
631                packed_var_index,
632            )
633                .unwrap();
634            packed_vars_size -= packed_var_size;
635            packed_var_index += 1;
636        }
637    }
638    
639    fn write_uniform_ty_unpack(&mut self, ty: &Ty, prefix: &str, i:&str, s: usize) {
640        match ty {
641            Ty::Bool => write!(self.string, "{}[{}]>0.5?true:false", prefix, s),
642            Ty::Int => write!(self.string, "int({}[{}])", prefix, s),
643            Ty::Float => write!(self.string, "{}[{}]", prefix, s),
644            Ty::Bvec2 => write!(self.string, "bvec2({0}[{1}]>0.5?true:false, {0}[{2}]>0.5?true:false)", prefix, s, s + 1),
645            Ty::Bvec3 => write!(self.string, "bvec3({0}[{1}]>0.5?true:false, {0}[{2}]>0.5?true:false, {0}[{3}]>0.5?true:false)", prefix, s, s + 1, s + 2),
646            Ty::Bvec4 => write!(self.string, "bvec4({0}[{1}]>0.5?true:false, {0}[{2}]>0.5?true:false, {0}[{3}]>0.5?true:false, {0}[{4}]>0.5?true:false)", prefix, s, s + 1, s + 2, s + 3),
647            Ty::Ivec2 => write!(self.string, "ivec2(int({0}[{1}]), int({0}[{2}]))", prefix, s, s + 1),
648            Ty::Ivec3 => write!(self.string, "ivec3(int({0}[{1}]), int({0}[{2}]), int({0}[{3}]))", prefix, s, s + 1, s + 2),
649            Ty::Ivec4 => write!(self.string, "ivec4(int({0}[{1}]), int({0}[{2}]), int({0}[{3}]), int({0}[{4}]))", prefix, s, s + 1, s + 2, s + 3),
650            Ty::Vec2 => write!(self.string, "vec2({0}[{1}], {0}[{2}])", prefix, s, s + 1),
651            Ty::Vec3 => write!(self.string, "vec3({0}[{1}], {0}[{2}], {0}[{3}])", prefix, s, s + 1, s + 2),
652            Ty::Vec4 => write!(self.string, "vec4({0}[{1}], {0}[{2}], {0}[{3}], {0}[{4}])", prefix, s, s + 1, s + 2, s + 3),
653            Ty::Mat2 => write!(self.string, "mat2({0}[{1}], {0}[{2}], {0}[{3}], {0}[{4}])", prefix, s, s + 1, s + 2, s + 3),
654            Ty::Mat3 => write!(self.string, "mat3({0}[{1}], {0}[{2}], {0}[{3}], {0}[{4}], {0}[{5}], {0}[{6}], {0}[{7}], {0}[{8}], {0}[{9}])", prefix, s, s + 1, s + 2, s + 3, s + 4, s + 5, s + 6, s + 7, s + 8),
655            Ty::Mat4 => write!(self.string, "mat4({0}[{1}{i}], {0}[{2}{i}], {0}[{3}{i}], {0}[{4}{i}], {0}[{5}{i}], {0}[{6}{i}], {0}[{7}{i}], {0}[{8}{i}], {0}[{9}{i}], {0}[{10}{i}], {0}[{11}{i}], {0}[{12}{i}], {0}[{13}{i}], {0}[{14}{i}], {0}[{15}{i}], {0}[{16}{i}])", prefix, s, s + 1, s + 2, s + 3, s + 4, s + 5, s + 6, s + 7, s + 8, s + 9, s + 10, s + 11, s + 12, s + 13, s + 14, s + 15,),
656            //Ty::Mat4 => write!(self.string, "mat4({0}[{1}], {0}[{2}], {0}[{3}], {0}[{4}], {0}[{5}], {0}[{6}], {0}[{7}], {0}[{8}], {0}[{9}], {0}[{10}], {0}[{11}], {0}[{12}], {0}[{13}], {0}[{14}], {0}[{15}], {0}[{16}])", prefix, s, s + 4, s + 8, s + 12, s + 1, s + 5, s + 9, s + 13, s + 2, s + 6, s + 10, s + 14, s + 3, s + 7, s + 11, s + 15,),
657            Ty::Enum {..} => write!(self.string, "{}[{}]", prefix, s),
658            _ => panic!("unexpected as initializeable type {:?}", ty),
659        }.unwrap()
660    }
661    
662    fn generate_expr(&mut self, expr: &Expr) {
663        ExprGenerator {
664            fn_def: None,
665            shader_registry: self.shader_registry,
666            closure_site_info: None,
667            const_table_offset: None,
668            backend_writer: self.backend_writer,
669            string: self.string,
670        }
671        .generate_expr(expr)
672    }
673    
674    fn write_var_decl(&mut self, ident: &dyn fmt::Display, ty: &Ty) {
675        self.backend_writer.write_var_decl(&mut self.string, "", false, false, ident, ty);
676    }
677    
678    fn write_ty_lit(&mut self, ty_lit: TyLit) {
679        self.backend_writer.write_ty_lit(&mut self.string, ty_lit);
680    }
681}
682
683struct VarPacker<'a> {
684    packed_var_name: &'a str,
685    packed_vars_size: usize,
686    packed_var_index: usize,
687    packed_var_size: usize,
688    packed_var_offset: usize,
689    string: &'a mut String,
690}
691
692impl<'a> VarPacker<'a> {
693    fn new(
694        packed_var_name: &'a str,
695        packed_vars_size: usize,
696        string: &'a mut String,
697    ) -> VarPacker<'a> {
698        VarPacker {
699            packed_var_name,
700            packed_vars_size,
701            packed_var_index: 0,
702            packed_var_size: packed_vars_size.min(4),
703            packed_var_offset: 0,
704            string,
705        }
706    }
707    
708    fn pack_var(&mut self, ident: Ident, ty: &Ty) {
709        let var_slots = ty.slots();
710        let mut var_offset = 0;
711        let mut in_matrix = None;
712        while var_offset < var_slots {
713            let count = var_slots - var_offset;
714            let packed_count = self.packed_var_size - self.packed_var_offset;
715            let min_count = if var_slots > 4 {1} else {count.min(packed_count)};
716            write!(
717                self.string,
718                "    {}_{}",
719                self.packed_var_name,
720                self.packed_var_index
721            )
722                .unwrap();
723            if self.packed_var_size > 1 {
724                write!(
725                    self.string,
726                    ".{}",
727                    Swizzle::from_range(self.packed_var_offset, self.packed_var_offset + min_count)
728                )
729                    .unwrap();
730            }
731            write!(self.string, " = {}", &DisplayDsIdent(ident)).unwrap();
732            if var_slots > 1 {
733                if var_slots <= 4 {
734                    in_matrix = None;
735                    write!(
736                        self.string,
737                        ".{}",
738                        Swizzle::from_range(var_offset, var_offset + min_count)
739                    )
740                        .unwrap();
741                }
742                else { // make a matrix constructor and unpack into it
743                    if let Some(in_matrix) = &mut in_matrix {
744                        *in_matrix += 1;
745                    }
746                    else {
747                        in_matrix = Some(0);
748                    }
749                    if let Some(in_matrix) = in_matrix {
750                        write!(
751                            self.string,
752                            "[{}][{}]",
753                            in_matrix >> 2,
754                            in_matrix & 3,
755                        ).unwrap();
756                    }
757                }
758            }
759            writeln!(self.string, ";").unwrap();
760            self.packed_var_offset += min_count;
761            if self.packed_var_offset == self.packed_var_size {
762                self.packed_vars_size -= self.packed_var_size;
763                self.packed_var_index += 1;
764                self.packed_var_size = self.packed_vars_size.min(4);
765                self.packed_var_offset = 0;
766            }
767            var_offset += min_count;
768        }
769    }
770}
771
772struct VarUnpacker<'a> {
773    packed_var_name: &'a str,
774    packed_vars_size: usize,
775    packed_var_index: usize,
776    packed_var_size: usize,
777    packed_var_offset: usize,
778    string: &'a mut String,
779}
780
781impl<'a> VarUnpacker<'a> {
782    fn new(
783        packed_var_name: &'a str,
784        packed_vars_size: usize,
785        string: &'a mut String,
786    ) -> VarUnpacker<'a> {
787        VarUnpacker {
788            packed_var_name,
789            packed_vars_size,
790            packed_var_index: 0,
791            packed_var_size: packed_vars_size.min(4),
792            packed_var_offset: 0,
793            string,
794        }
795    }
796    
797    fn unpack_var(&mut self, ident: Ident, ty: &Ty) {
798        let var_slots = ty.slots();
799        let mut var_offset = 0;
800        let mut in_matrix = None;
801        while var_offset < var_slots {
802            let count = var_slots - var_offset;
803            let packed_count = self.packed_var_size - self.packed_var_offset;
804            let min_count = if var_slots > 4 {1} else {count.min(packed_count)};
805            write!(self.string, "    {}", &DisplayDsIdent(ident)).unwrap();
806            if var_slots > 1 {
807                if var_slots <= 4 { // its a matrix
808                    in_matrix = None;
809                    write!(
810                        self.string,
811                        ".{}",
812                        Swizzle::from_range(var_offset, var_offset + min_count)
813                    )
814                        .unwrap();
815                }
816                else {
817                    if let Some(in_matrix) = &mut in_matrix {
818                        *in_matrix += 1;
819                    }
820                    else {
821                        in_matrix = Some(0);
822                    }
823                    if let Some(in_matrix) = in_matrix {
824                        write!(
825                            self.string,
826                            "[{}][{}]",
827                            in_matrix >> 2,
828                            in_matrix & 3,
829                        ).unwrap();
830                    }
831                }
832            }
833            write!(
834                self.string,
835                " = {}_{}",
836                self.packed_var_name,
837                self.packed_var_index
838            )
839                .unwrap();
840            
841            if self.packed_var_size > 1 {
842                write!(
843                    self.string,
844                    ".{}",
845                    Swizzle::from_range(self.packed_var_offset, self.packed_var_offset + min_count)
846                )
847                    .unwrap();
848            }
849            
850            writeln!(self.string, ";").unwrap();
851            var_offset += min_count;
852            self.packed_var_offset += min_count;
853            if self.packed_var_offset == self.packed_var_size {
854                self.packed_vars_size -= self.packed_var_size;
855                self.packed_var_index += 1;
856                self.packed_var_size = self.packed_vars_size.min(4);
857                self.packed_var_offset = 0;
858            }
859        }
860    }
861}
862
863struct GlslBackendWriter<'a> {
864    pub shader_registry: &'a ShaderRegistry,
865    pub draw_shader_def: &'a DrawShaderDef,
866    const_table: &'a DrawShaderConstTable,
867    options: GlslOptions,
868}
869
870#[derive(Copy, Clone)]
871pub struct GlslOptions{
872    pub use_ovr_multiview: bool,
873    pub use_uniform_buffers: bool,
874    pub use_inout: bool
875}
876
877impl<'a> BackendWriter for GlslBackendWriter<'a> {
878    fn get_struct_cons_type(&self) -> StructConsType {
879        StructConsType::Paren
880    }
881    
882    fn const_table_prefix(&self)->&'static str{
883        "const_table"
884    }
885    
886    fn enum_is_float(&self) -> bool {
887        true
888    }
889    
890    fn needs_mul_fn_for_matrix_multiplication(&self) -> bool {
891        false
892    }
893    
894    fn needs_unpack_for_matrix_multiplication(&self) -> bool {
895        false
896    }
897    
898    fn const_table_is_vec4(&self) -> bool {
899        false
900    }
901    
902    fn use_cons_fn(&self, _what: &str) -> bool {
903        false
904    }
905    
906    fn write_var_decl(
907        &self,
908        string: &mut String,
909        sep: &'static str,
910        is_inout: bool,
911        is_packed: bool,
912        ident: &dyn fmt::Display,
913        ty: &Ty,
914    ) -> bool {
915        fn prefix(string: &mut String, sep: &'static str, is_inout: bool) {
916            write!(string, "{}", sep).unwrap();
917            if is_inout {
918                write!(string, "inout ").unwrap();
919            }
920        }
921        match *ty {
922            Ty::Void => {
923                write!(string, "{}void {}", sep, ident).unwrap();
924            }
925            Ty::Bool => {
926                prefix(string, sep, is_inout);
927                self.write_ty_lit(string, TyLit::Bool);
928                write!(string, " {}", ident).unwrap();
929            }
930            Ty::Int => {
931                prefix(string, sep, is_inout);
932                self.write_ty_lit(string, TyLit::Int);
933                write!(string, " {}", ident).unwrap();
934            }
935            Ty::Float => {
936                prefix(string, sep, is_inout);
937                self.write_ty_lit(string, TyLit::Float);
938                write!(string, " {}", ident).unwrap();
939            }
940            Ty::Bvec2 => {
941                prefix(string, sep, is_inout);
942                self.write_ty_lit(string, TyLit::Bvec2);
943                write!(string, " {}", ident).unwrap();
944            }
945            Ty::Bvec3 => {
946                prefix(string, sep, is_inout);
947                self.write_ty_lit(string, TyLit::Bvec3);
948                write!(string, " {}", ident).unwrap();
949            }
950            Ty::Bvec4 => {
951                prefix(string, sep, is_inout);
952                self.write_ty_lit(string, TyLit::Bvec4);
953                write!(string, " {}", ident).unwrap();
954            }
955            Ty::Ivec2 => {
956                prefix(string, sep, is_inout);
957                self.write_ty_lit(string, TyLit::Ivec2);
958                write!(string, " {}", ident).unwrap();
959            }
960            Ty::Ivec3 => {
961                prefix(string, sep, is_inout);
962                self.write_ty_lit(string, TyLit::Ivec3);
963                write!(string, " {}", ident).unwrap();
964            }
965            Ty::Ivec4 => {
966                prefix(string, sep, is_inout);
967                self.write_ty_lit(string, TyLit::Ivec4);
968                write!(string, " {}", ident).unwrap();
969            }
970            Ty::Vec2 => {
971                prefix(string, sep, is_inout);
972                self.write_ty_lit(string, TyLit::Vec2);
973                write!(string, " {}", ident).unwrap();
974            }
975            Ty::Vec3 => {
976                prefix(string, sep, is_inout);
977                self.write_ty_lit(string, TyLit::Vec3);
978                write!(string, " {}", ident).unwrap();
979            }
980            Ty::Vec4 => {
981                prefix(string, sep, is_inout);
982                self.write_ty_lit(string, TyLit::Vec4);
983                write!(string, " {}", ident).unwrap();
984            }
985            Ty::Mat2 => {
986                prefix(string, sep, is_inout);
987                self.write_ty_lit(string, TyLit::Mat2);
988                write!(string, " {}", ident).unwrap();
989            }
990            Ty::Mat3 => {
991                prefix(string, sep, is_inout);
992                self.write_ty_lit(string, TyLit::Mat3);
993                write!(string, " {}", ident).unwrap();
994            }
995            Ty::Mat4 => {
996                prefix(string, sep, is_inout);
997                self.write_ty_lit(string, TyLit::Mat4);
998                write!(string, " {}", ident).unwrap();
999            }
1000            Ty::Texture2D => {
1001                write!(string, "{}", sep).unwrap();
1002                self.write_ty_lit(string, TyLit::Texture2D);
1003                write!(string, " {}", ident).unwrap();
1004            }
1005            Ty::TextureOES => {
1006                write!(string, "{}", sep).unwrap();
1007                self.write_ty_lit(string, TyLit::TextureOES);
1008                write!(string, " {}", ident).unwrap();
1009            }
1010            Ty::Array {ref elem_ty, len} => {
1011                self.write_var_decl(string, sep, is_inout, is_packed, ident, elem_ty);
1012                write!(string, "[{}]", len).unwrap();
1013            }
1014            Ty::DrawShader(_) => {
1015                // we should output nothing
1016                return false
1017            }
1018            Ty::ClosureDef {..} => {
1019                return false
1020            }
1021            Ty::ClosureDecl => {
1022                return false
1023            }
1024            Ty::Struct(ptr) => {
1025                prefix(string, sep, is_inout);
1026                write!(string, "{} {}", ptr, ident).unwrap();
1027            }
1028            Ty::Enum(_) => {
1029                prefix(string, sep, is_inout);
1030                write!(string, "float {}", ident).unwrap();
1031            }
1032        }
1033        true
1034    }
1035    
1036    fn write_call_expr_hidden_args(&self, _string: &mut String, _hidden_args: &BTreeSet<HiddenArgKind >, _sep: &str) {
1037    }
1038    
1039    fn write_fn_def_hidden_params(&self, _string: &mut String, _hidden_args: &BTreeSet<HiddenArgKind >, _sep: &str) {
1040    }
1041    
1042    fn generate_live_value_prefix(&self, string: &mut String) {
1043        if self.options.use_uniform_buffers{
1044            write!(string, "lt.").unwrap();
1045        }
1046    }
1047    
1048    fn generate_draw_shader_field_expr(&self, string: &mut String, field_ident: Ident, _ty: &Ty) {
1049        if self.options.use_uniform_buffers{
1050            let field_def = self.draw_shader_def.find_field(field_ident).unwrap();
1051                            
1052            match &field_def.kind {
1053                DrawShaderFieldKind::Geometry {..} |
1054                DrawShaderFieldKind::Instance { ..} |
1055                DrawShaderFieldKind::Varying {..} |
1056                DrawShaderFieldKind::Texture {..} => {
1057                     write!(string, "{}", &DisplayDsIdent(field_ident)).unwrap();
1058                }
1059                DrawShaderFieldKind::Uniform {block_ident, ..} => {
1060                    write!(string, "{}.{}", block_ident, field_ident).unwrap();
1061                    if self.options.use_ovr_multiview && *block_ident == Ident(live_id!(pass)) &&(
1062                        field_ident == Ident(live_id!(camera_projection)) ||
1063                        field_ident == Ident(live_id!(camera_view))){
1064                        write!(string, "[VIEW_ID]").unwrap();
1065                    }
1066                }
1067            }
1068        }
1069        else{
1070            write!(string, "{}", &DisplayDsIdent(field_ident)).unwrap();
1071        }
1072    }
1073    
1074    fn write_ty_lit(&self, string: &mut String, ty_lit: TyLit) {
1075        write!(
1076            string,
1077            "{}",
1078            match ty_lit {
1079                TyLit::Bool => "bool",
1080                TyLit::Int => "int",
1081                TyLit::Float => "float",
1082                TyLit::Bvec2 => "bvec2",
1083                TyLit::Bvec3 => "bvec3",
1084                TyLit::Bvec4 => "bvec4",
1085                TyLit::Ivec2 => "ivec2",
1086                TyLit::Ivec3 => "ivec3",
1087                TyLit::Ivec4 => "ivec4",
1088                TyLit::Vec2 => "vec2",
1089                TyLit::Vec3 => "vec3",
1090                TyLit::Vec4 => "vec4",
1091                TyLit::Mat2 => "mat2",
1092                TyLit::Mat3 => "mat3",
1093                TyLit::Mat4 => "mat4",
1094                TyLit::Texture2D => "sampler2D",
1095                TyLit::TextureOES => "samplerExternalOES",
1096            }
1097        )
1098            .unwrap();
1099    }
1100    
1101    fn write_builtin_call_ident(&self, string: &mut String, ident: Ident, _arg_exprs: &[Expr]) {
1102         match ident {
1103            _ => {
1104                write!(string, "{}", ident).unwrap()
1105            }
1106        }
1107    }
1108    
1109}