summaryrefslogtreecommitdiffstats
path: root/third_party/rust/naga/src/front/spv/null.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/naga/src/front/spv/null.rs')
-rw-r--r--third_party/rust/naga/src/front/spv/null.rs175
1 files changed, 175 insertions, 0 deletions
diff --git a/third_party/rust/naga/src/front/spv/null.rs b/third_party/rust/naga/src/front/spv/null.rs
new file mode 100644
index 0000000000..85350c563e
--- /dev/null
+++ b/third_party/rust/naga/src/front/spv/null.rs
@@ -0,0 +1,175 @@
+use super::Error;
+use crate::arena::{Arena, Handle, UniqueArena};
+
+const fn make_scalar_inner(kind: crate::ScalarKind, width: crate::Bytes) -> crate::ConstantInner {
+ crate::ConstantInner::Scalar {
+ width,
+ value: match kind {
+ crate::ScalarKind::Uint => crate::ScalarValue::Uint(0),
+ crate::ScalarKind::Sint => crate::ScalarValue::Sint(0),
+ crate::ScalarKind::Float => crate::ScalarValue::Float(0.0),
+ crate::ScalarKind::Bool => crate::ScalarValue::Bool(false),
+ },
+ }
+}
+
+pub fn generate_null_constant(
+ ty: Handle<crate::Type>,
+ type_arena: &UniqueArena<crate::Type>,
+ constant_arena: &mut Arena<crate::Constant>,
+ span: crate::Span,
+) -> Result<crate::ConstantInner, Error> {
+ let inner = match type_arena[ty].inner {
+ crate::TypeInner::Scalar { kind, width } => make_scalar_inner(kind, width),
+ crate::TypeInner::Vector { size, kind, width } => {
+ let mut components = Vec::with_capacity(size as usize);
+ for _ in 0..size as usize {
+ components.push(constant_arena.fetch_or_append(
+ crate::Constant {
+ name: None,
+ specialization: None,
+ inner: make_scalar_inner(kind, width),
+ },
+ span,
+ ));
+ }
+ crate::ConstantInner::Composite { ty, components }
+ }
+ crate::TypeInner::Matrix {
+ columns,
+ rows,
+ width,
+ } => {
+ // If we successfully declared a matrix type, we have declared a vector type for it too.
+ let vector_ty = type_arena
+ .get(&crate::Type {
+ name: None,
+ inner: crate::TypeInner::Vector {
+ kind: crate::ScalarKind::Float,
+ size: rows,
+ width,
+ },
+ })
+ .unwrap();
+ let vector_inner = generate_null_constant(vector_ty, type_arena, constant_arena, span)?;
+ let vector_handle = constant_arena.fetch_or_append(
+ crate::Constant {
+ name: None,
+ specialization: None,
+ inner: vector_inner,
+ },
+ span,
+ );
+ crate::ConstantInner::Composite {
+ ty,
+ components: vec![vector_handle; columns as usize],
+ }
+ }
+ crate::TypeInner::Struct { ref members, .. } => {
+ let mut components = Vec::with_capacity(members.len());
+ // copy out the types to avoid borrowing `members`
+ let member_tys = members.iter().map(|member| member.ty).collect::<Vec<_>>();
+ for member_ty in member_tys {
+ let inner = generate_null_constant(member_ty, type_arena, constant_arena, span)?;
+ components.push(constant_arena.fetch_or_append(
+ crate::Constant {
+ name: None,
+ specialization: None,
+ inner,
+ },
+ span,
+ ));
+ }
+ crate::ConstantInner::Composite { ty, components }
+ }
+ crate::TypeInner::Array {
+ base,
+ size: crate::ArraySize::Constant(handle),
+ ..
+ } => {
+ let size = constant_arena[handle]
+ .to_array_length()
+ .ok_or(Error::InvalidArraySize(handle))?;
+ let inner = generate_null_constant(base, type_arena, constant_arena, span)?;
+ let value = constant_arena.fetch_or_append(
+ crate::Constant {
+ name: None,
+ specialization: None,
+ inner,
+ },
+ span,
+ );
+ crate::ConstantInner::Composite {
+ ty,
+ components: vec![value; size as usize],
+ }
+ }
+ ref other => {
+ log::warn!("null constant type {:?}", other);
+ return Err(Error::UnsupportedType(ty));
+ }
+ };
+ Ok(inner)
+}
+
+/// Create a default value for an output built-in.
+pub fn generate_default_built_in(
+ built_in: Option<crate::BuiltIn>,
+ ty: Handle<crate::Type>,
+ type_arena: &UniqueArena<crate::Type>,
+ constant_arena: &mut Arena<crate::Constant>,
+ span: crate::Span,
+) -> Result<Handle<crate::Constant>, Error> {
+ let inner = match built_in {
+ Some(crate::BuiltIn::Position { .. }) => {
+ let zero = constant_arena.fetch_or_append(
+ crate::Constant {
+ name: None,
+ specialization: None,
+ inner: crate::ConstantInner::Scalar {
+ value: crate::ScalarValue::Float(0.0),
+ width: 4,
+ },
+ },
+ span,
+ );
+ let one = constant_arena.fetch_or_append(
+ crate::Constant {
+ name: None,
+ specialization: None,
+ inner: crate::ConstantInner::Scalar {
+ value: crate::ScalarValue::Float(1.0),
+ width: 4,
+ },
+ },
+ span,
+ );
+ crate::ConstantInner::Composite {
+ ty,
+ components: vec![zero, zero, zero, one],
+ }
+ }
+ Some(crate::BuiltIn::PointSize) => crate::ConstantInner::Scalar {
+ value: crate::ScalarValue::Float(1.0),
+ width: 4,
+ },
+ Some(crate::BuiltIn::FragDepth) => crate::ConstantInner::Scalar {
+ value: crate::ScalarValue::Float(0.0),
+ width: 4,
+ },
+ Some(crate::BuiltIn::SampleMask) => crate::ConstantInner::Scalar {
+ value: crate::ScalarValue::Uint(u64::MAX),
+ width: 4,
+ },
+ //Note: `crate::BuiltIn::ClipDistance` is intentionally left for the default path
+ _ => generate_null_constant(ty, type_arena, constant_arena, span)?,
+ };
+ Ok(constant_arena.fetch_or_append(
+ crate::Constant {
+ name: None,
+ specialization: None,
+ inner,
+ },
+ span,
+ ))
+}