1use{
2 std::{
3 fmt,
4 fmt::Write,
5 collections::{BTreeSet,BTreeMap},
6 },
7 crate::{
8 makepad_live_id::{
9 live_id,
10 LiveId,
11 },
12 generate::*,
13 shader_ast::*,
14 shader_registry::ShaderRegistry
15 }
16};
17
18pub fn index_to_char(index: usize) -> char {
19 std::char::from_u32(index as u32 + 65).unwrap()
20}
21
22pub fn generate_shader(draw_shader_def: &DrawShaderDef, const_table:&DrawShaderConstTable, shader_registry: &ShaderRegistry) -> String {
23 let mut string = String::new();
24 DrawShaderGenerator {
25 draw_shader_def,
26 shader_registry,
27 string: &mut string,
28 const_table,
29 backend_writer: &HlslBackendWriter {shader_registry, draw_shader_def, const_table}
30 }
31 .generate_shader();
32 string
33}
34
35struct DrawShaderGenerator<'a> {
36 draw_shader_def: &'a DrawShaderDef,
37 shader_registry: &'a ShaderRegistry,
38 string: &'a mut String,
39 backend_writer: &'a dyn BackendWriter,
40 const_table: &'a DrawShaderConstTable
41}
42
43impl<'a> DrawShaderGenerator<'a> {
44 fn generate_shader(&mut self) {
45
46 let mut all_constructor_fns = BTreeSet::new();
47
48 for fn_iter in self.draw_shader_def.all_fns.borrow().iter() {
49 let fn_def = self.shader_registry.all_fns.get(fn_iter).unwrap();
50 all_constructor_fns.extend(fn_def.constructor_fn_deps.borrow().as_ref().unwrap().iter().cloned());
51 }
52
53 for fn_iter in self.draw_shader_def.all_fns.borrow().iter() {
54 let fn_def = self.shader_registry.all_fns.get(fn_iter).unwrap();
55 if fn_def.builtin_deps.borrow().as_ref().unwrap().contains(&Ident(live_id!(sample2d))) {
56 writeln!(self.string, "SamplerState default_texture_sampler{{Filter=MIN_MAX_MIP_LINEAR;AddressU = Wrap;AddressV=Wrap;}};").unwrap();
57 writeln!(self.string, "float4 sample2d(Texture2D tex, float2 pos){{return tex.Sample(default_texture_sampler,pos);}}").unwrap();
58 break;
59 }
60
61 if fn_def.builtin_deps.borrow().as_ref().unwrap().contains(&Ident(live_id!(sample2d_rt))) {
62 writeln!(self.string, "SamplerState default_texture_sampler{{Filter=MIN_MAX_MIP_LINEAR;AddressU = Wrap;AddressV=Wrap;}};").unwrap();
63 writeln!(self.string, "float4 sample2d_rt(Texture2D tex, float2 pos){{return tex.Sample(default_texture_sampler,pos);}}").unwrap();
64 break;
65 }
66 };
67
68 self.generate_struct_decls();
69 let fields_as_uniform_blocks = self.draw_shader_def.fields_as_uniform_blocks();
70 self.generate_uniform_structs(&fields_as_uniform_blocks);
71 self.generate_texture_defs();
72 self.generate_geometry_struct();
73 self.generate_instance_struct();
74 self.generate_varying_struct();
75
76 for (ty_lit, ref param_tys) in all_constructor_fns{
80 generate_cons_fn(self.backend_writer, self.string, ty_lit, ¶m_tys);
81 }
82
83 let all_fns = self.draw_shader_def.all_fns.borrow();
84 for fn_iter in all_fns.iter().rev() {
85 let const_table_offset = self.const_table.offsets.get(fn_iter).cloned();
86 let fn_def = self.shader_registry.all_fns.get(fn_iter).unwrap();
87 if fn_def.has_closure_args() {
88 for call_iter in all_fns.iter().rev() {
89 let call_def = self.shader_registry.all_fns.get(call_iter).unwrap();
91 if call_def.callees.borrow().as_ref().unwrap().contains(&fn_iter) {
92 FnDefWithClosureArgsGenerator::generate_fn_def_with_all_closures(
93 &mut self.string,
94 self.shader_registry,
95 fn_def,
96 call_def,
97 self.backend_writer,
98 const_table_offset
99 );
100 }
101 }
102 continue
103 }
104 FnDefGenerator {
105 fn_def,
106 const_table_offset,
107 shader_registry: self.shader_registry,
108 backend_writer: self.backend_writer,
109 string: self.string,
110 }
111 .generate_fn_def()
112 }
113 self.generate_vertex_main();
114 self.generate_pixel_main();
115 }
116
117 fn generate_struct_decls(&mut self) {
118 for struct_ptr in self.draw_shader_def.all_structs.borrow().iter().rev() {
119 let struct_def = self.shader_registry.structs.get(struct_ptr).unwrap();
120 write!(self.string, "struct {} {{", struct_ptr).unwrap();
121 if !struct_def.fields.is_empty() {
122 writeln!(self.string).unwrap();
123 for field in &struct_def.fields {
124 write!(self.string, " ").unwrap();
125 self.write_var_decl(
126 &DisplayStructField(field.ident),
127 field.ty_expr.ty.borrow().as_ref().unwrap(),
128 );
129 writeln!(self.string, ";").unwrap();
130 }
131 }
132 writeln!(self.string, "}};").unwrap();
133
134 write!(self.string, "{0} consfn_{0}(", struct_ptr).unwrap();
135 if !struct_def.fields.is_empty() {
136 writeln!(self.string).unwrap();
137 let mut sep = "";
138 for field in &struct_def.fields {
139 write!(self.string, "{}", sep).unwrap();
140 self.write_var_decl(
141 &DisplayStructField(field.ident),
142 field.ty_expr.ty.borrow().as_ref().unwrap(),
143 );
144 sep = ", ";
145 }
146 }
147 writeln!(self.string, "){{;").unwrap();
148 writeln!(self.string, "{} r;", struct_ptr).unwrap();
149 if !struct_def.fields.is_empty() {
150 for field in &struct_def.fields {
151 writeln!(self.string, "r.{0} = {0};", DisplayStructField(field.ident)).unwrap();
152 }
153 }
154 writeln!(self.string, "return r;\n}}").unwrap();
155 }
156 }
157
158 fn generate_uniform_structs(&mut self, fields_as_uniform_blocks: &BTreeMap<Ident, Vec<(usize, Ident) >>) {
159 writeln!(self.string, "cbuffer LiveUniforms : register(b0) {{").unwrap();
160 for (value_node_ptr, ty) in self.draw_shader_def.all_live_refs.borrow().iter() {
161 write!(self.string, " ").unwrap();
162 self.write_ty_lit(ty.maybe_ty_lit().unwrap());
163 write!(self.string, " ").unwrap();
164 write!(self.string, "{}", value_node_ptr).unwrap();
165 writeln!(self.string, ";").unwrap();
166 }
167 writeln!(self.string, "}};").unwrap();
168
169 writeln!(self.string, "cbuffer ConstTable : register(b1){{float4 const_table[{}];}};", self.const_table.table.len() >> 2).unwrap();
170
171 for (ident, vec) in fields_as_uniform_blocks {
172 let index = match ident.0{
173 live_id!(draw)=>2,
174 live_id!(pass)=>3,
175 live_id!(user)=>5,
176 live_id!(view)=>4,
177 _=>panic!()
178 };
179 writeln!(self.string, "cbuffer Uniforms_{} : register(b{}) {{", ident, index).unwrap();
180 for (index, _item) in vec {
181 let field = &self.draw_shader_def.fields[*index];
182 write!(self.string, " ").unwrap();
183 self.write_var_decl(&DisplayDsIdent(field.ident), field.ty_expr.ty.borrow().as_ref().unwrap(),);
184 writeln!(self.string, ";").unwrap();
185 }
186 writeln!(self.string, "}};").unwrap();
187 }
188 }
189
190 fn generate_texture_defs(&mut self) {
191 let mut index = 0;
192 for field in &self.draw_shader_def.fields {
194 match field.kind {
195 DrawShaderFieldKind::Texture {..} => {
196 assert_eq!(*field.ty_expr.ty.borrow().as_ref().unwrap(), Ty::Texture2D);
197 write!(self.string, "Texture2D {}: register(t{});", DisplayDsIdent(field.ident), index).unwrap();
198 index += 1;
199 }
200 _ => {}
201 }
202 }
203 }
205
206 fn generate_geometry_struct(&mut self) {
207 writeln!(self.string, "struct Geometries {{").unwrap();
208 let mut index = 0;
209 for field in &self.draw_shader_def.fields {
210 match field.kind {
211 DrawShaderFieldKind::Geometry {..} => {
212 write!(self.string, " ").unwrap();
213 self.write_var_decl(&DisplayDsIdent(field.ident), field.ty_expr.ty.borrow().as_ref().unwrap(),);
214 writeln!(self.string, ": GEOM{};", index_to_char(index)).unwrap();
215 index += 1;
216 }
217 _ => ()
218 }
219 }
220 writeln!(self.string, "}};").unwrap();
221 }
222
223 fn generate_instance_struct(&mut self) {
224 writeln!(self.string, "struct Instances {{").unwrap();
225 let mut index = 0;
226 for field in &self.draw_shader_def.fields {
227 match field.kind {
228 DrawShaderFieldKind::Instance {..} => {
229 match field.ty_expr.ty.borrow().as_ref().unwrap() {
230 Ty::Float | Ty::Vec2 | Ty::Vec3 | Ty::Vec4 => {
231 write!(self.string, " ").unwrap();
232 self.write_var_decl(&DisplayDsIdent(field.ident), field.ty_expr.ty.borrow().as_ref().unwrap(),);
233 writeln!(self.string, ": INST{};", index_to_char(index)).unwrap();
234 index += 1;
235 },
236 Ty::Mat4 => {
237 for i in 0..4 {
238 write!(self.string, " ").unwrap();
239 self.write_ty_lit(TyLit::Vec4);
240 write!(self.string, " {}{}", &DisplayDsIdent(field.ident), i).unwrap();
241 writeln!(self.string, ": INST{};", index_to_char(index)).unwrap();
242 index += 1;
243 }
244 },
245 Ty::Mat3 => {
246 for i in 0..3 {
247 write!(self.string, " ").unwrap();
248 self.write_ty_lit(TyLit::Vec3);
249 write!(self.string, " {}{}", &DisplayDsIdent(field.ident), i).unwrap();
250 writeln!(self.string, ": INST{};", index_to_char(index)).unwrap();
251 index += 1;
252 }
253 },
254 Ty::Mat2 => {
255 write!(self.string, " ").unwrap();
256 self.write_ty_lit(TyLit::Vec4);
257 write!(self.string, " {}", &DisplayDsIdent(field.ident)).unwrap();
258 writeln!(self.string, ": INST{};", index_to_char(index)).unwrap();
259 index += 1;
260 },
261 Ty::Enum(_) => {
262 write!(self.string, " ").unwrap();
263 self.write_ty_lit(TyLit::Int);
264 write!(self.string, " {}", &DisplayDsIdent(field.ident)).unwrap();
265 writeln!(self.string, ": INST{};", index_to_char(index)).unwrap();
266 index += 1;
267 },
268 x => panic!("unsupported type in generate_instance_struct {:?}", x)
269 }
270 }
271 _ => {}
272 }
273 }
274 writeln!(self.string, "}};").unwrap();
275 }
276
277 fn generate_varying_struct(&mut self) {
278 writeln!(self.string, "struct Varyings {{").unwrap();
279 writeln!(self.string, " float4 position: SV_POSITION;").unwrap();
280 let mut index = 0;
281 for field in &self.draw_shader_def.fields {
282 match &field.kind {
283 DrawShaderFieldKind::Geometry {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
284 write!(self.string, " ").unwrap();
285 self.write_var_decl(&DisplayDsIdent(field.ident), field.ty_expr.ty.borrow().as_ref().unwrap(),);
286 writeln!(self.string, ": VARY{};", index_to_char(index)).unwrap();
287 index += 1;
288 }
289 DrawShaderFieldKind::Instance {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
290 match field.ty_expr.ty.borrow().as_ref().unwrap() {
291 Ty::Float | Ty::Vec2 | Ty::Vec3 | Ty::Vec4 => {
292 write!(self.string, " ").unwrap();
293 self.write_var_decl(&DisplayDsIdent(field.ident), field.ty_expr.ty.borrow().as_ref().unwrap(),);
294 writeln!(self.string, ": VARY{};", index_to_char(index)).unwrap();
295 index += 1;
296 },
297 Ty::Mat4 => {
298 for i in 0..4 {
299 write!(self.string, " ").unwrap();
300 self.write_ty_lit(TyLit::Vec4);
301 write!(self.string, " {}{}", &DisplayDsIdent(field.ident), i).unwrap();
302 writeln!(self.string, ": VARY{};", index_to_char(index)).unwrap();
303 index += 1;
304 }
305 },
306 Ty::Mat3 => {
307 for i in 0..3 {
308 write!(self.string, " ").unwrap();
309 self.write_ty_lit(TyLit::Vec3);
310 write!(self.string, " {}{}", &DisplayDsIdent(field.ident), i).unwrap();
311 writeln!(self.string, ": VARY{};", index_to_char(index)).unwrap();
312 index += 1;
313 }
314 },
315 Ty::Mat2 => {
316 write!(self.string, " ").unwrap();
317 self.write_ty_lit(TyLit::Vec4);
318 write!(self.string, " {}", &DisplayDsIdent(field.ident)).unwrap();
319 writeln!(self.string, ": VARY{};", index_to_char(index)).unwrap();
320 index += 1;
321 },
322 Ty::Enum(_) =>{
323 write!(self.string, " ").unwrap();
324 self.write_ty_lit(TyLit::Int);
325 write!(self.string, " {}", &DisplayDsIdent(field.ident)).unwrap();
326 writeln!(self.string, ": VARY{};", index_to_char(index)).unwrap();
327 index += 1;
328 }
329 x => panic!("unsupported type in generate_varying_struct {:?}", x)
330 }
331 }
332 DrawShaderFieldKind::Varying {..} => {
333 write!(self.string, " ").unwrap();
334 self.write_var_decl(&DisplayDsIdent(field.ident), field.ty_expr.ty.borrow().as_ref().unwrap(),);
335 writeln!(self.string, ": VARY{};", index_to_char(index)).unwrap();
336 index += 1;
337 }
338 _ => {}
339 }
340 }
341 writeln!(self.string, "}};").unwrap();
342 }
343
344 fn generate_varying_init(&mut self) {
345 write!(self.string, "{{").unwrap();
346 write!(self.string, "float4(0.0,0.0,0.0,0.0)").unwrap();
347 let sep = ", ";
348 for field in &self.draw_shader_def.fields {
349 match &field.kind {
350 DrawShaderFieldKind::Geometry {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
351 write!(self.string, "{}", sep).unwrap();
352 self.write_var_init(field.ty_expr.ty.borrow().as_ref().unwrap());
353 }
354 DrawShaderFieldKind::Instance {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
355 match field.ty_expr.ty.borrow().as_ref().unwrap() {
356 Ty::Mat4 => {
357 for _ in 0..4 {
358 write!(self.string, "{}", sep).unwrap();
359 self.write_var_init(&Ty::Vec4);
360 }
361 },
362 Ty::Mat3 => {
363 for _ in 0..3 {
364 write!(self.string, "{}", sep).unwrap();
365 self.write_var_init(&Ty::Vec3);
366 }
367 },
368 Ty::Mat2 => {
369 write!(self.string, "{}", sep).unwrap();
370 self.write_var_init(&Ty::Vec4);
371 },
372 _ => {
373 write!(self.string, "{}", sep).unwrap();
374 self.write_var_init(field.ty_expr.ty.borrow().as_ref().unwrap());
375 }
376 }
377 }
378 DrawShaderFieldKind::Varying {..} => {
379 write!(self.string, "{}", sep).unwrap();
380 self.write_var_init(field.ty_expr.ty.borrow().as_ref().unwrap());
381 }
382 _ => {}
383 }
384 }
385 writeln!(self.string, "}};").unwrap();
386 }
387
388 fn generate_vertex_main(&mut self) {
389
390 write!(self.string, "Varyings vertex_main(").unwrap();
391 write!(self.string, "Geometries geometries").unwrap();
392 write!(self.string, ", Instances instances").unwrap();
393 write!(self.string, ", uint inst_id: SV_InstanceID").unwrap();
394 writeln!(self.string, ") {{").unwrap();
395 write!(self.string, " Varyings varyings = ").unwrap();
396 self.generate_varying_init();
397
398 for decl in &self.draw_shader_def.fields {
399 match &decl.kind {
400 DrawShaderFieldKind::Geometry {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
401 writeln!(self.string, " varyings.{0} = geometries.{0};", decl.ident).unwrap();
402 }
403 DrawShaderFieldKind::Instance {is_used_in_pixel_shader, ..} if is_used_in_pixel_shader.get() => {
404 match decl.ty_expr.ty.borrow().as_ref().unwrap(){
405 Ty::Mat4=>{
406 for i in 0..4{
407 writeln!(self.string, " varyings.{0}{1} = instances.{0}{1};", DisplayDsIdent(decl.ident), i).unwrap();
408 }
409 }
410 Ty::Mat3=>{
411 for i in 0..3{
412 writeln!(self.string, " varyings.{0}{1} = instances.{0}{1};", DisplayDsIdent(decl.ident), i).unwrap();
413 }
414 }
415 _=>{
416 writeln!(self.string, " varyings.{0} = instances.{0};", DisplayDsIdent(decl.ident)).unwrap();
417 }
418 }
419 }
420 _ => {}
421 }
422 }
423
424 let vertex_def = self.shader_registry.draw_shader_method_decl_from_ident(self.draw_shader_def, Ident(live_id!(vertex))).unwrap();
425 write!(self.string, " varyings.position = {}", DisplayFnName(vertex_def.fn_ptr, vertex_def.ident)).unwrap();
426
427 write!(self.string, "(").unwrap();
428
429 self.backend_writer.write_call_expr_hidden_args(self.string, vertex_def.hidden_args.borrow().as_ref().unwrap(), "");
430
431 writeln!(self.string, ");").unwrap();
432
433 writeln!(self.string, " return varyings;").unwrap();
434 writeln!(self.string, "}}").unwrap();
435 }
436
437 fn generate_pixel_main(&mut self) {
438
439 write!(self.string, "float4 pixel_main(").unwrap();
440 write!(self.string, "Varyings varyings").unwrap();
441 writeln!(self.string, ") : SV_TARGET{{").unwrap();
442
443 write!(self.string, " return ").unwrap();
444 let pixel_def = self.shader_registry.draw_shader_method_decl_from_ident(self.draw_shader_def, Ident(live_id!(pixel))).unwrap();
445 write!(self.string, " {}", DisplayFnName(pixel_def.fn_ptr, pixel_def.ident)).unwrap();
446 write!(self.string, "(").unwrap();
447 self.backend_writer.write_call_expr_hidden_args(self.string, pixel_def.hidden_args.borrow().as_ref().unwrap(), "");
448 writeln!(self.string, ");").unwrap();
449
450 writeln!(self.string, "}}").unwrap();
451 }
452
453 fn generate_expr(&mut self, expr: &Expr) {
454 ExprGenerator {
455 fn_def: None,
456 shader_registry: self.shader_registry,
457 closure_site_info: None,
458 const_table_offset: None,
460 backend_writer: self.backend_writer,
461 string: self.string,
462 }
463 .generate_expr(expr)
464 }
465
466 fn write_var_init(&mut self, ty: &Ty) {
467 match ty {
468 Ty::Bool => write!(self.string, "false").unwrap(),
469 Ty::Int => write!(self.string, "0").unwrap(),
470 Ty::Float => write!(self.string, "0.0").unwrap(),
471 Ty::Bvec2 => write!(self.string, "bool2(0,0)").unwrap(),
472 Ty::Bvec3 => write!(self.string, "bool3(0,0,0)").unwrap(),
473 Ty::Bvec4 => write!(self.string, "bool4(0,0,0,0)").unwrap(),
474 Ty::Ivec2 => write!(self.string, "int2(0,0)").unwrap(),
475 Ty::Ivec3 => write!(self.string, "int3(0,0,0)").unwrap(),
476 Ty::Ivec4 => write!(self.string, "int4(0,0,0,0)").unwrap(),
477 Ty::Vec2 => write!(self.string, "float2(0.0,0.0)").unwrap(),
478 Ty::Vec3 => write!(self.string, "float3(0.0,0.0,0.0)").unwrap(),
479 Ty::Vec4 => write!(self.string, "float4(0.0,0.0,0.0,0.0)").unwrap(),
480 Ty::Mat2 => write!(self.string, "float2x2(0.0,0.0, 0.0,0.0)").unwrap(),
481 Ty::Mat3 => write!(self.string, "float3x3(0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0)").unwrap(),
482 Ty::Mat4 => write!(self.string, "float4x4(0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0)").unwrap(),
483 Ty::Enum(_) => write!(self.string, "0").unwrap(),
484 _ => panic!("Implement init for type")
485 }
486 }
487
488 fn write_var_decl(&mut self, ident: &dyn fmt::Display, ty: &Ty) {
489 self.backend_writer.write_var_decl(&mut self.string, "", false, false, ident, ty);
490 }
491
492 fn write_ty_lit(&mut self, ty_lit: TyLit) {
493 self.backend_writer.write_ty_lit(&mut self.string, ty_lit);
494 }
495}
496
497struct HlslBackendWriter<'a> {
498 pub shader_registry: &'a ShaderRegistry,
499 pub draw_shader_def: &'a DrawShaderDef,
500 pub const_table: &'a DrawShaderConstTable
501}
502
503impl<'a> BackendWriter for HlslBackendWriter<'a> {
504
505 fn get_struct_cons_type(&self) -> StructConsType {
506 StructConsType::ConsFn
507 }
508
509 fn enum_is_float(&self)->bool{
510 false
511 }
512
513 fn needs_mul_fn_for_matrix_multiplication(&self) -> bool {
514 true
515 }
516
517 fn needs_unpack_for_matrix_multiplication(&self) -> bool {
518 false
519 }
520
521 fn const_table_is_vec4(&self) -> bool {
522 true
523 }
524
525 fn use_cons_fn(&self, what: &str) -> bool {
526 match what {
527 "consfn_vec4_float_float_float_float" => false,
528 "consfn_vec3_float_float_float" => false,
529 "consfn_vec2_float_float" => false,
530 _ => true
531 }
532 }
533
534 fn write_var_decl(
535 &self,
536 string: &mut String,
537 sep: &'static str,
538 is_inout: bool,
539 is_packed: bool,
540 ident: &dyn fmt::Display,
541 ty: &Ty,
542 ) -> bool {
543 fn prefix(string: &mut String, sep: &'static str, is_inout: bool) {
544 write!(string, "{}", sep).unwrap();
545 if is_inout {
546 write!(string, "inout ").unwrap();
547 }
548 }
549 match *ty {
550 Ty::Void => {
551 write!(string, "{}void {}", sep, ident).unwrap();
552 }
553 Ty::Bool => {
554 prefix(string, sep, is_inout);
555 self.write_ty_lit(string, TyLit::Bool);
556 write!(string, " {}", ident).unwrap();
557 }
558 Ty::Int => {
559 prefix(string, sep, is_inout);
560 self.write_ty_lit(string, TyLit::Int);
561 write!(string, " {}", ident).unwrap();
562 }
563 Ty::Float => {
564 prefix(string, sep, is_inout);
565 self.write_ty_lit(string, TyLit::Float);
566 write!(string, " {}", ident).unwrap();
567 }
568 Ty::Bvec2 => {
569 prefix(string, sep, is_inout);
570 self.write_ty_lit(string, TyLit::Bvec2);
571 write!(string, " {}", ident).unwrap();
572 }
573 Ty::Bvec3 => {
574 prefix(string, sep, is_inout);
575 self.write_ty_lit(string, TyLit::Bvec3);
576 write!(string, " {}", ident).unwrap();
577 }
578 Ty::Bvec4 => {
579 prefix(string, sep, is_inout);
580 self.write_ty_lit(string, TyLit::Bvec4);
581 write!(string, " {}", ident).unwrap();
582 }
583 Ty::Ivec2 => {
584 prefix(string, sep, is_inout);
585 self.write_ty_lit(string, TyLit::Ivec2);
586 write!(string, " {}", ident).unwrap();
587 }
588 Ty::Ivec3 => {
589 prefix(string, sep, is_inout);
590 self.write_ty_lit(string, TyLit::Ivec3);
591 write!(string, " {}", ident).unwrap();
592 }
593 Ty::Ivec4 => {
594 prefix(string, sep, is_inout);
595 self.write_ty_lit(string, TyLit::Ivec4);
596 write!(string, " {}", ident).unwrap();
597 }
598 Ty::Vec2 => {
599 prefix(string, sep, is_inout);
600 self.write_ty_lit(string, TyLit::Vec2);
601 write!(string, " {}", ident).unwrap();
602 }
603 Ty::Vec3 => {
604 prefix(string, sep, is_inout);
605 self.write_ty_lit(string, TyLit::Vec3);
606 write!(string, " {}", ident).unwrap();
607 }
608 Ty::Vec4 => {
609 prefix(string, sep, is_inout);
610 self.write_ty_lit(string, TyLit::Vec4);
611 write!(string, " {}", ident).unwrap();
612 }
613 Ty::Mat2 => {
614 prefix(string, sep, is_inout);
615 self.write_ty_lit(string, TyLit::Mat2);
616 write!(string, " {}", ident).unwrap();
617 }
618 Ty::Mat3 => {
619 prefix(string, sep, is_inout);
620 self.write_ty_lit(string, TyLit::Mat3);
621 write!(string, " {}", ident).unwrap();
622 }
623 Ty::Mat4 => {
624 prefix(string, sep, is_inout);
625 self.write_ty_lit(string, TyLit::Mat4);
626 write!(string, " {}", ident).unwrap();
627 }
628 Ty::Texture2D => panic!(), Ty::Array {ref elem_ty, len} => {
630 self.write_var_decl(string, sep, is_inout, is_packed, ident, elem_ty);
631 write!(string, "[{}]", len).unwrap();
632 }
633 Ty::Struct(struct_node_ptr) => {
634 prefix(string, sep, is_inout);
635 write!(string, "{} {}", struct_node_ptr, ident).unwrap();
636 }
637 Ty::Enum(_) => {
638 prefix(string, sep, is_inout);
639 write!(string, "int {}", ident).unwrap();
640 } Ty::DrawShader(_) => {
641 return false
642 }
643 Ty::ClosureDef {..} => {
644 return false
645 }
646 Ty::ClosureDecl => {
647 return false
648 }
649 }
650 true
651 }
652
653 fn write_call_expr_hidden_args(&self, string: &mut String, hidden_args: &BTreeSet<HiddenArgKind >, sep: &str) {
654 let mut sep = sep;
655 for hidden_arg in hidden_args {
662 match hidden_arg {
663 HiddenArgKind::Geometries => {
664 write!(string, "{}geometries",sep).unwrap();
665 sep = ", ";
666 }
667 HiddenArgKind::Instances => {
668 write!(string, "{}instances",sep).unwrap();
669 sep = ", ";
670 }
671 HiddenArgKind::Varyings => {
672 write!(string, "{}varyings",sep).unwrap();
673 sep = ", ";
674 }
675 _ => ()
676 }
677 }
678 }
679
680 fn write_fn_def_hidden_params(&self, string: &mut String, hidden_args: &BTreeSet<HiddenArgKind >, sep: &str) {
681 let mut sep = sep;
682
683 for hidden_arg in hidden_args {
684 match hidden_arg {
685 HiddenArgKind::Geometries => {
686 write!(string, "{}in Geometries geometries", sep).unwrap();
687 sep = ", ";
688 }
689 HiddenArgKind::Instances => {
690 write!(string, "{}in Instances instances", sep).unwrap();
691 sep = ", ";
692 }
693 HiddenArgKind::Varyings => {
694 write!(string, "{}inout Varyings varyings", sep).unwrap();
695 sep = ", ";
696 }
697 _ => ()
698 }
699 }
700 }
701
702 fn generate_live_value_prefix(&self, _string: &mut String) {
703 }
704
705 fn generate_draw_shader_field_expr(&self, string: &mut String, field_ident: Ident, ty: &Ty) {
706 let field_def = self.draw_shader_def.find_field(field_ident).unwrap();
707
708 match &field_def.kind {
709 DrawShaderFieldKind::Geometry {is_used_in_pixel_shader, ..} => {
710 if is_used_in_pixel_shader.get() {
711 write!(string, "varyings.").unwrap()
712 }
713 else {
714 write!(string, "geometries.").unwrap()
715 }
716 }
717 DrawShaderFieldKind::Instance {is_used_in_pixel_shader, ..} => {
718 let prefix = if is_used_in_pixel_shader.get() {
719 "varyings"
720 }
721 else {
722 "instances"
723 };
724
725 match ty {
726 Ty::Mat4 => {
727 write!(string, "float4x4(").unwrap();
728 for i in 0..4 {
729 for j in 0..4 {
730 if i != 0 || j != 0 {
731 write!(string, ",").unwrap();
732 }
733 write!(string, "{}.", prefix).unwrap();
734 write!(string, "{}{}", DisplayDsIdent(field_ident), j).unwrap();
735 match i {
736 0 => write!(string, ".x").unwrap(),
737 1 => write!(string, ".y").unwrap(),
738 2 => write!(string, ".z").unwrap(),
739 _ => write!(string, ".w").unwrap()
740 }
741 }
742 }
743 write!(string, ")").unwrap();
744 return
745 },
746 Ty::Mat3 => {
747 write!(string, "float3x3(").unwrap();
748 for i in 0..3 {
749 for j in 0..3 {
750 if i != 0 || j != 0 {
751 write!(string, ",").unwrap();
752 }
753 write!(string, "{}.", prefix).unwrap();
754 write!(string, "{}{}", DisplayDsIdent(field_ident), j).unwrap();
755 match i {
756 0 => write!(string, ".x").unwrap(),
757 1 => write!(string, ".y").unwrap(),
758 _ => write!(string, ".z").unwrap(),
759 }
760 }
761 }
762 write!(string, ")").unwrap();
763 return
764 },
765 Ty::Mat2 => {
766 write!(string, "float2x2({0}.{1}.x, {0}.{1}.y, {0}.{1}.z, {0}.{1}.w)", prefix, DisplayDsIdent(field_ident)).unwrap();
767 return
768 },
769 _ => {
770 write!(string, "{}.", prefix).unwrap();
771 }
772 }
773 }
774 DrawShaderFieldKind::Varying {..} => {
775 write!(string, "varyings.").unwrap()
776 }
777 _ => ()
778 }
779 write!(string, "{}", &DisplayDsIdent(field_ident)).unwrap();
780 }
781
782
783 fn write_ty_lit(&self, string: &mut String, ty_lit: TyLit) {
784 write!(
785 string,
786 "{}",
787 match ty_lit {
788 TyLit::Bool => "bool",
789 TyLit::Int => "int",
790 TyLit::Float => "float",
791 TyLit::Bvec2 => "bool2",
792 TyLit::Bvec3 => "bool3",
793 TyLit::Bvec4 => "bool4",
794 TyLit::Ivec2 => "int2",
795 TyLit::Ivec3 => "int3",
796 TyLit::Ivec4 => "int4",
797 TyLit::Vec2 => "float2",
798 TyLit::Vec3 => "float3",
799 TyLit::Vec4 => "float4",
800 TyLit::Mat2 => "float2x2",
801 TyLit::Mat3 => "float3x3",
802 TyLit::Mat4 => "float4x4",
803 TyLit::Texture2D => panic!(), }
805 )
806 .unwrap();
807 }
808
809
810 fn write_builtin_call_ident(&self, string: &mut String, ident: Ident, arg_exprs: &[Expr]) {
811 match ident {
812 Ident(live_id!(atan)) => {
813 if arg_exprs.len() == 2 {
814 write!(string, "atan2").unwrap();
815 }
816 else {
817 write!(string, "atan").unwrap();
818 }
819 }
820 Ident(live_id!(mod)) => {
821 write!(string, "fmod").unwrap();
822 }
823 Ident(live_id!(dFdx)) => {
824 write!(string, "ddx").unwrap();
825 }
826 Ident(live_id!(dFdy)) => {
827 write!(string, "ddy").unwrap();
828 }
829 Ident(live_id!(fract)) => {
830 write!(string, "frac").unwrap();
831 }
832 Ident(live_id!(mix)) => {
833 write!(string, "lerp").unwrap();
834 }
835 _ => {
836 write!(string, "{}", ident).unwrap()
837 }
838 }
839 }
840}