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