From 881c8a7abc9bc712f140f224a4ef89b759ce96a2 Mon Sep 17 00:00:00 2001 From: Ashley Date: Thu, 29 Apr 2021 16:19:30 +0200 Subject: [PATCH] [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 --- src/front/spv/function.rs | 2 +- src/front/spv/mod.rs | 191 +++++++++++++++++++++++--------------- 2 files changed, 115 insertions(+), 78 deletions(-) diff --git a/src/front/spv/function.rs b/src/front/spv/function.rs index a8e97ba615..c3fae71961 100644 --- a/src/front/spv/function.rs +++ b/src/front/spv/function.rs @@ -149,8 +149,8 @@ impl> super::Parser { fun_id, &mut fun.expressions, &mut fun.local_variables, + &mut module.constants, &module.types, - &module.constants, &module.global_variables, )?; diff --git a/src/front/spv/mod.rs b/src/front/spv/mod.rs index ccea724d5e..1e4384a839 100644 --- a/src/front/spv/mod.rs +++ b/src/front/spv/mod.rs @@ -772,8 +772,8 @@ impl> Parser { function_id: spirv::Word, expressions: &mut Arena, local_arena: &mut Arena, + const_arena: &mut Arena, type_arena: &Arena, - const_arena: &Arena, global_arena: &Arena, ) -> Result { let mut block = Vec::new(); @@ -1695,84 +1695,121 @@ impl> Parser { } 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 => {