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 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 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 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, ¶m_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 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 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 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::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 { 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 { 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 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}