mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[naga] Introduce TypeInner::is_abstract utility function.
Define `TypeInner::is_abstract`, and let it take a type arena so that it can properly handle abstract arrays. Use this in compaction and in the WGSL front end's conversion code to recognize abstract types.
This commit is contained in:
@@ -114,24 +114,14 @@ pub fn compact(module: &mut crate::Module) {
|
||||
// abstract type as we do not want those reaching the validator.
|
||||
log::trace!("tracing named constants");
|
||||
for (handle, constant) in module.constants.iter() {
|
||||
if constant.name.is_some() {
|
||||
log::trace!("tracing constant {:?}", constant.name.as_ref().unwrap());
|
||||
// If the type is an array (of an array, etc) then we must check whether the
|
||||
// type of the innermost array's base type is abstract.
|
||||
let mut ty = constant.ty;
|
||||
while let crate::TypeInner::Array { base, .. } = module.types[ty].inner {
|
||||
ty = base;
|
||||
}
|
||||
if !module.types[ty]
|
||||
.inner
|
||||
.scalar()
|
||||
.is_some_and(|s| s.is_abstract())
|
||||
{
|
||||
module_tracer.constants_used.insert(handle);
|
||||
module_tracer.types_used.insert(constant.ty);
|
||||
module_tracer.global_expressions_used.insert(constant.init);
|
||||
}
|
||||
if constant.name.is_none() || module.types[constant.ty].inner.is_abstract(&module.types) {
|
||||
continue;
|
||||
}
|
||||
|
||||
log::trace!("tracing constant {:?}", constant.name.as_ref().unwrap());
|
||||
module_tracer.constants_used.insert(handle);
|
||||
module_tracer.types_used.insert(constant.ty);
|
||||
module_tracer.global_expressions_used.insert(constant.init);
|
||||
}
|
||||
|
||||
// We treat all named overrides as used by definition.
|
||||
|
||||
@@ -37,14 +37,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
|
||||
// rather than them being misreported as type conversion errors.
|
||||
// If the type is an array (of an array, etc) then we must check whether the
|
||||
// type of the innermost array's base type is abstract.
|
||||
let mut base_inner = expr_inner;
|
||||
while let crate::TypeInner::Array { base, .. } = *base_inner {
|
||||
base_inner = &types[base].inner;
|
||||
}
|
||||
if !base_inner
|
||||
.scalar()
|
||||
.is_some_and(|scalar| scalar.is_abstract())
|
||||
{
|
||||
if !expr_inner.is_abstract(types) {
|
||||
return Ok(expr);
|
||||
}
|
||||
|
||||
|
||||
@@ -281,4 +281,26 @@ impl crate::TypeInner {
|
||||
| crate::TypeInner::BindingArray { .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return true if `self` is an abstract type.
|
||||
///
|
||||
/// Use `types` to look up type handles. This is necessary to
|
||||
/// recognize abstract arrays.
|
||||
pub fn is_abstract(&self, types: &crate::UniqueArena<crate::Type>) -> bool {
|
||||
match *self {
|
||||
crate::TypeInner::Scalar(scalar)
|
||||
| crate::TypeInner::Vector { scalar, .. }
|
||||
| crate::TypeInner::Matrix { scalar, .. }
|
||||
| crate::TypeInner::Atomic(scalar) => scalar.is_abstract(),
|
||||
crate::TypeInner::Array { base, .. } => types[base].inner.is_abstract(types),
|
||||
crate::TypeInner::ValuePointer { .. }
|
||||
| crate::TypeInner::Pointer { .. }
|
||||
| crate::TypeInner::Struct { .. }
|
||||
| crate::TypeInner::Image { .. }
|
||||
| crate::TypeInner::Sampler { .. }
|
||||
| crate::TypeInner::AccelerationStructure
|
||||
| crate::TypeInner::RayQuery
|
||||
| crate::TypeInner::BindingArray { .. } => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user