1 use super::Error;
2 use crate::arena::{Arena, Handle};
3
make_scalar_inner(kind: crate::ScalarKind, width: crate::Bytes) -> crate::ConstantInner4 fn make_scalar_inner(kind: crate::ScalarKind, width: crate::Bytes) -> crate::ConstantInner {
5 crate::ConstantInner::Scalar {
6 width,
7 value: match kind {
8 crate::ScalarKind::Uint => crate::ScalarValue::Uint(0),
9 crate::ScalarKind::Sint => crate::ScalarValue::Sint(0),
10 crate::ScalarKind::Float => crate::ScalarValue::Float(0.0),
11 crate::ScalarKind::Bool => crate::ScalarValue::Bool(false),
12 },
13 }
14 }
15
generate_null_constant( ty: Handle<crate::Type>, type_arena: &mut Arena<crate::Type>, constant_arena: &mut Arena<crate::Constant>, ) -> Result<crate::ConstantInner, Error>16 pub fn generate_null_constant(
17 ty: Handle<crate::Type>,
18 type_arena: &mut Arena<crate::Type>,
19 constant_arena: &mut Arena<crate::Constant>,
20 ) -> Result<crate::ConstantInner, Error> {
21 let inner = match type_arena[ty].inner {
22 crate::TypeInner::Scalar { kind, width } => make_scalar_inner(kind, width),
23 crate::TypeInner::Vector { size, kind, width } => {
24 let mut components = Vec::with_capacity(size as usize);
25 for _ in 0..size as usize {
26 components.push(constant_arena.fetch_or_append(crate::Constant {
27 name: None,
28 specialization: None,
29 inner: make_scalar_inner(kind, width),
30 }));
31 }
32 crate::ConstantInner::Composite { ty, components }
33 }
34 crate::TypeInner::Matrix {
35 columns,
36 rows,
37 width,
38 } => {
39 let vector_ty = type_arena.fetch_or_append(crate::Type {
40 name: None,
41 inner: crate::TypeInner::Vector {
42 kind: crate::ScalarKind::Float,
43 size: rows,
44 width,
45 },
46 });
47 let vector_inner = generate_null_constant(vector_ty, type_arena, constant_arena)?;
48 let vector_handle = constant_arena.fetch_or_append(crate::Constant {
49 name: None,
50 specialization: None,
51 inner: vector_inner,
52 });
53 crate::ConstantInner::Composite {
54 ty,
55 components: vec![vector_handle; columns as usize],
56 }
57 }
58 crate::TypeInner::Struct { ref members, .. } => {
59 let mut components = Vec::with_capacity(members.len());
60 // copy out the types to avoid borrowing `members`
61 let member_tys = members.iter().map(|member| member.ty).collect::<Vec<_>>();
62 for member_ty in member_tys {
63 let inner = generate_null_constant(member_ty, type_arena, constant_arena)?;
64 components.push(constant_arena.fetch_or_append(crate::Constant {
65 name: None,
66 specialization: None,
67 inner,
68 }));
69 }
70 crate::ConstantInner::Composite { ty, components }
71 }
72 crate::TypeInner::Array {
73 base,
74 size: crate::ArraySize::Constant(handle),
75 ..
76 } => {
77 let size = constant_arena[handle]
78 .to_array_length()
79 .ok_or(Error::InvalidArraySize(handle))?;
80 let inner = generate_null_constant(base, type_arena, constant_arena)?;
81 let value = constant_arena.fetch_or_append(crate::Constant {
82 name: None,
83 specialization: None,
84 inner,
85 });
86 crate::ConstantInner::Composite {
87 ty,
88 components: vec![value; size as usize],
89 }
90 }
91 ref other => {
92 log::warn!("null constant type {:?}", other);
93 return Err(Error::UnsupportedType(ty));
94 }
95 };
96 Ok(inner)
97 }
98
99 /// Create a default value for an output built-in.
generate_default_built_in( built_in: Option<crate::BuiltIn>, ty: Handle<crate::Type>, type_arena: &mut Arena<crate::Type>, constant_arena: &mut Arena<crate::Constant>, ) -> Result<Handle<crate::Constant>, Error>100 pub fn generate_default_built_in(
101 built_in: Option<crate::BuiltIn>,
102 ty: Handle<crate::Type>,
103 type_arena: &mut Arena<crate::Type>,
104 constant_arena: &mut Arena<crate::Constant>,
105 ) -> Result<Handle<crate::Constant>, Error> {
106 let inner = match built_in {
107 Some(crate::BuiltIn::Position) => {
108 let zero = constant_arena.fetch_or_append(crate::Constant {
109 name: None,
110 specialization: None,
111 inner: crate::ConstantInner::Scalar {
112 value: crate::ScalarValue::Float(0.0),
113 width: 4,
114 },
115 });
116 let one = constant_arena.fetch_or_append(crate::Constant {
117 name: None,
118 specialization: None,
119 inner: crate::ConstantInner::Scalar {
120 value: crate::ScalarValue::Float(1.0),
121 width: 4,
122 },
123 });
124 crate::ConstantInner::Composite {
125 ty,
126 components: vec![zero, zero, zero, one],
127 }
128 }
129 Some(crate::BuiltIn::PointSize) => crate::ConstantInner::Scalar {
130 value: crate::ScalarValue::Float(1.0),
131 width: 4,
132 },
133 Some(crate::BuiltIn::FragDepth) => crate::ConstantInner::Scalar {
134 value: crate::ScalarValue::Float(0.0),
135 width: 4,
136 },
137 Some(crate::BuiltIn::SampleMask) => crate::ConstantInner::Scalar {
138 value: crate::ScalarValue::Uint(!0),
139 width: 4,
140 },
141 //Note: `crate::BuiltIn::ClipDistance` is intentionally left for the default path
142 _ => generate_null_constant(ty, type_arena, constant_arena)?,
143 };
144 Ok(constant_arena.fetch_or_append(crate::Constant {
145 name: None,
146 specialization: None,
147 inner,
148 }))
149 }
150