@@ -268,10 +268,10 @@ impl ShaderProcessor {
268
268
for line in shader. split ( '\n' ) {
269
269
if let Some ( cap) = self . ifdef_regex . captures ( line) {
270
270
let def = cap. get ( 1 ) . unwrap ( ) ;
271
- scopes. push ( shader_defs. contains ( def. as_str ( ) ) ) ;
271
+ scopes. push ( * scopes . last ( ) . unwrap ( ) && shader_defs. contains ( def. as_str ( ) ) ) ;
272
272
} else if let Some ( cap) = self . ifndef_regex . captures ( line) {
273
273
let def = cap. get ( 1 ) . unwrap ( ) ;
274
- scopes. push ( !shader_defs. contains ( def. as_str ( ) ) ) ;
274
+ scopes. push ( * scopes . last ( ) . unwrap ( ) && !shader_defs. contains ( def. as_str ( ) ) ) ;
275
275
} else if self . endif_regex . is_match ( line) {
276
276
scopes. pop ( ) ;
277
277
if scopes. is_empty ( ) {
@@ -315,6 +315,38 @@ struct VertexOutput {
315
315
[[builtin(position)]] position: vec4<f32>;
316
316
};
317
317
318
+ [[stage(vertex)]]
319
+ fn vertex(
320
+ [[location(0)]] vertex_position: vec3<f32>,
321
+ [[location(1)]] vertex_uv: vec2<f32>
322
+ ) -> VertexOutput {
323
+ var out: VertexOutput;
324
+ out.uv = vertex_uv;
325
+ out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
326
+ return out;
327
+ }
328
+ " ;
329
+ const WGSL_NESTED_IFDEF : & str = r"
330
+ [[block]]
331
+ struct View {
332
+ view_proj: mat4x4<f32>;
333
+ world_position: vec3<f32>;
334
+ };
335
+ [[group(0), binding(0)]]
336
+ var<uniform> view: View;
337
+
338
+ # ifdef TEXTURE
339
+ # ifdef ATTRIBUTE
340
+ [[group(1), binding(0)]]
341
+ var sprite_texture: texture_2d<f32>;
342
+ # endif
343
+ # endif
344
+
345
+ struct VertexOutput {
346
+ [[location(0)]] uv: vec2<f32>;
347
+ [[builtin(position)]] position: vec4<f32>;
348
+ };
349
+
318
350
[[stage(vertex)]]
319
351
fn vertex(
320
352
[[location(0)]] vertex_position: vec3<f32>,
@@ -432,4 +464,151 @@ fn foo() { }
432
464
let result = processor. process_str ( INPUT , & [ ] ) . unwrap ( ) ;
433
465
assert_eq ! ( result, INPUT ) ;
434
466
}
467
+
468
+ #[ test]
469
+ fn process_nested_shader_def_outer_defined_inner_not ( ) {
470
+ #[ rustfmt:: skip]
471
+ const EXPECTED : & str = r"
472
+ [[block]]
473
+ struct View {
474
+ view_proj: mat4x4<f32>;
475
+ world_position: vec3<f32>;
476
+ };
477
+ [[group(0), binding(0)]]
478
+ var<uniform> view: View;
479
+
480
+
481
+ struct VertexOutput {
482
+ [[location(0)]] uv: vec2<f32>;
483
+ [[builtin(position)]] position: vec4<f32>;
484
+ };
485
+
486
+ [[stage(vertex)]]
487
+ fn vertex(
488
+ [[location(0)]] vertex_position: vec3<f32>,
489
+ [[location(1)]] vertex_uv: vec2<f32>
490
+ ) -> VertexOutput {
491
+ var out: VertexOutput;
492
+ out.uv = vertex_uv;
493
+ out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
494
+ return out;
495
+ }
496
+ " ;
497
+ let processor = ShaderProcessor :: default ( ) ;
498
+ let result = processor
499
+ . process_str ( WGSL_NESTED_IFDEF , & [ "TEXTURE" . to_string ( ) ] )
500
+ . unwrap ( ) ;
501
+ assert_eq ! ( result, EXPECTED ) ;
502
+ }
503
+
504
+ #[ test]
505
+ fn process_nested_shader_def_neither_defined ( ) {
506
+ #[ rustfmt:: skip]
507
+ const EXPECTED : & str = r"
508
+ [[block]]
509
+ struct View {
510
+ view_proj: mat4x4<f32>;
511
+ world_position: vec3<f32>;
512
+ };
513
+ [[group(0), binding(0)]]
514
+ var<uniform> view: View;
515
+
516
+
517
+ struct VertexOutput {
518
+ [[location(0)]] uv: vec2<f32>;
519
+ [[builtin(position)]] position: vec4<f32>;
520
+ };
521
+
522
+ [[stage(vertex)]]
523
+ fn vertex(
524
+ [[location(0)]] vertex_position: vec3<f32>,
525
+ [[location(1)]] vertex_uv: vec2<f32>
526
+ ) -> VertexOutput {
527
+ var out: VertexOutput;
528
+ out.uv = vertex_uv;
529
+ out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
530
+ return out;
531
+ }
532
+ " ;
533
+ let processor = ShaderProcessor :: default ( ) ;
534
+ let result = processor. process_str ( WGSL_NESTED_IFDEF , & [ ] ) . unwrap ( ) ;
535
+ assert_eq ! ( result, EXPECTED ) ;
536
+ }
537
+
538
+ #[ test]
539
+ fn process_nested_shader_def_inner_defined_outer_not ( ) {
540
+ #[ rustfmt:: skip]
541
+ const EXPECTED : & str = r"
542
+ [[block]]
543
+ struct View {
544
+ view_proj: mat4x4<f32>;
545
+ world_position: vec3<f32>;
546
+ };
547
+ [[group(0), binding(0)]]
548
+ var<uniform> view: View;
549
+
550
+
551
+ struct VertexOutput {
552
+ [[location(0)]] uv: vec2<f32>;
553
+ [[builtin(position)]] position: vec4<f32>;
554
+ };
555
+
556
+ [[stage(vertex)]]
557
+ fn vertex(
558
+ [[location(0)]] vertex_position: vec3<f32>,
559
+ [[location(1)]] vertex_uv: vec2<f32>
560
+ ) -> VertexOutput {
561
+ var out: VertexOutput;
562
+ out.uv = vertex_uv;
563
+ out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
564
+ return out;
565
+ }
566
+ " ;
567
+ let processor = ShaderProcessor :: default ( ) ;
568
+ let result = processor
569
+ . process_str ( WGSL_NESTED_IFDEF , & [ "ATTRIBUTE" . to_string ( ) ] )
570
+ . unwrap ( ) ;
571
+ assert_eq ! ( result, EXPECTED ) ;
572
+ }
573
+
574
+ #[ test]
575
+ fn process_nested_shader_def_both_defined ( ) {
576
+ #[ rustfmt:: skip]
577
+ const EXPECTED : & str = r"
578
+ [[block]]
579
+ struct View {
580
+ view_proj: mat4x4<f32>;
581
+ world_position: vec3<f32>;
582
+ };
583
+ [[group(0), binding(0)]]
584
+ var<uniform> view: View;
585
+
586
+ [[group(1), binding(0)]]
587
+ var sprite_texture: texture_2d<f32>;
588
+
589
+ struct VertexOutput {
590
+ [[location(0)]] uv: vec2<f32>;
591
+ [[builtin(position)]] position: vec4<f32>;
592
+ };
593
+
594
+ [[stage(vertex)]]
595
+ fn vertex(
596
+ [[location(0)]] vertex_position: vec3<f32>,
597
+ [[location(1)]] vertex_uv: vec2<f32>
598
+ ) -> VertexOutput {
599
+ var out: VertexOutput;
600
+ out.uv = vertex_uv;
601
+ out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
602
+ return out;
603
+ }
604
+ " ;
605
+ let processor = ShaderProcessor :: default ( ) ;
606
+ let result = processor
607
+ . process_str (
608
+ WGSL_NESTED_IFDEF ,
609
+ & [ "TEXTURE" . to_string ( ) , "ATTRIBUTE" . to_string ( ) ] ,
610
+ )
611
+ . unwrap ( ) ;
612
+ assert_eq ! ( result, EXPECTED ) ;
613
+ }
435
614
}
0 commit comments