6
6
//! - expression reference counts
7
7
8
8
use super :: { ExpressionError , FunctionError , ModuleInfo , ShaderStages , ValidationFlags } ;
9
+ use crate :: diagnostic_filter:: DiagnosticFilterNode ;
9
10
use crate :: span:: { AddSpan as _, WithSpan } ;
10
11
use crate :: {
11
12
arena:: { Arena , Handle } ,
@@ -289,6 +290,13 @@ pub struct FunctionInfo {
289
290
290
291
/// Indicates that the function is using dual source blending.
291
292
pub dual_source_blending : bool ,
293
+
294
+ /// The leaf of all module-wide diagnostic filter rules tree parsed from directives in this
295
+ /// module.
296
+ ///
297
+ /// See [`DiagnosticFilterNode`] for details on how the tree is represented and used in
298
+ /// validation.
299
+ diagnostic_filter_leaf : Option < Handle < DiagnosticFilterNode > > ,
292
300
}
293
301
294
302
impl FunctionInfo {
@@ -820,12 +828,14 @@ impl FunctionInfo {
820
828
/// Returns a `NonUniformControlFlow` error if any of the expressions in the block
821
829
/// require uniformity, but the current flow is non-uniform.
822
830
#[ allow( clippy:: or_fun_call) ]
831
+ #[ allow( clippy:: only_used_in_recursion) ]
823
832
fn process_block (
824
833
& mut self ,
825
834
statements : & crate :: Block ,
826
835
other_functions : & [ FunctionInfo ] ,
827
836
mut disruptor : Option < UniformityDisruptor > ,
828
837
expression_arena : & Arena < crate :: Expression > ,
838
+ diagnostic_filter_arena : & Arena < DiagnosticFilterNode > ,
829
839
) -> Result < FunctionUniformity , WithSpan < FunctionError > > {
830
840
use crate :: Statement as S ;
831
841
@@ -901,9 +911,13 @@ impl FunctionInfo {
901
911
exit : ExitFlags :: empty ( ) ,
902
912
}
903
913
}
904
- S :: Block ( ref b) => {
905
- self . process_block ( b, other_functions, disruptor, expression_arena) ?
906
- }
914
+ S :: Block ( ref b) => self . process_block (
915
+ b,
916
+ other_functions,
917
+ disruptor,
918
+ expression_arena,
919
+ diagnostic_filter_arena,
920
+ ) ?,
907
921
S :: If {
908
922
condition,
909
923
ref accept,
@@ -917,12 +931,14 @@ impl FunctionInfo {
917
931
other_functions,
918
932
branch_disruptor,
919
933
expression_arena,
934
+ diagnostic_filter_arena,
920
935
) ?;
921
936
let reject_uniformity = self . process_block (
922
937
reject,
923
938
other_functions,
924
939
branch_disruptor,
925
940
expression_arena,
941
+ diagnostic_filter_arena,
926
942
) ?;
927
943
accept_uniformity | reject_uniformity
928
944
}
@@ -941,6 +957,7 @@ impl FunctionInfo {
941
957
other_functions,
942
958
case_disruptor,
943
959
expression_arena,
960
+ diagnostic_filter_arena,
944
961
) ?;
945
962
case_disruptor = if case. fall_through {
946
963
case_disruptor. or ( case_uniformity. exit_disruptor ( ) )
@@ -956,14 +973,20 @@ impl FunctionInfo {
956
973
ref continuing,
957
974
break_if,
958
975
} => {
959
- let body_uniformity =
960
- self . process_block ( body, other_functions, disruptor, expression_arena) ?;
976
+ let body_uniformity = self . process_block (
977
+ body,
978
+ other_functions,
979
+ disruptor,
980
+ expression_arena,
981
+ diagnostic_filter_arena,
982
+ ) ?;
961
983
let continuing_disruptor = disruptor. or ( body_uniformity. exit_disruptor ( ) ) ;
962
984
let continuing_uniformity = self . process_block (
963
985
continuing,
964
986
other_functions,
965
987
continuing_disruptor,
966
988
expression_arena,
989
+ diagnostic_filter_arena,
967
990
) ?;
968
991
if let Some ( expr) = break_if {
969
992
let _ = self . add_ref ( expr) ;
@@ -1117,6 +1140,7 @@ impl ModuleInfo {
1117
1140
expressions : vec ! [ ExpressionInfo :: new( ) ; fun. expressions. len( ) ] . into_boxed_slice ( ) ,
1118
1141
sampling : crate :: FastHashSet :: default ( ) ,
1119
1142
dual_source_blending : false ,
1143
+ diagnostic_filter_leaf : module. diagnostic_filter_leaf ,
1120
1144
} ;
1121
1145
let resolve_context =
1122
1146
ResolveContext :: with_locals ( module, & fun. local_variables , & fun. arguments ) ;
@@ -1140,7 +1164,13 @@ impl ModuleInfo {
1140
1164
}
1141
1165
}
1142
1166
1143
- let uniformity = info. process_block ( & fun. body , & self . functions , None , & fun. expressions ) ?;
1167
+ let uniformity = info. process_block (
1168
+ & fun. body ,
1169
+ & self . functions ,
1170
+ None ,
1171
+ & fun. expressions ,
1172
+ & module. diagnostic_filters ,
1173
+ ) ?;
1144
1174
info. uniformity = uniformity. result ;
1145
1175
info. may_kill = uniformity. exit . contains ( ExitFlags :: MAY_KILL ) ;
1146
1176
@@ -1230,6 +1260,7 @@ fn uniform_control_flow() {
1230
1260
expressions : vec ! [ ExpressionInfo :: new( ) ; expressions. len( ) ] . into_boxed_slice ( ) ,
1231
1261
sampling : crate :: FastHashSet :: default ( ) ,
1232
1262
dual_source_blending : false ,
1263
+ diagnostic_filter_leaf : None ,
1233
1264
} ;
1234
1265
let resolve_context = ResolveContext {
1235
1266
constants : & Arena :: new ( ) ,
@@ -1276,7 +1307,8 @@ fn uniform_control_flow() {
1276
1307
& vec![ stmt_emit1, stmt_if_uniform] . into( ) ,
1277
1308
& [ ] ,
1278
1309
None ,
1279
- & expressions
1310
+ & expressions,
1311
+ & Arena :: new( ) ,
1280
1312
) ,
1281
1313
Ok ( FunctionUniformity {
1282
1314
result: Uniformity {
@@ -1308,6 +1340,7 @@ fn uniform_control_flow() {
1308
1340
& [ ] ,
1309
1341
None ,
1310
1342
& expressions,
1343
+ & Arena :: new ( ) ,
1311
1344
) ;
1312
1345
if DISABLE_UNIFORMITY_REQ_FOR_FRAGMENT_STAGE {
1313
1346
assert_eq ! ( info[ derivative_expr] . ref_count, 2 ) ;
@@ -1335,7 +1368,8 @@ fn uniform_control_flow() {
1335
1368
& vec![ stmt_emit3, stmt_return_non_uniform] . into( ) ,
1336
1369
& [ ] ,
1337
1370
Some ( UniformityDisruptor :: Return ) ,
1338
- & expressions
1371
+ & expressions,
1372
+ & Arena :: new( ) ,
1339
1373
) ,
1340
1374
Ok ( FunctionUniformity {
1341
1375
result: Uniformity {
@@ -1362,7 +1396,8 @@ fn uniform_control_flow() {
1362
1396
& vec![ stmt_emit4, stmt_assign, stmt_kill, stmt_return_pointer] . into( ) ,
1363
1397
& [ ] ,
1364
1398
Some ( UniformityDisruptor :: Discard ) ,
1365
- & expressions
1399
+ & expressions,
1400
+ & Arena :: new( ) ,
1366
1401
) ,
1367
1402
Ok ( FunctionUniformity {
1368
1403
result: Uniformity {
0 commit comments