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