[spv-in] Impl GLOp::Radians and GLOp::Degrees (#797)

* Implement GLOp::Radians and GLOp::Degrees

* Simplify and inline

* Change comment

* Generate constant on demand

* Fix 180/pi/180
This commit is contained in:
Ashley
2021-04-29 16:19:30 +02:00
committed by GitHub
parent 93e57ffcf2
commit 881c8a7abc
2 changed files with 115 additions and 78 deletions

View File

@@ -149,8 +149,8 @@ impl<I: Iterator<Item = u32>> super::Parser<I> {
fun_id,
&mut fun.expressions,
&mut fun.local_variables,
&mut module.constants,
&module.types,
&module.constants,
&module.global_variables,
)?;

View File

@@ -772,8 +772,8 @@ impl<I: Iterator<Item = u32>> Parser<I> {
function_id: spirv::Word,
expressions: &mut Arena<crate::Expression>,
local_arena: &mut Arena<crate::LocalVariable>,
const_arena: &mut Arena<crate::Constant>,
type_arena: &Arena<crate::Type>,
const_arena: &Arena<crate::Constant>,
global_arena: &Arena<crate::GlobalVariable>,
) -> Result<ControlFlowNode, Error> {
let mut block = Vec::new();
@@ -1695,84 +1695,121 @@ impl<I: Iterator<Item = u32>> Parser<I> {
}
let inst_id = self.next()?;
let gl_op = Glo::from_u32(inst_id).ok_or(Error::UnsupportedExtInst(inst_id))?;
let fun = match gl_op {
Glo::Round => Mf::Round,
Glo::Trunc => Mf::Trunc,
Glo::FAbs | Glo::SAbs => Mf::Abs,
Glo::FSign | Glo::SSign => Mf::Sign,
Glo::Floor => Mf::Floor,
Glo::Ceil => Mf::Ceil,
Glo::Fract => Mf::Fract,
Glo::Sin => Mf::Sin,
Glo::Cos => Mf::Cos,
Glo::Tan => Mf::Tan,
Glo::Asin => Mf::Asin,
Glo::Acos => Mf::Acos,
Glo::Atan => Mf::Atan,
Glo::Sinh => Mf::Sinh,
Glo::Cosh => Mf::Cosh,
Glo::Tanh => Mf::Tanh,
Glo::Atan2 => Mf::Atan2,
Glo::Pow => Mf::Pow,
Glo::Exp => Mf::Exp,
Glo::Log => Mf::Log,
Glo::Exp2 => Mf::Exp2,
Glo::Log2 => Mf::Log2,
Glo::Sqrt => Mf::Sqrt,
Glo::InverseSqrt => Mf::InverseSqrt,
Glo::Determinant => Mf::Determinant,
Glo::Modf => Mf::Modf,
Glo::FMin | Glo::UMin | Glo::SMin | Glo::NMin => Mf::Min,
Glo::FMax | Glo::UMax | Glo::SMax | Glo::NMax => Mf::Max,
Glo::FClamp | Glo::UClamp | Glo::SClamp | Glo::NClamp => Mf::Clamp,
Glo::FMix => Mf::Mix,
Glo::Step => Mf::Step,
Glo::SmoothStep => Mf::SmoothStep,
Glo::Fma => Mf::Fma,
Glo::Frexp => Mf::Frexp, //TODO: FrexpStruct?
Glo::Ldexp => Mf::Ldexp,
Glo::Length => Mf::Length,
Glo::Distance => Mf::Distance,
Glo::Cross => Mf::Cross,
Glo::Normalize => Mf::Normalize,
Glo::FaceForward => Mf::FaceForward,
Glo::Reflect => Mf::Reflect,
Glo::Refract => Mf::Refract,
_ => return Err(Error::UnsupportedExtInst(inst_id)),
};
let arg_count = fun.argument_count();
inst.expect(base_wc + arg_count as u16)?;
let arg = {
let arg_id = self.next()?;
self.lookup_expression.lookup(arg_id)?.handle
};
let arg1 = if arg_count > 1 {
let arg_id = self.next()?;
Some(self.lookup_expression.lookup(arg_id)?.handle)
} else {
None
};
let arg2 = if arg_count > 2 {
let arg_id = self.next()?;
Some(self.lookup_expression.lookup(arg_id)?.handle)
} else {
None
};
if gl_op == Glo::Radians || gl_op == Glo::Degrees {
inst.expect(base_wc + 1)?;
let arg = {
let arg_id = self.next()?;
self.lookup_expression.lookup(arg_id)?.handle
};
let expr = crate::Expression::Math {
fun,
arg,
arg1,
arg2,
};
self.lookup_expression.insert(
result_id,
LookupExpression {
handle: expressions.append(expr),
type_id: result_type_id,
},
);
let constant_handle = const_arena.fetch_or_append(crate::Constant {
name: None,
specialization: None,
inner: crate::ConstantInner::Scalar {
width: 4,
value: crate::ScalarValue::Float(match gl_op {
Glo::Radians => std::f64::consts::PI / 180.0,
Glo::Degrees => 180.0 / std::f64::consts::PI,
_ => unreachable!(),
}),
},
});
let expr_handle =
expressions.append(crate::Expression::Constant(constant_handle));
self.lookup_expression.insert(
result_id,
LookupExpression {
handle: expressions.append(crate::Expression::Binary {
op: crate::BinaryOperator::Multiply,
left: arg,
right: expr_handle,
}),
type_id: result_type_id,
},
);
} else {
let fun = match gl_op {
Glo::Round => Mf::Round,
Glo::Trunc => Mf::Trunc,
Glo::FAbs | Glo::SAbs => Mf::Abs,
Glo::FSign | Glo::SSign => Mf::Sign,
Glo::Floor => Mf::Floor,
Glo::Ceil => Mf::Ceil,
Glo::Fract => Mf::Fract,
Glo::Sin => Mf::Sin,
Glo::Cos => Mf::Cos,
Glo::Tan => Mf::Tan,
Glo::Asin => Mf::Asin,
Glo::Acos => Mf::Acos,
Glo::Atan => Mf::Atan,
Glo::Sinh => Mf::Sinh,
Glo::Cosh => Mf::Cosh,
Glo::Tanh => Mf::Tanh,
Glo::Atan2 => Mf::Atan2,
Glo::Pow => Mf::Pow,
Glo::Exp => Mf::Exp,
Glo::Log => Mf::Log,
Glo::Exp2 => Mf::Exp2,
Glo::Log2 => Mf::Log2,
Glo::Sqrt => Mf::Sqrt,
Glo::InverseSqrt => Mf::InverseSqrt,
Glo::Determinant => Mf::Determinant,
Glo::Modf => Mf::Modf,
Glo::FMin | Glo::UMin | Glo::SMin | Glo::NMin => Mf::Min,
Glo::FMax | Glo::UMax | Glo::SMax | Glo::NMax => Mf::Max,
Glo::FClamp | Glo::UClamp | Glo::SClamp | Glo::NClamp => Mf::Clamp,
Glo::FMix => Mf::Mix,
Glo::Step => Mf::Step,
Glo::SmoothStep => Mf::SmoothStep,
Glo::Fma => Mf::Fma,
Glo::Frexp => Mf::Frexp, //TODO: FrexpStruct?
Glo::Ldexp => Mf::Ldexp,
Glo::Length => Mf::Length,
Glo::Distance => Mf::Distance,
Glo::Cross => Mf::Cross,
Glo::Normalize => Mf::Normalize,
Glo::FaceForward => Mf::FaceForward,
Glo::Reflect => Mf::Reflect,
Glo::Refract => Mf::Refract,
_ => return Err(Error::UnsupportedExtInst(inst_id)),
};
let arg_count = fun.argument_count();
inst.expect(base_wc + arg_count as u16)?;
let arg = {
let arg_id = self.next()?;
self.lookup_expression.lookup(arg_id)?.handle
};
let arg1 = if arg_count > 1 {
let arg_id = self.next()?;
Some(self.lookup_expression.lookup(arg_id)?.handle)
} else {
None
};
let arg2 = if arg_count > 2 {
let arg_id = self.next()?;
Some(self.lookup_expression.lookup(arg_id)?.handle)
} else {
None
};
let expr = crate::Expression::Math {
fun,
arg,
arg1,
arg2,
};
self.lookup_expression.insert(
result_id,
LookupExpression {
handle: expressions.append(expr),
type_id: result_type_id,
},
);
}
}
// Relational and Logical Instructions
Op::LogicalNot => {