mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
ray query: validation, better test
This commit is contained in:
@@ -35,6 +35,8 @@ pub enum ExpressionError {
|
||||
InvalidPointerType(Handle<crate::Expression>),
|
||||
#[error("Array length of {0:?} can't be done")]
|
||||
InvalidArrayType(Handle<crate::Expression>),
|
||||
#[error("Get intersection of {0:?} can't be done")]
|
||||
InvalidRayQueryType(Handle<crate::Expression>),
|
||||
#[error("Splatting {0:?} can't be done")]
|
||||
InvalidSplatType(Handle<crate::Expression>),
|
||||
#[error("Swizzling {0:?} can't be done")]
|
||||
@@ -1427,7 +1429,26 @@ impl super::Validator {
|
||||
return Err(ExpressionError::InvalidArrayType(expr));
|
||||
}
|
||||
},
|
||||
E::RayQueryProceedResult | E::RayQueryGetIntersection { .. } => ShaderStages::all(),
|
||||
E::RayQueryProceedResult => ShaderStages::all(),
|
||||
E::RayQueryGetIntersection {
|
||||
query,
|
||||
committed: _,
|
||||
} => match resolver[query] {
|
||||
Ti::Pointer {
|
||||
base,
|
||||
space: crate::AddressSpace::Function,
|
||||
} => match resolver.types[base].inner {
|
||||
Ti::RayQuery => ShaderStages::all(),
|
||||
ref other => {
|
||||
log::error!("Intersection result of a pointer to {:?}", other);
|
||||
return Err(ExpressionError::InvalidRayQueryType(query));
|
||||
}
|
||||
},
|
||||
ref other => {
|
||||
log::error!("Intersection result of {:?}", other);
|
||||
return Err(ExpressionError::InvalidRayQueryType(query));
|
||||
}
|
||||
},
|
||||
};
|
||||
Ok(stages)
|
||||
}
|
||||
|
||||
@@ -47,8 +47,6 @@ pub enum AtomicError {
|
||||
InvalidPointer(Handle<crate::Expression>),
|
||||
#[error("Operand {0:?} has invalid type.")]
|
||||
InvalidOperand(Handle<crate::Expression>),
|
||||
#[error("Result expression {0:?} has already been introduced earlier")]
|
||||
ResultAlreadyInScope(Handle<crate::Expression>),
|
||||
#[error("Result type for {0:?} doesn't match the statement")]
|
||||
ResultTypeMismatch(Handle<crate::Expression>),
|
||||
}
|
||||
@@ -131,6 +129,14 @@ pub enum FunctionError {
|
||||
},
|
||||
#[error("Atomic operation is invalid")]
|
||||
InvalidAtomic(#[from] AtomicError),
|
||||
#[error("Ray Query {0:?} is not a local variable")]
|
||||
InvalidRayQueryExpression(Handle<crate::Expression>),
|
||||
#[error("Acceleration structure {0:?} is not a matching expression")]
|
||||
InvalidAccelerationStructure(Handle<crate::Expression>),
|
||||
#[error("Ray descriptor {0:?} is not a matching expression")]
|
||||
InvalidRayDescriptor(Handle<crate::Expression>),
|
||||
#[error("Ray Query {0:?} does not have a matching type")]
|
||||
InvalidRayQueryType(Handle<crate::Type>),
|
||||
#[error(
|
||||
"Required uniformity of control flow for {0:?} in {1:?} is not fulfilled because of {2:?}"
|
||||
)]
|
||||
@@ -169,8 +175,10 @@ struct BlockContext<'a> {
|
||||
info: &'a FunctionInfo,
|
||||
expressions: &'a Arena<crate::Expression>,
|
||||
types: &'a UniqueArena<crate::Type>,
|
||||
local_vars: &'a Arena<crate::LocalVariable>,
|
||||
global_vars: &'a Arena<crate::GlobalVariable>,
|
||||
functions: &'a Arena<crate::Function>,
|
||||
special_types: &'a crate::SpecialTypes,
|
||||
prev_infos: &'a [FunctionInfo],
|
||||
return_type: Option<Handle<crate::Type>>,
|
||||
}
|
||||
@@ -188,8 +196,10 @@ impl<'a> BlockContext<'a> {
|
||||
info,
|
||||
expressions: &fun.expressions,
|
||||
types: &module.types,
|
||||
local_vars: &fun.local_variables,
|
||||
global_vars: &module.global_variables,
|
||||
functions: &module.functions,
|
||||
special_types: &module.special_types,
|
||||
prev_infos,
|
||||
return_type: fun.result.as_ref().map(|fr| fr.ty),
|
||||
}
|
||||
@@ -299,6 +309,21 @@ impl super::Validator {
|
||||
Ok(callee_info.available_stages)
|
||||
}
|
||||
|
||||
#[cfg(feature = "validate")]
|
||||
fn emit_expression(
|
||||
&mut self,
|
||||
handle: Handle<crate::Expression>,
|
||||
context: &BlockContext,
|
||||
) -> Result<(), WithSpan<FunctionError>> {
|
||||
if self.valid_expression_set.insert(handle.index()) {
|
||||
self.valid_expression_list.push(handle);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(FunctionError::ExpressionAlreadyInScope(handle)
|
||||
.with_span_handle(handle, context.expressions))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "validate")]
|
||||
fn validate_atomic(
|
||||
&mut self,
|
||||
@@ -347,13 +372,7 @@ impl super::Validator {
|
||||
}
|
||||
}
|
||||
|
||||
if self.valid_expression_set.insert(result.index()) {
|
||||
self.valid_expression_list.push(result);
|
||||
} else {
|
||||
return Err(AtomicError::ResultAlreadyInScope(result)
|
||||
.with_span_handle(result, context.expressions)
|
||||
.into_other());
|
||||
}
|
||||
self.emit_expression(result, context)?;
|
||||
match context.expressions[result] {
|
||||
crate::Expression::AtomicResult { ty, comparison }
|
||||
if {
|
||||
@@ -401,12 +420,7 @@ impl super::Validator {
|
||||
match *statement {
|
||||
S::Emit(ref range) => {
|
||||
for handle in range.clone() {
|
||||
if self.valid_expression_set.insert(handle.index()) {
|
||||
self.valid_expression_list.push(handle);
|
||||
} else {
|
||||
return Err(FunctionError::ExpressionAlreadyInScope(handle)
|
||||
.with_span_handle(handle, context.expressions));
|
||||
}
|
||||
self.emit_expression(handle, context)?;
|
||||
}
|
||||
}
|
||||
S::Block(ref block) => {
|
||||
@@ -807,8 +821,55 @@ impl super::Validator {
|
||||
} => {
|
||||
self.validate_atomic(pointer, fun, value, result, context)?;
|
||||
}
|
||||
S::RayQuery { query: _, fun: _ } => {
|
||||
//TODO
|
||||
S::RayQuery { query, ref fun } => {
|
||||
let query_var = match *context.get_expression(query) {
|
||||
crate::Expression::LocalVariable(var) => &context.local_vars[var],
|
||||
ref other => {
|
||||
log::error!("Unexpected ray query expression {other:?}");
|
||||
return Err(FunctionError::InvalidRayQueryExpression(query)
|
||||
.with_span_static(span, "invalid query expression"));
|
||||
}
|
||||
};
|
||||
match context.types[query_var.ty].inner {
|
||||
Ti::RayQuery => {}
|
||||
ref other => {
|
||||
log::error!("Unexpected ray query type {other:?}");
|
||||
return Err(FunctionError::InvalidRayQueryType(query_var.ty)
|
||||
.with_span_static(span, "invalid query type"));
|
||||
}
|
||||
}
|
||||
match *fun {
|
||||
crate::RayQueryFunction::Initialize {
|
||||
acceleration_structure,
|
||||
descriptor,
|
||||
} => {
|
||||
match *context
|
||||
.resolve_type(acceleration_structure, &self.valid_expression_set)?
|
||||
{
|
||||
Ti::AccelerationStructure => {}
|
||||
_ => {
|
||||
return Err(FunctionError::InvalidAccelerationStructure(
|
||||
acceleration_structure,
|
||||
)
|
||||
.with_span_static(span, "invalid acceleration structure"))
|
||||
}
|
||||
}
|
||||
let desc_ty_given =
|
||||
context.resolve_type(descriptor, &self.valid_expression_set)?;
|
||||
let desc_ty_expected = context
|
||||
.special_types
|
||||
.ray_desc
|
||||
.map(|handle| &context.types[handle].inner);
|
||||
if Some(desc_ty_given) != desc_ty_expected {
|
||||
return Err(FunctionError::InvalidRayDescriptor(descriptor)
|
||||
.with_span_static(span, "invalid ray descriptor"));
|
||||
}
|
||||
}
|
||||
crate::RayQueryFunction::Proceed { result } => {
|
||||
self.emit_expression(result, context)?;
|
||||
}
|
||||
crate::RayQueryFunction::Terminate => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user