mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 06:44:14 +00:00
[naga wgsl-in] Relocate automatic_conversion_consensus
.
Move `naga::front::wgsl::lower:🚧:automatic_conversion_consensus`
into `conversion.rs`, and make it a method of `ExpressionContext`.
This commit is contained in:
parent
3ffd5a1e56
commit
84c74adec2
@ -5,7 +5,6 @@ use crate::{Handle, Span};
|
||||
|
||||
use crate::front::wgsl::error::Error;
|
||||
use crate::front::wgsl::lower::{ExpressionContext, Lowerer};
|
||||
use crate::front::wgsl::Scalar;
|
||||
|
||||
/// A cooked form of `ast::ConstructorType` that uses Naga types whenever
|
||||
/// possible.
|
||||
@ -316,9 +315,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
Constructor::PartialVector { size },
|
||||
) => {
|
||||
let consensus_scalar =
|
||||
automatic_conversion_consensus(&components, ctx).map_err(|index| {
|
||||
Error::InvalidConstructorComponentType(spans[index], index as i32)
|
||||
})?;
|
||||
ctx.automatic_conversion_consensus(&components)
|
||||
.map_err(|index| {
|
||||
Error::InvalidConstructorComponentType(spans[index], index as i32)
|
||||
})?;
|
||||
ctx.convert_slice_to_common_scalar(&mut components, consensus_scalar)?;
|
||||
let inner = consensus_scalar.to_inner_vector(size);
|
||||
let ty = ctx.ensure_type_exists(inner);
|
||||
@ -343,9 +343,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
Constructor::PartialMatrix { columns, rows },
|
||||
) if components.len() == columns as usize * rows as usize => {
|
||||
let consensus_scalar =
|
||||
automatic_conversion_consensus(&components, ctx).map_err(|index| {
|
||||
Error::InvalidConstructorComponentType(spans[index], index as i32)
|
||||
})?;
|
||||
ctx.automatic_conversion_consensus(&components)
|
||||
.map_err(|index| {
|
||||
Error::InvalidConstructorComponentType(spans[index], index as i32)
|
||||
})?;
|
||||
// We actually only accept floating-point elements.
|
||||
let consensus_scalar = consensus_scalar
|
||||
.automatic_conversion_combine(crate::Scalar::ABSTRACT_FLOAT)
|
||||
@ -420,9 +421,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
Constructor::PartialMatrix { columns, rows },
|
||||
) => {
|
||||
let consensus_scalar =
|
||||
automatic_conversion_consensus(&components, ctx).map_err(|index| {
|
||||
Error::InvalidConstructorComponentType(spans[index], index as i32)
|
||||
})?;
|
||||
ctx.automatic_conversion_consensus(&components)
|
||||
.map_err(|index| {
|
||||
Error::InvalidConstructorComponentType(spans[index], index as i32)
|
||||
})?;
|
||||
ctx.convert_slice_to_common_scalar(&mut components, consensus_scalar)?;
|
||||
let ty = ctx.ensure_type_exists(crate::TypeInner::Matrix {
|
||||
columns,
|
||||
@ -456,10 +458,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
// Array constructor - infer type
|
||||
(components, Constructor::PartialArray) => {
|
||||
let mut components = components.into_components_vec();
|
||||
if let Ok(consensus_scalar) = automatic_conversion_consensus(&components, ctx) {
|
||||
if let Ok(consensus_scalar) = ctx.automatic_conversion_consensus(&components) {
|
||||
// Note that this will *not* necessarily convert all the
|
||||
// components to the same type! The `automatic_conversion_consensus`
|
||||
// function only considers the parameters' leaf scalar
|
||||
// method only considers the parameters' leaf scalar
|
||||
// types; the parameters themselves could be any mix of
|
||||
// vectors, matrices, and scalars.
|
||||
//
|
||||
@ -609,50 +611,3 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
Ok(handle)
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the consensus scalar of `components` under WGSL's automatic
|
||||
/// conversions.
|
||||
///
|
||||
/// If `components` can all be converted to any common scalar via
|
||||
/// WGSL's automatic conversions, return the best such scalar.
|
||||
///
|
||||
/// The `components` slice must not be empty. All elements' types must
|
||||
/// have been resolved.
|
||||
///
|
||||
/// If `components` are definitely not acceptable as arguments to such
|
||||
/// constructors, return `Err(i)`, where `i` is the index in
|
||||
/// `components` of some problematic argument.
|
||||
///
|
||||
/// This function doesn't fully type-check the arguments - it only
|
||||
/// considers their leaf scalar types. This means it may return `Ok`
|
||||
/// even when the Naga validator will reject the resulting
|
||||
/// construction expression later.
|
||||
fn automatic_conversion_consensus(
|
||||
components: &[Handle<crate::Expression>],
|
||||
ctx: &ExpressionContext<'_, '_, '_>,
|
||||
) -> Result<Scalar, usize> {
|
||||
let types = &ctx.module.types;
|
||||
let mut inners = components
|
||||
.iter()
|
||||
.map(|&c| ctx.typifier()[c].inner_with(types));
|
||||
log::debug!(
|
||||
"wgsl automatic_conversion_consensus: {:?}",
|
||||
inners
|
||||
.clone()
|
||||
.map(|inner| inner.to_wgsl(&ctx.module.to_ctx()))
|
||||
.collect::<Vec<String>>()
|
||||
);
|
||||
let mut best = inners.next().unwrap().scalar().ok_or(0_usize)?;
|
||||
for (inner, i) in inners.zip(1..) {
|
||||
let scalar = inner.scalar().ok_or(i)?;
|
||||
match best.automatic_conversion_combine(scalar) {
|
||||
Some(new_best) => {
|
||||
best = new_best;
|
||||
}
|
||||
None => return Err(i),
|
||||
}
|
||||
}
|
||||
|
||||
log::debug!(" consensus: {:?}", best.to_wgsl());
|
||||
Ok(best)
|
||||
}
|
||||
|
@ -196,6 +196,53 @@ impl<'source, 'temp, 'out> super::ExpressionContext<'source, 'temp, 'out> {
|
||||
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
/// Find the consensus scalar of `components` under WGSL's automatic
|
||||
/// conversions.
|
||||
///
|
||||
/// If `components` can all be converted to any common scalar via
|
||||
/// WGSL's automatic conversions, return the best such scalar.
|
||||
///
|
||||
/// The `components` slice must not be empty. All elements' types must
|
||||
/// have been resolved.
|
||||
///
|
||||
/// If `components` are definitely not acceptable as arguments to such
|
||||
/// constructors, return `Err(i)`, where `i` is the index in
|
||||
/// `components` of some problematic argument.
|
||||
///
|
||||
/// This function doesn't fully type-check the arguments - it only
|
||||
/// considers their leaf scalar types. This means it may return `Ok`
|
||||
/// even when the Naga validator will reject the resulting
|
||||
/// construction expression later.
|
||||
pub fn automatic_conversion_consensus(
|
||||
&self,
|
||||
components: &[Handle<crate::Expression>],
|
||||
) -> Result<crate::Scalar, usize> {
|
||||
let types = &self.module.types;
|
||||
let mut inners = components
|
||||
.iter()
|
||||
.map(|&c| self.typifier()[c].inner_with(types));
|
||||
log::debug!(
|
||||
"wgsl automatic_conversion_consensus: {:?}",
|
||||
inners
|
||||
.clone()
|
||||
.map(|inner| inner.to_wgsl(&self.module.to_ctx()))
|
||||
.collect::<Vec<String>>()
|
||||
);
|
||||
let mut best = inners.next().unwrap().scalar().ok_or(0_usize)?;
|
||||
for (inner, i) in inners.zip(1..) {
|
||||
let scalar = inner.scalar().ok_or(i)?;
|
||||
match best.automatic_conversion_combine(scalar) {
|
||||
Some(new_best) => {
|
||||
best = new_best;
|
||||
}
|
||||
None => return Err(i),
|
||||
}
|
||||
}
|
||||
|
||||
log::debug!(" consensus: {:?}", best.to_wgsl());
|
||||
Ok(best)
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::TypeInner {
|
||||
|
Loading…
Reference in New Issue
Block a user