@@ -47,8 +47,6 @@ pub enum AtomicError {
47
47
InvalidPointer ( Handle < crate :: Expression > ) ,
48
48
#[ error( "Operand {0:?} has invalid type." ) ]
49
49
InvalidOperand ( Handle < crate :: Expression > ) ,
50
- #[ error( "Result expression {0:?} has already been introduced earlier" ) ]
51
- ResultAlreadyInScope ( Handle < crate :: Expression > ) ,
52
50
#[ error( "Result type for {0:?} doesn't match the statement" ) ]
53
51
ResultTypeMismatch ( Handle < crate :: Expression > ) ,
54
52
}
@@ -131,6 +129,14 @@ pub enum FunctionError {
131
129
} ,
132
130
#[ error( "Atomic operation is invalid" ) ]
133
131
InvalidAtomic ( #[ from] AtomicError ) ,
132
+ #[ error( "Ray Query {0:?} is not a local variable" ) ]
133
+ InvalidRayQueryExpression ( Handle < crate :: Expression > ) ,
134
+ #[ error( "Acceleration structure {0:?} is not a matching expression" ) ]
135
+ InvalidAccelerationStructure ( Handle < crate :: Expression > ) ,
136
+ #[ error( "Ray descriptor {0:?} is not a matching expression" ) ]
137
+ InvalidRayDescriptor ( Handle < crate :: Expression > ) ,
138
+ #[ error( "Ray Query {0:?} does not have a matching type" ) ]
139
+ InvalidRayQueryType ( Handle < crate :: Type > ) ,
134
140
#[ error(
135
141
"Required uniformity of control flow for {0:?} in {1:?} is not fulfilled because of {2:?}"
136
142
) ]
@@ -169,8 +175,10 @@ struct BlockContext<'a> {
169
175
info : & ' a FunctionInfo ,
170
176
expressions : & ' a Arena < crate :: Expression > ,
171
177
types : & ' a UniqueArena < crate :: Type > ,
178
+ local_vars : & ' a Arena < crate :: LocalVariable > ,
172
179
global_vars : & ' a Arena < crate :: GlobalVariable > ,
173
180
functions : & ' a Arena < crate :: Function > ,
181
+ special_types : & ' a crate :: SpecialTypes ,
174
182
prev_infos : & ' a [ FunctionInfo ] ,
175
183
return_type : Option < Handle < crate :: Type > > ,
176
184
}
@@ -188,8 +196,10 @@ impl<'a> BlockContext<'a> {
188
196
info,
189
197
expressions : & fun. expressions ,
190
198
types : & module. types ,
199
+ local_vars : & fun. local_variables ,
191
200
global_vars : & module. global_variables ,
192
201
functions : & module. functions ,
202
+ special_types : & module. special_types ,
193
203
prev_infos,
194
204
return_type : fun. result . as_ref ( ) . map ( |fr| fr. ty ) ,
195
205
}
@@ -299,6 +309,21 @@ impl super::Validator {
299
309
Ok ( callee_info. available_stages )
300
310
}
301
311
312
+ #[ cfg( feature = "validate" ) ]
313
+ fn emit_expression (
314
+ & mut self ,
315
+ handle : Handle < crate :: Expression > ,
316
+ context : & BlockContext ,
317
+ ) -> Result < ( ) , WithSpan < FunctionError > > {
318
+ if self . valid_expression_set . insert ( handle. index ( ) ) {
319
+ self . valid_expression_list . push ( handle) ;
320
+ Ok ( ( ) )
321
+ } else {
322
+ Err ( FunctionError :: ExpressionAlreadyInScope ( handle)
323
+ . with_span_handle ( handle, context. expressions ) )
324
+ }
325
+ }
326
+
302
327
#[ cfg( feature = "validate" ) ]
303
328
fn validate_atomic (
304
329
& mut self ,
@@ -347,13 +372,7 @@ impl super::Validator {
347
372
}
348
373
}
349
374
350
- if self . valid_expression_set . insert ( result. index ( ) ) {
351
- self . valid_expression_list . push ( result) ;
352
- } else {
353
- return Err ( AtomicError :: ResultAlreadyInScope ( result)
354
- . with_span_handle ( result, context. expressions )
355
- . into_other ( ) ) ;
356
- }
375
+ self . emit_expression ( result, context) ?;
357
376
match context. expressions [ result] {
358
377
crate :: Expression :: AtomicResult { ty, comparison }
359
378
if {
@@ -401,12 +420,7 @@ impl super::Validator {
401
420
match * statement {
402
421
S :: Emit ( ref range) => {
403
422
for handle in range. clone ( ) {
404
- if self . valid_expression_set . insert ( handle. index ( ) ) {
405
- self . valid_expression_list . push ( handle) ;
406
- } else {
407
- return Err ( FunctionError :: ExpressionAlreadyInScope ( handle)
408
- . with_span_handle ( handle, context. expressions ) ) ;
409
- }
423
+ self . emit_expression ( handle, context) ?;
410
424
}
411
425
}
412
426
S :: Block ( ref block) => {
@@ -807,8 +821,55 @@ impl super::Validator {
807
821
} => {
808
822
self . validate_atomic ( pointer, fun, value, result, context) ?;
809
823
}
810
- S :: RayQuery { query : _, fun : _ } => {
811
- //TODO
824
+ S :: RayQuery { query, ref fun } => {
825
+ let query_var = match * context. get_expression ( query) {
826
+ crate :: Expression :: LocalVariable ( var) => & context. local_vars [ var] ,
827
+ ref other => {
828
+ log:: error!( "Unexpected ray query expression {other:?}" ) ;
829
+ return Err ( FunctionError :: InvalidRayQueryExpression ( query)
830
+ . with_span_static ( span, "invalid query expression" ) ) ;
831
+ }
832
+ } ;
833
+ match context. types [ query_var. ty ] . inner {
834
+ Ti :: RayQuery => { }
835
+ ref other => {
836
+ log:: error!( "Unexpected ray query type {other:?}" ) ;
837
+ return Err ( FunctionError :: InvalidRayQueryType ( query_var. ty )
838
+ . with_span_static ( span, "invalid query type" ) ) ;
839
+ }
840
+ }
841
+ match * fun {
842
+ crate :: RayQueryFunction :: Initialize {
843
+ acceleration_structure,
844
+ descriptor,
845
+ } => {
846
+ match * context
847
+ . resolve_type ( acceleration_structure, & self . valid_expression_set ) ?
848
+ {
849
+ Ti :: AccelerationStructure => { }
850
+ _ => {
851
+ return Err ( FunctionError :: InvalidAccelerationStructure (
852
+ acceleration_structure,
853
+ )
854
+ . with_span_static ( span, "invalid acceleration structure" ) )
855
+ }
856
+ }
857
+ let desc_ty_given =
858
+ context. resolve_type ( descriptor, & self . valid_expression_set ) ?;
859
+ let desc_ty_expected = context
860
+ . special_types
861
+ . ray_desc
862
+ . map ( |handle| & context. types [ handle] . inner ) ;
863
+ if Some ( desc_ty_given) != desc_ty_expected {
864
+ return Err ( FunctionError :: InvalidRayDescriptor ( descriptor)
865
+ . with_span_static ( span, "invalid ray descriptor" ) ) ;
866
+ }
867
+ }
868
+ crate :: RayQueryFunction :: Proceed { result } => {
869
+ self . emit_expression ( result, context) ?;
870
+ }
871
+ crate :: RayQueryFunction :: Terminate => { }
872
+ }
812
873
}
813
874
}
814
875
}
0 commit comments