mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[naga] Allow abstract scalars in modf and frexp results.
Allow `PredeclaredType::ModfResult` and `PredeclaredType::FrexpResult` to hold any sort of scalar, not just a floating-point scalar. This prepares Naga for implementing the `AbstractFloat` overloads for the `modf` and `frexp` builtin functions.
This commit is contained in:
committed by
Teodor Tanasoaia
parent
658052885a
commit
f6f9233295
@@ -747,14 +747,17 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// Write functions to create special types.
|
||||
for (type_key, struct_ty) in self.module.special_types.predeclared_types.iter() {
|
||||
match type_key {
|
||||
&crate::PredeclaredType::ModfResult { size, width }
|
||||
| &crate::PredeclaredType::FrexpResult { size, width } => {
|
||||
&crate::PredeclaredType::ModfResult { size, scalar }
|
||||
| &crate::PredeclaredType::FrexpResult { size, scalar } => {
|
||||
let arg_type_name_owner;
|
||||
let arg_type_name = if let Some(size) = size {
|
||||
arg_type_name_owner =
|
||||
format!("{}vec{}", if width == 8 { "d" } else { "" }, size as u8);
|
||||
arg_type_name_owner = format!(
|
||||
"{}vec{}",
|
||||
if scalar.width == 8 { "d" } else { "" },
|
||||
size as u8
|
||||
);
|
||||
&arg_type_name_owner
|
||||
} else if width == 8 {
|
||||
} else if scalar.width == 8 {
|
||||
"double"
|
||||
} else {
|
||||
"float"
|
||||
|
||||
@@ -796,17 +796,17 @@ impl<W: Write> super::Writer<'_, W> {
|
||||
pub(super) fn write_special_functions(&mut self, module: &crate::Module) -> BackendResult {
|
||||
for (type_key, struct_ty) in module.special_types.predeclared_types.iter() {
|
||||
match type_key {
|
||||
&crate::PredeclaredType::ModfResult { size, width }
|
||||
| &crate::PredeclaredType::FrexpResult { size, width } => {
|
||||
&crate::PredeclaredType::ModfResult { size, scalar }
|
||||
| &crate::PredeclaredType::FrexpResult { size, scalar } => {
|
||||
let arg_type_name_owner;
|
||||
let arg_type_name = if let Some(size) = size {
|
||||
arg_type_name_owner = format!(
|
||||
"{}{}",
|
||||
if width == 8 { "double" } else { "float" },
|
||||
if scalar.width == 8 { "double" } else { "float" },
|
||||
size as u8
|
||||
);
|
||||
&arg_type_name_owner
|
||||
} else if width == 8 {
|
||||
} else if scalar.width == 8 {
|
||||
"double"
|
||||
} else {
|
||||
"float"
|
||||
|
||||
@@ -3830,17 +3830,17 @@ impl<W: Write> Writer<W> {
|
||||
// Write functions to create special types.
|
||||
for (type_key, struct_ty) in module.special_types.predeclared_types.iter() {
|
||||
match type_key {
|
||||
&crate::PredeclaredType::ModfResult { size, width }
|
||||
| &crate::PredeclaredType::FrexpResult { size, width } => {
|
||||
&crate::PredeclaredType::ModfResult { size, scalar }
|
||||
| &crate::PredeclaredType::FrexpResult { size, scalar } => {
|
||||
let arg_type_name_owner;
|
||||
let arg_type_name = if let Some(size) = size {
|
||||
arg_type_name_owner = format!(
|
||||
"{NAMESPACE}::{}{}",
|
||||
if width == 8 { "double" } else { "float" },
|
||||
if scalar.width == 8 { "double" } else { "float" },
|
||||
size as u8
|
||||
);
|
||||
&arg_type_name_owner
|
||||
} else if width == 8 {
|
||||
} else if scalar.width == 8 {
|
||||
"double"
|
||||
} else {
|
||||
"float"
|
||||
|
||||
@@ -298,11 +298,11 @@ impl crate::Module {
|
||||
},
|
||||
}
|
||||
}
|
||||
crate::PredeclaredType::ModfResult { size, width } => {
|
||||
crate::PredeclaredType::ModfResult { size, scalar } => {
|
||||
let float_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::float(width)),
|
||||
inner: crate::TypeInner::Scalar(scalar),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@@ -311,23 +311,20 @@ impl crate::Module {
|
||||
let vec_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
scalar: crate::Scalar::float(width),
|
||||
},
|
||||
inner: crate::TypeInner::Vector { size, scalar },
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
(vec_ty, size as u32 * width as u32)
|
||||
(vec_ty, size as u32 * scalar.width as u32)
|
||||
} else {
|
||||
(float_ty, width as u32)
|
||||
(float_ty, scalar.width as u32)
|
||||
};
|
||||
|
||||
let mut type_name = "__modf_result_".to_string();
|
||||
if let Some(size) = size {
|
||||
let _ = write!(type_name, "vec{}_", size as u8);
|
||||
}
|
||||
let _ = write!(type_name, "f{}", width * 8);
|
||||
let _ = write!(type_name, "f{}", scalar.width * 8);
|
||||
|
||||
crate::Type {
|
||||
name: Some(type_name),
|
||||
@@ -350,11 +347,11 @@ impl crate::Module {
|
||||
},
|
||||
}
|
||||
}
|
||||
crate::PredeclaredType::FrexpResult { size, width } => {
|
||||
crate::PredeclaredType::FrexpResult { size, scalar } => {
|
||||
let float_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::float(width)),
|
||||
inner: crate::TypeInner::Scalar(scalar),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@@ -364,7 +361,7 @@ impl crate::Module {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width,
|
||||
width: scalar.width,
|
||||
}),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@@ -374,10 +371,7 @@ impl crate::Module {
|
||||
let vec_float_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
scalar: crate::Scalar::float(width),
|
||||
},
|
||||
inner: crate::TypeInner::Vector { size, scalar },
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@@ -388,22 +382,22 @@ impl crate::Module {
|
||||
size,
|
||||
scalar: crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width,
|
||||
width: scalar.width,
|
||||
},
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
(vec_float_ty, vec_int_ty, size as u32 * width as u32)
|
||||
(vec_float_ty, vec_int_ty, size as u32 * scalar.width as u32)
|
||||
} else {
|
||||
(float_ty, int_ty, width as u32)
|
||||
(float_ty, int_ty, scalar.width as u32)
|
||||
};
|
||||
|
||||
let mut type_name = "__frexp_result_".to_string();
|
||||
if let Some(size) = size {
|
||||
let _ = write!(type_name, "vec{}_", size as u8);
|
||||
}
|
||||
let _ = write!(type_name, "f{}", width * 8);
|
||||
let _ = write!(type_name, "f{}", scalar.width * 8);
|
||||
|
||||
crate::Type {
|
||||
name: Some(type_name),
|
||||
|
||||
@@ -2304,22 +2304,18 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
args.finish()?;
|
||||
|
||||
if fun == crate::MathFunction::Modf || fun == crate::MathFunction::Frexp {
|
||||
if let Some((size, width)) = match *resolve_inner!(ctx, arg) {
|
||||
crate::TypeInner::Scalar(crate::Scalar { width, .. }) => {
|
||||
Some((None, width))
|
||||
if let Some((size, scalar)) = match *resolve_inner!(ctx, arg) {
|
||||
crate::TypeInner::Scalar(scalar) => Some((None, scalar)),
|
||||
crate::TypeInner::Vector { size, scalar, .. } => {
|
||||
Some((Some(size), scalar))
|
||||
}
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
scalar: crate::Scalar { width, .. },
|
||||
..
|
||||
} => Some((Some(size), width)),
|
||||
_ => None,
|
||||
} {
|
||||
ctx.module.generate_predeclared_type(
|
||||
if fun == crate::MathFunction::Modf {
|
||||
crate::PredeclaredType::ModfResult { size, width }
|
||||
crate::PredeclaredType::ModfResult { size, scalar }
|
||||
} else {
|
||||
crate::PredeclaredType::FrexpResult { size, width }
|
||||
crate::PredeclaredType::FrexpResult { size, scalar }
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2217,11 +2217,11 @@ pub enum PredeclaredType {
|
||||
AtomicCompareExchangeWeakResult(Scalar),
|
||||
ModfResult {
|
||||
size: Option<VectorSize>,
|
||||
width: Bytes,
|
||||
scalar: Scalar,
|
||||
},
|
||||
FrexpResult {
|
||||
size: Option<VectorSize>,
|
||||
width: Bytes,
|
||||
scalar: Scalar,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -668,19 +668,9 @@ impl<'a> ResolveContext<'a> {
|
||||
| Mf::Pow
|
||||
| Mf::QuantizeToF16 => res_arg.clone(),
|
||||
Mf::Modf | Mf::Frexp => {
|
||||
let (size, width) = match res_arg.inner_with(types) {
|
||||
&Ti::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
}) => (None, width),
|
||||
&Ti::Vector {
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
size,
|
||||
} => (Some(size), width),
|
||||
let (size, scalar) = match res_arg.inner_with(types) {
|
||||
&Ti::Scalar(scalar) => (None, scalar),
|
||||
&Ti::Vector { scalar, size } => (Some(size), scalar),
|
||||
ref other => {
|
||||
return Err(ResolveError::IncompatibleOperands(format!(
|
||||
"{fun:?}({other:?}, _)"
|
||||
@@ -691,9 +681,9 @@ impl<'a> ResolveContext<'a> {
|
||||
.special_types
|
||||
.predeclared_types
|
||||
.get(&if fun == Mf::Modf {
|
||||
crate::PredeclaredType::ModfResult { size, width }
|
||||
crate::PredeclaredType::ModfResult { size, scalar }
|
||||
} else {
|
||||
crate::PredeclaredType::FrexpResult { size, width }
|
||||
crate::PredeclaredType::FrexpResult { size, scalar }
|
||||
})
|
||||
.ok_or(ResolveError::MissingSpecialType)?;
|
||||
TypeResolution::Handle(*result)
|
||||
|
||||
Reference in New Issue
Block a user