1pub mod call;
22pub mod ctor;
23
24mod call_ty;
25mod ops;
26mod ops_ty;
27
28pub use call_ty::type_builtin_fn;
29pub use ctor::{is_ctor, struct_ctor, type_ctor, typecheck_struct_ctor};
30pub use ops_ty::{type_binary_op, type_unary_op};
31
32pub(crate) use call_ty::*;
33pub(crate) use ops::Compwise;
34
35use itertools::Itertools;
36
37#[cfg(feature = "naga-ext")]
38use crate::tplt::AccelerationStructureTags;
39use crate::{
40 CallSignature, Error, Instance, ShaderStage,
41 syntax::{BinaryOperator, UnaryOperator},
42 tplt::{
43 ArrayTemplate, AtomicTemplate, BitcastTemplate, MatTemplate, PtrTemplate, TextureTemplate,
44 TpltParam, VecTemplate,
45 },
46 ty::{SamplerType, TextureType, Ty, Type},
47};
48
49type E = Error;
50
51pub fn call_builtin_fn(
61 name: &str,
62 tplt: Option<&[TpltParam]>,
63 args: &[Instance],
64 stage: ShaderStage,
65) -> Result<Option<Instance>, E> {
66 match (name, tplt, args) {
67 ("array", Some(t), []) => Instance::zero_value(&ArrayTemplate::parse(t)?.ty()),
69 ("array", Some(t), a) => {
70 let tplt = ArrayTemplate::parse(t)?;
71 ctor::array_t(
72 &tplt.inner_ty(),
73 tplt.n().ok_or(E::TemplateArgs("array"))?,
74 a,
75 )
76 }
77 ("array", None, a) => ctor::array(a),
78 ("bool", None, []) => Instance::zero_value(&Type::Bool),
79 ("bool", None, [a1]) => ctor::bool(a1),
80 ("i32", None, []) => Instance::zero_value(&Type::I32),
81 ("i32", None, [a1]) => ctor::i32(a1),
82 ("u32", None, []) => Instance::zero_value(&Type::U32),
83 ("u32", None, [a1]) => ctor::u32(a1),
84 ("f32", None, []) => Instance::zero_value(&Type::F32),
85 ("f32", None, [a1]) => ctor::f32(a1, stage),
86 ("f16", None, []) => Instance::zero_value(&Type::F16),
87 ("f16", None, [a1]) => ctor::f16(a1, stage),
88 ("mat2x2", Some(t), []) => Instance::zero_value(&MatTemplate::parse(t)?.ty(2, 2)),
89 ("mat2x2", Some(t), a) => ctor::mat_t(2, 2, MatTemplate::parse(t)?.inner_ty(), a, stage),
90 ("mat2x2", None, a) => ctor::mat(2, 2, a),
91 ("mat2x3", Some(t), []) => Instance::zero_value(&MatTemplate::parse(t)?.ty(2, 3)),
92 ("mat2x3", Some(t), a) => ctor::mat_t(2, 3, MatTemplate::parse(t)?.inner_ty(), a, stage),
93 ("mat2x3", None, a) => ctor::mat(2, 3, a),
94 ("mat2x4", Some(t), []) => Instance::zero_value(&MatTemplate::parse(t)?.ty(2, 4)),
95 ("mat2x4", Some(t), a) => ctor::mat_t(2, 4, MatTemplate::parse(t)?.inner_ty(), a, stage),
96 ("mat2x4", None, a) => ctor::mat(2, 4, a),
97 ("mat3x2", Some(t), []) => Instance::zero_value(&MatTemplate::parse(t)?.ty(3, 2)),
98 ("mat3x2", Some(t), a) => ctor::mat_t(3, 2, MatTemplate::parse(t)?.inner_ty(), a, stage),
99 ("mat3x2", None, a) => ctor::mat(3, 2, a),
100 ("mat3x3", Some(t), []) => Instance::zero_value(&MatTemplate::parse(t)?.ty(3, 3)),
101 ("mat3x3", Some(t), a) => ctor::mat_t(3, 3, MatTemplate::parse(t)?.inner_ty(), a, stage),
102 ("mat3x3", None, a) => ctor::mat(3, 3, a),
103 ("mat3x4", Some(t), []) => Instance::zero_value(&MatTemplate::parse(t)?.ty(3, 4)),
104 ("mat3x4", Some(t), a) => ctor::mat_t(3, 4, MatTemplate::parse(t)?.inner_ty(), a, stage),
105 ("mat3x4", None, a) => ctor::mat(3, 4, a),
106 ("mat4x2", Some(t), []) => Instance::zero_value(&MatTemplate::parse(t)?.ty(4, 2)),
107 ("mat4x2", Some(t), a) => ctor::mat_t(4, 2, MatTemplate::parse(t)?.inner_ty(), a, stage),
108 ("mat4x2", None, a) => ctor::mat(4, 2, a),
109 ("mat4x3", Some(t), []) => Instance::zero_value(&MatTemplate::parse(t)?.ty(4, 3)),
110 ("mat4x3", Some(t), a) => ctor::mat_t(4, 3, MatTemplate::parse(t)?.inner_ty(), a, stage),
111 ("mat4x3", None, a) => ctor::mat(4, 3, a),
112 ("mat4x4", Some(t), []) => Instance::zero_value(&MatTemplate::parse(t)?.ty(4, 4)),
113 ("mat4x4", Some(t), a) => ctor::mat_t(4, 4, MatTemplate::parse(t)?.inner_ty(), a, stage),
114 ("mat4x4", None, a) => ctor::mat(4, 4, a),
115 ("vec2", Some(t), []) => Instance::zero_value(&VecTemplate::parse(t)?.ty(2)),
116 ("vec2", Some(t), a) => ctor::vec_t(2, VecTemplate::parse(t)?.inner_ty(), a, stage),
117 ("vec2", None, a) => ctor::vec(2, a),
118 ("vec3", Some(t), []) => Instance::zero_value(&VecTemplate::parse(t)?.ty(3)),
119 ("vec3", Some(t), a) => ctor::vec_t(3, VecTemplate::parse(t)?.inner_ty(), a, stage),
120 ("vec3", None, a) => ctor::vec(3, a),
121 ("vec4", Some(t), []) => Instance::zero_value(&VecTemplate::parse(t)?.ty(4)),
122 ("vec4", Some(t), a) => ctor::vec_t(4, VecTemplate::parse(t)?.inner_ty(), a, stage),
123 ("vec4", None, a) => ctor::vec(4, a),
124 #[cfg(feature = "naga-ext")]
125 ("i64", None, []) => Instance::zero_value(&Type::I64),
126 #[cfg(feature = "naga-ext")]
127 ("i64", None, [a1]) => ctor::i64(a1),
128 #[cfg(feature = "naga-ext")]
129 ("u64", None, []) => Instance::zero_value(&Type::U64),
130 #[cfg(feature = "naga-ext")]
131 ("u64", None, [a1]) => ctor::u64(a1),
132 #[cfg(feature = "naga-ext")]
133 ("f64", None, []) => Instance::zero_value(&Type::F64),
134 #[cfg(feature = "naga-ext")]
135 ("f64", None, [a1]) => ctor::f64(a1, stage),
136 ("bitcast", Some(t), [a1]) => call::bitcast_t(BitcastTemplate::parse(t)?.ty(), a1),
138 ("all", None, [a]) => call::all(a),
140 ("any", None, [a]) => call::any(a),
141 ("select", None, [a1, a2, a3]) => call::select(a1, a2, a3),
142 ("arrayLength", None, [a]) => call::arrayLength(a),
144 ("abs", None, [a]) => call::abs(a),
146 ("acos", None, [a]) => call::acos(a),
147 ("acosh", None, [a]) => call::acosh(a),
148 ("asin", None, [a]) => call::asin(a),
149 ("asinh", None, [a]) => call::asinh(a),
150 ("atan", None, [a]) => call::atan(a),
151 ("atanh", None, [a]) => call::atanh(a),
152 ("atan2", None, [a1, a2]) => call::atan2(a1, a2),
153 ("ceil", None, [a]) => call::ceil(a),
154 ("clamp", None, [a1, a2, a3]) => call::clamp(a1, a2, a3),
155 ("cos", None, [a]) => call::cos(a),
156 ("cosh", None, [a]) => call::cosh(a),
157 ("countLeadingZeros", None, [a]) => call::countLeadingZeros(a),
158 ("countOneBits", None, [a]) => call::countOneBits(a),
159 ("countTrailingZeros", None, [a]) => call::countTrailingZeros(a),
160 ("cross", None, [a1, a2]) => call::cross(a1, a2, stage),
161 ("degrees", None, [a]) => call::degrees(a),
162 ("determinant", None, [a]) => call::determinant(a),
163 ("distance", None, [a1, a2]) => call::distance(a1, a2, stage),
164 ("dot", None, [a1, a2]) => call::dot(a1, a2, stage),
165 ("dot4U8Packed", None, [a1, a2]) => call::dot4U8Packed(a1, a2),
166 ("dot4I8Packed", None, [a1, a2]) => call::dot4I8Packed(a1, a2),
167 ("exp", None, [a]) => call::exp(a),
168 ("exp2", None, [a]) => call::exp2(a),
169 ("extractBits", None, [a1, a2, a3]) => call::extractBits(a1, a2, a3),
170 ("faceForward", None, [a1, a2, a3]) => call::faceForward(a1, a2, a3),
171 ("firstLeadingBit", None, [a]) => call::firstLeadingBit(a),
172 ("firstTrailingBit", None, [a]) => call::firstTrailingBit(a),
173 ("floor", None, [a]) => call::floor(a),
174 ("fma", None, [a1, a2, a3]) => call::fma(a1, a2, a3),
175 ("fract", None, [a]) => call::fract(a, stage),
176 ("frexp", None, [a]) => call::frexp(a),
177 ("insertBits", None, [a1, a2, a3, a4]) => call::insertBits(a1, a2, a3, a4),
178 ("inverseSqrt", None, [a]) => call::inverseSqrt(a),
179 ("ldexp", None, [a1, a2]) => call::ldexp(a1, a2),
180 ("length", None, [a]) => call::length(a),
181 ("log", None, [a]) => call::log(a),
182 ("log2", None, [a]) => call::log2(a),
183 ("max", None, [a1, a2]) => call::max(a1, a2),
184 ("min", None, [a1, a2]) => call::min(a1, a2),
185 ("mix", None, [a1, a2, a3]) => call::mix(a1, a2, a3, stage),
186 ("modf", None, [a]) => call::modf(a),
187 ("normalize", None, [a]) => call::normalize(a, stage),
188 ("pow", None, [a1, a2]) => call::pow(a1, a2),
189 ("quantizeToF16", None, [a]) => call::quantizeToF16(a),
190 ("radians", None, [a]) => call::radians(a),
191 ("reflect", None, [a1, a2]) => call::reflect(a1, a2),
192 ("refract", None, [a1, a2, a3]) => call::refract(a1, a2, a3),
193 ("reverseBits", None, [a]) => call::reverseBits(a),
194 ("round", None, [a]) => call::round(a),
195 ("saturate", None, [a]) => call::saturate(a),
196 ("sign", None, [a]) => call::sign(a),
197 ("sin", None, [a]) => call::sin(a),
198 ("sinh", None, [a]) => call::sinh(a),
199 ("smoothstep", None, [a1, a2, a3]) => call::smoothstep(a1, a2, a3),
200 ("sqrt", None, [a]) => call::sqrt(a),
201 ("step", None, [a1, a2]) => call::step(a1, a2),
202 ("tan", None, [a]) => call::tan(a),
203 ("tanh", None, [a]) => call::tanh(a),
204 ("transpose", None, [a]) => call::transpose(a),
205 ("trunc", None, [a]) => call::trunc(a),
206 ("atomicLoad", None, [a]) => call::atomicLoad(a),
208 ("atomicStore", None, [a1, a2]) => {
209 call::atomicStore(a1, a2)?;
210 return Ok(None);
211 }
212 ("atomicAdd", None, [a1, a2]) => call::atomicAdd(a1, a2),
213 ("atomicSub", None, [a1, a2]) => call::atomicSub(a1, a2),
214 ("atomicMax", None, [a1, a2]) => call::atomicMax(a1, a2),
215 ("atomicMin", None, [a1, a2]) => call::atomicMin(a1, a2),
216 ("atomicAnd", None, [a1, a2]) => call::atomicAnd(a1, a2),
217 ("atomicOr", None, [a1, a2]) => call::atomicOr(a1, a2),
218 ("atomicXor", None, [a1, a2]) => call::atomicXor(a1, a2),
219 ("atomicExchange", None, [a1, a2]) => call::atomicExchange(a1, a2),
220 ("atomicCompareExchangeWeak", None, [a1, a2, a3]) => {
221 call::atomicCompareExchangeWeak(a1, a2, a3)
222 }
223 ("pack4x8snorm", None, [a]) => call::pack4x8snorm(a),
225 ("pack4x8unorm", None, [a]) => call::pack4x8unorm(a),
226 ("pack4xI8", None, [a]) => call::pack4xI8(a),
227 ("pack4xU8", None, [a]) => call::pack4xU8(a),
228 ("pack4xI8Clamp", None, [a]) => call::pack4xI8Clamp(a),
229 ("pack4xU8Clamp", None, [a]) => call::pack4xU8Clamp(a),
230 ("pack2x16snorm", None, [a]) => call::pack2x16snorm(a),
231 ("pack2x16unorm", None, [a]) => call::pack2x16unorm(a),
232 ("pack2x16float", None, [a]) => call::pack2x16float(a),
233 ("unpack4x8snorm", None, [a]) => call::unpack4x8snorm(a),
234 ("unpack4x8unorm", None, [a]) => call::unpack4x8unorm(a),
235 ("unpack4xI8", None, [a]) => call::unpack4xI8(a),
236 ("unpack4xU8", None, [a]) => call::unpack4xU8(a),
237 ("unpack2x16snorm", None, [a]) => call::unpack2x16snorm(a),
238 ("unpack2x16unorm", None, [a]) => call::unpack2x16unorm(a),
239 ("unpack2x16float", None, [a]) => call::unpack2x16float(a),
240 ("storageBarrier", None, []) => return Ok(None),
243 ("textureBarrier", None, []) => return Ok(None),
244 ("workgroupBarrier", None, []) => return Ok(None),
245 _ => Err(E::Signature(CallSignature {
246 name: name.to_string(),
247 tplt: tplt.map(|tplt| tplt.to_vec()),
248 args: args.iter().map(|a| a.ty()).collect_vec(),
249 })),
250 }
251 .map(Option::Some)
252}
253
254pub fn call_ctor(ty: &Type, args: &[Instance], stage: ShaderStage) -> Result<Instance, E> {
258 match (ty, args) {
259 (_, []) => Instance::zero_value(ty),
260 (Type::Bool, [a1]) => ctor::bool(a1),
261 (Type::I32, [a1]) => ctor::i32(a1),
262 (Type::U32, [a1]) => ctor::u32(a1),
263 (Type::F32, [a1]) => ctor::f32(a1, stage),
264 (Type::F16, [a1]) => ctor::f16(a1, stage),
265 (Type::Struct(ty), a) => struct_ctor(ty, a).map(Instance::from),
266 (Type::Array(ty, n), a) => ctor::array_t(ty, n.unwrap_or(a.len()), a),
267 (Type::Vec(n, ty), a) => ctor::vec_t(*n as usize, ty, a, stage),
268 (Type::Mat(c, r, ty), a) => ctor::mat_t(*c as usize, *r as usize, ty, a, stage),
269 (
270 Type::AbstractInt
271 | Type::AbstractFloat
272 | Type::Atomic(_)
273 | Type::Ptr(_, _, _)
274 | Type::Ref(_, _, _)
275 | Type::Texture(_)
276 | Type::Sampler(_)
277 | Type::Unknown,
278 _,
279 ) => Err(E::NotConstructible(ty.clone())),
280 #[cfg(feature = "naga-ext")]
281 (Type::I64 | Type::U64 | Type::F64, _) => Err(E::Todo(
282 "naga 64-bit literal constructors not implemented".to_string(),
283 )),
284 #[cfg(feature = "naga-ext")]
285 (Type::BindingArray(_, _), _) => Err(E::NotConstructible(ty.clone())),
286 (Type::Bool | Type::I32 | Type::U32 | Type::F32 | Type::F16, _) => {
287 Err(E::Signature(CallSignature {
288 name: ty.to_string(),
289 tplt: None,
290 args: args.iter().map(|a| a.ty()).collect_vec(),
291 }))
292 }
293 #[cfg(feature = "naga-ext")]
294 (Type::RayQuery(_) | Type::AccelerationStructure(_), _) => {
295 Err(E::NotConstructible(ty.clone()))
296 }
297 }
298}
299
300pub fn call_binary_op(
307 op: BinaryOperator,
308 lhs: &Instance,
309 rhs: &Instance,
310 stage: ShaderStage,
311) -> Result<Instance, E> {
312 match op {
313 BinaryOperator::ShortCircuitOr => lhs.op_or(rhs),
314 BinaryOperator::ShortCircuitAnd => lhs.op_and(rhs),
315 BinaryOperator::Addition => lhs.op_add(rhs, stage),
316 BinaryOperator::Subtraction => lhs.op_sub(rhs, stage),
317 BinaryOperator::Multiplication => lhs.op_mul(rhs, stage),
318 BinaryOperator::Division => lhs.op_div(rhs, stage),
319 BinaryOperator::Remainder => lhs.op_rem(rhs, stage),
320 BinaryOperator::Equality => lhs.op_eq(rhs),
321 BinaryOperator::Inequality => lhs.op_ne(rhs),
322 BinaryOperator::LessThan => lhs.op_lt(rhs),
323 BinaryOperator::LessThanEqual => lhs.op_le(rhs),
324 BinaryOperator::GreaterThan => lhs.op_gt(rhs),
325 BinaryOperator::GreaterThanEqual => lhs.op_ge(rhs),
326 BinaryOperator::BitwiseOr => lhs.op_bitor(rhs),
327 BinaryOperator::BitwiseAnd => lhs.op_bitand(rhs),
328 BinaryOperator::BitwiseXor => lhs.op_bitxor(rhs),
329 BinaryOperator::ShiftLeft => lhs.op_shl(rhs, stage),
330 BinaryOperator::ShiftRight => lhs.op_shr(rhs, stage),
331 }
332}
333
334pub fn call_unary_op(operator: UnaryOperator, operand: &Instance) -> Result<Instance, E> {
338 match operator {
339 UnaryOperator::LogicalNegation => operand.op_not(),
340 UnaryOperator::Negation => operand.op_neg(),
341 UnaryOperator::BitwiseComplement => operand.op_bitnot(),
342 UnaryOperator::AddressOf => operand.op_ref(),
343 UnaryOperator::Indirection => operand.op_deref(),
344 }
345}
346
347pub fn builtin_type(name: &str, tplt: Option<&[TpltParam]>) -> Result<Type, E> {
352 if let Some(t) = tplt {
353 match name {
354 "array" => Ok(ArrayTemplate::parse(t)?.ty()),
355 #[cfg(feature = "naga-ext")]
356 "binding_array" => Ok(crate::tplt::BindingArrayTemplate::parse(t)?.ty()),
357 "vec2" => Ok(VecTemplate::parse(t)?.ty(2)),
358 "vec3" => Ok(VecTemplate::parse(t)?.ty(3)),
359 "vec4" => Ok(VecTemplate::parse(t)?.ty(4)),
360 "mat2x2" => Ok(MatTemplate::parse(t)?.ty(2, 2)),
361 "mat2x3" => Ok(MatTemplate::parse(t)?.ty(2, 3)),
362 "mat2x4" => Ok(MatTemplate::parse(t)?.ty(2, 4)),
363 "mat3x2" => Ok(MatTemplate::parse(t)?.ty(3, 2)),
364 "mat3x3" => Ok(MatTemplate::parse(t)?.ty(3, 3)),
365 "mat3x4" => Ok(MatTemplate::parse(t)?.ty(3, 4)),
366 "mat4x2" => Ok(MatTemplate::parse(t)?.ty(4, 2)),
367 "mat4x3" => Ok(MatTemplate::parse(t)?.ty(4, 3)),
368 "mat4x4" => Ok(MatTemplate::parse(t)?.ty(4, 4)),
369 "ptr" => Ok(PtrTemplate::parse(t)?.ty()),
370 "atomic" => Ok(AtomicTemplate::parse(t)?.ty()),
371 "texture_1d"
372 | "texture_2d"
373 | "texture_2d_array"
374 | "texture_3d"
375 | "texture_cube"
376 | "texture_cube_array"
377 | "texture_multisampled_2d"
378 | "texture_storage_1d"
379 | "texture_storage_2d"
380 | "texture_storage_2d_array"
381 | "texture_storage_3d" => Ok(Type::Texture(TextureTemplate::parse(name, t)?.ty())),
382
383 #[cfg(feature = "naga-ext")]
384 "texture_1d_array" | "texture_storage_1d_array" | "texture_multisampled_2d_array" => {
385 Ok(Type::Texture(TextureTemplate::parse(name, t)?.ty()))
386 }
387 #[cfg(feature = "naga-ext")]
388 "ray_query" => Ok(Type::RayQuery(None)),
389 #[cfg(feature = "naga-ext")]
390 "acceleration_structure" => Ok(Type::AccelerationStructure(Some(
392 AccelerationStructureTags::parse(t)?,
393 ))),
394
395 _ => Err(E::UnexpectedTemplate(name.to_string())),
396 }
397 }
398 else {
400 match name {
401 "bool" => Ok(Type::Bool),
402 "__AbstractInt" => Ok(Type::AbstractInt),
403 "__AbstractFloat" => Ok(Type::AbstractFloat),
404 "i32" => Ok(Type::I32),
405 "u32" => Ok(Type::U32),
406 "f32" => Ok(Type::F32),
407 "f16" => Ok(Type::F16),
408 "texture_depth_multisampled_2d" => Ok(Type::Texture(TextureType::DepthMultisampled2D)),
409 "texture_external" => Ok(Type::Texture(TextureType::External)),
410 "texture_depth_2d" => Ok(Type::Texture(TextureType::Depth2D)),
411 "texture_depth_2d_array" => Ok(Type::Texture(TextureType::Depth2DArray)),
412 "texture_depth_cube" => Ok(Type::Texture(TextureType::DepthCube)),
413 "texture_depth_cube_array" => Ok(Type::Texture(TextureType::DepthCubeArray)),
414 "sampler" => Ok(Type::Sampler(SamplerType::Sampler)),
415 "sampler_comparison" => Ok(Type::Sampler(SamplerType::SamplerComparison)),
416
417 #[cfg(feature = "naga-ext")]
418 "i64" => Ok(Type::I64),
419 #[cfg(feature = "naga-ext")]
420 "u64" => Ok(Type::U64),
421 #[cfg(feature = "naga-ext")]
422 "f64" => Ok(Type::F64),
423 #[cfg(feature = "naga-ext")]
424 "ray_query" => Ok(Type::RayQuery(Default::default())),
425 #[cfg(feature = "naga-ext")]
426 "acceleration_structure" => Ok(Type::AccelerationStructure(Default::default())),
427
428 "array" => Err(E::MissingTemplate("array")),
430 "binding_array" => Err(E::MissingTemplate("binding_array")),
431 "vec2" => Err(E::MissingTemplate("vec2")),
432 "vec3" => Err(E::MissingTemplate("vec3")),
433 "vec4" => Err(E::MissingTemplate("vec4")),
434 "mat2x2" => Err(E::MissingTemplate("mat2x2")),
435 "mat2x3" => Err(E::MissingTemplate("mat2x3")),
436 "mat2x4" => Err(E::MissingTemplate("mat2x4")),
437 "mat3x2" => Err(E::MissingTemplate("mat3x2")),
438 "mat3x3" => Err(E::MissingTemplate("mat3x3")),
439 "mat3x4" => Err(E::MissingTemplate("mat3x4")),
440 "mat4x2" => Err(E::MissingTemplate("mat4x2")),
441 "mat4x3" => Err(E::MissingTemplate("mat4x3")),
442 "mat4x4" => Err(E::MissingTemplate("mat4x4")),
443 "ptr" => Err(E::MissingTemplate("ptr")),
444 "atomic" => Err(E::MissingTemplate("atomic")),
445 "texture_1d" => Err(E::MissingTemplate("texture_1d")),
446 "texture_2d" => Err(E::MissingTemplate("texture_2d")),
447 "texture_2d_array" => Err(E::MissingTemplate("texture_2d_array")),
448 "texture_3d" => Err(E::MissingTemplate("texture_3d")),
449 "texture_cube" => Err(E::MissingTemplate("texture_cube")),
450 "texture_cube_array" => Err(E::MissingTemplate("texture_cube_array")),
451 "texture_multisampled_2d" => Err(E::MissingTemplate("texture_multisampled_2d")),
452 "texture_storage_1d" => Err(E::MissingTemplate("texture_storage_1d")),
453 "texture_storage_2d" => Err(E::MissingTemplate("texture_storage_2d")),
454 "texture_storage_2d_array" => Err(E::MissingTemplate("texture_storage_2d_array")),
455 "texture_storage_3d" => Err(E::MissingTemplate("texture_storage_3d")),
456 #[cfg(feature = "naga-ext")]
457 "texture_1d_array" => Err(E::MissingTemplate("texture_1d_array")),
458 #[cfg(feature = "naga-ext")]
459 "texture_storage_1d_array" => Err(E::MissingTemplate("texture_storage_1d_array")),
460 #[cfg(feature = "naga-ext")]
461 "texture_multisampled_2d_array" => {
462 Err(E::MissingTemplate("texture_multisampled_2d_array"))
463 }
464
465 _ => Err(E::UnknownType(name.to_string())),
466 }
467 }
468}