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 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 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 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, ¶m_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 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 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 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 }
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 self.generate_uniform_block_decl(field);
438
439 }
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,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,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 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::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 { 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 { 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 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}