Skip to content
This repository has been archived by the owner on Jan 29, 2025. It is now read-only.

[wgsl-in] Support radians/degrees builtin functions #1627

Merged
merged 1 commit into from
Dec 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2445,6 +2445,8 @@ impl<'a, W: Write> Writer<'a, W> {
Mf::Asinh => "asinh",
Mf::Acosh => "acosh",
Mf::Atanh => "atanh",
Mf::Radians => "radians",
Mf::Degrees => "degrees",
// glsl doesn't have atan2 function
// use two-argument variation of the atan function
Mf::Atan2 => "atan",
Expand Down
2 changes: 2 additions & 0 deletions src/back/hlsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1835,6 +1835,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
Mf::Asinh => Function::Asincosh { is_sin: true },
Mf::Acosh => Function::Asincosh { is_sin: false },
Mf::Atanh => Function::Atanh,
Mf::Radians => Function::Regular("radians"),
Mf::Degrees => Function::Regular("degrees"),
// decomposition
Mf::Ceil => Function::Regular("ceil"),
Mf::Floor => Function::Regular("floor"),
Expand Down
10 changes: 10 additions & 0 deletions src/back/msl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,8 @@ impl<W: Write> Writer<W> {
Mf::Asinh => "asinh",
Mf::Acosh => "acosh",
Mf::Atanh => "atanh",
Mf::Radians => "",
Mf::Degrees => "",
// decomposition
Mf::Ceil => "ceil",
Mf::Floor => "floor",
Expand Down Expand Up @@ -1223,6 +1225,14 @@ impl<W: Write> Writer<W> {
write!(self.out, "as_type<uint>(half2(")?;
self.put_expression(arg, context, false)?;
write!(self.out, "))")?;
} else if fun == Mf::Radians {
write!(self.out, "((")?;
self.put_expression(arg, context, false)?;
write!(self.out, ") * 0.017453292519943295474)")?;
} else if fun == Mf::Degrees {
write!(self.out, "((")?;
self.put_expression(arg, context, false)?;
write!(self.out, ") * 57.295779513082322865)")?;
} else {
write!(self.out, "{}::{}", NAMESPACE, fun_name)?;
self.put_call_parameters(
Expand Down
2 changes: 2 additions & 0 deletions src/back/spv/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,8 @@ impl<'w> BlockContext<'w> {
Mf::Asinh => MathOp::Ext(spirv::GLOp::Asinh),
Mf::Acosh => MathOp::Ext(spirv::GLOp::Acosh),
Mf::Atanh => MathOp::Ext(spirv::GLOp::Atanh),
Mf::Radians => MathOp::Ext(spirv::GLOp::Radians),
Mf::Degrees => MathOp::Ext(spirv::GLOp::Degrees),
// decomposition
Mf::Ceil => MathOp::Ext(spirv::GLOp::Ceil),
Mf::Round => MathOp::Ext(spirv::GLOp::RoundEven),
Expand Down
2 changes: 2 additions & 0 deletions src/back/wgsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1527,6 +1527,8 @@ impl<W: Write> Writer<W> {
Mf::Asinh => Function::Asincosh { is_sin: true },
Mf::Acosh => Function::Asincosh { is_sin: false },
Mf::Atanh => Function::Atanh,
Mf::Radians => Function::Regular("radians"),
Mf::Degrees => Function::Regular("degrees"),
// decomposition
Mf::Ceil => Function::Regular("ceil"),
Mf::Floor => Function::Regular("floor"),
Expand Down
33 changes: 4 additions & 29 deletions src/front/glsl/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use super::{
Error, ErrorKind, Parser, Result,
};
use crate::{
BinaryOperator, Block, Constant, ConstantInner, DerivativeAxis, Expression, Handle, ImageClass,
BinaryOperator, Block, Constant, DerivativeAxis, Expression, Handle, ImageClass,
ImageDimension, ImageQuery, MathFunction, Module, RelationalFunction, SampleLevel,
ScalarKind as Sk, ScalarValue, Span, Type, TypeInner, VectorSize,
ScalarKind as Sk, Span, Type, TypeInner, VectorSize,
};

impl Module {
Expand Down Expand Up @@ -535,8 +535,8 @@ pub fn inject_builtin(declaration: &mut FunctionDeclaration, module: &mut Module
"asinh" => MacroCall::MathFunction(MathFunction::Asinh),
"acosh" => MacroCall::MathFunction(MathFunction::Acosh),
"atanh" => MacroCall::MathFunction(MathFunction::Atanh),
"radians" => MacroCall::ConstMultiply(std::f64::consts::PI / 180.0),
"degrees" => MacroCall::ConstMultiply(180.0 / std::f64::consts::PI),
"radians" => MacroCall::MathFunction(MathFunction::Radians),
"degrees" => MacroCall::MathFunction(MathFunction::Degrees),
"floatBitsToInt" => MacroCall::BitCast(Sk::Sint),
"floatBitsToUint" => MacroCall::BitCast(Sk::Uint),
"dFdx" | "dFdxFine" | "dFdxCoarse" => {
Expand Down Expand Up @@ -1551,7 +1551,6 @@ pub enum MacroCall {
Splatted(MathFunction, Option<VectorSize>, usize),
MixBoolean,
Clamp(Option<VectorSize>),
ConstMultiply(f64),
BitCast(Sk),
Derivate(DerivativeAxis),
}
Expand Down Expand Up @@ -1868,30 +1867,6 @@ impl MacroCall {
body,
))
}
MacroCall::ConstMultiply(value) => {
let constant = parser.module.constants.fetch_or_append(
Constant {
name: None,
specialization: None,
inner: ConstantInner::Scalar {
width: 4,
value: ScalarValue::Float(value),
},
},
Span::default(),
);
let right =
ctx.add_expression(Expression::Constant(constant), Span::default(), body);
Ok(ctx.add_expression(
Expression::Binary {
op: BinaryOperator::Multiply,
left: args[0],
right,
},
Span::default(),
body,
))
}
MacroCall::BitCast(kind) => Ok(ctx.add_expression(
Expression::As {
expr: args[0],
Expand Down
259 changes: 106 additions & 153 deletions src/front/spv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2531,162 +2531,115 @@ 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))?;

if gl_op == Glo::Radians || gl_op == Glo::Degrees {
inst.expect(base_wc + 1)?;
let arg = {
let arg_id = self.next()?;
let lexp = self.lookup_expression.lookup(arg_id)?;
get_expr_handle!(arg_id, lexp)
};

// constant expressions need to be excluded from the emitter
block.extend(emitter.finish(ctx.expressions));
let const_value = match gl_op {
Glo::Radians => std::f64::consts::PI / 180.0,
Glo::Degrees => 180.0 / std::f64::consts::PI,
_ => unreachable!(),
};
let const_handle = ctx.const_arena.fetch_or_append(
crate::Constant {
name: None,
specialization: None,
inner: crate::ConstantInner::Scalar {
width: 4,
value: crate::ScalarValue::Float(const_value),
},
},
crate::Span::default(),
);
let expr_handle = ctx.expressions.append(
crate::Expression::Constant(const_handle),
crate::Span::default(),
);
emitter.start(ctx.expressions);
let fun = match gl_op {
Glo::Round => Mf::Round,
Glo::RoundEven => 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::Asinh => Mf::Asinh,
Glo::Acosh => Mf::Acosh,
Glo::Atanh => Mf::Atanh,
Glo::Radians => Mf::Radians,
Glo::Degrees => Mf::Degrees,
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::MatrixInverse => Mf::Inverse,
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,
Glo::PackUnorm4x8 => Mf::Pack4x8unorm,
Glo::PackSnorm4x8 => Mf::Pack4x8snorm,
Glo::PackHalf2x16 => Mf::Pack2x16float,
Glo::PackUnorm2x16 => Mf::Pack2x16unorm,
Glo::PackSnorm2x16 => Mf::Pack2x16snorm,
Glo::UnpackUnorm4x8 => Mf::Unpack4x8unorm,
Glo::UnpackSnorm4x8 => Mf::Unpack4x8snorm,
Glo::UnpackHalf2x16 => Mf::Unpack2x16float,
Glo::UnpackUnorm2x16 => Mf::Unpack2x16unorm,
Glo::UnpackSnorm2x16 => Mf::Unpack2x16snorm,
Glo::FindILsb => Mf::FindLsb,
Glo::FindUMsb | Glo::FindSMsb => Mf::FindMsb,
_ => return Err(Error::UnsupportedExtInst(inst_id)),
};

self.lookup_expression.insert(
result_id,
LookupExpression {
handle: ctx.expressions.append(
crate::Expression::Binary {
op: crate::BinaryOperator::Multiply,
left: arg,
right: expr_handle,
},
span,
),
type_id: result_type_id,
block_id,
},
);
let arg_count = fun.argument_count();
inst.expect(base_wc + arg_count as u16)?;
let arg = {
let arg_id = self.next()?;
let lexp = self.lookup_expression.lookup(arg_id)?;
get_expr_handle!(arg_id, lexp)
};
let arg1 = if arg_count > 1 {
let arg_id = self.next()?;
let lexp = self.lookup_expression.lookup(arg_id)?;
Some(get_expr_handle!(arg_id, lexp))
} else {
let fun = match gl_op {
Glo::Round => Mf::Round,
Glo::RoundEven => 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::Asinh => Mf::Asinh,
Glo::Acosh => Mf::Acosh,
Glo::Atanh => Mf::Atanh,
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::MatrixInverse => Mf::Inverse,
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,
Glo::PackUnorm4x8 => Mf::Pack4x8unorm,
Glo::PackSnorm4x8 => Mf::Pack4x8snorm,
Glo::PackHalf2x16 => Mf::Pack2x16float,
Glo::PackUnorm2x16 => Mf::Pack2x16unorm,
Glo::PackSnorm2x16 => Mf::Pack2x16snorm,
Glo::UnpackUnorm4x8 => Mf::Unpack4x8unorm,
Glo::UnpackSnorm4x8 => Mf::Unpack4x8snorm,
Glo::UnpackHalf2x16 => Mf::Unpack2x16float,
Glo::UnpackUnorm2x16 => Mf::Unpack2x16unorm,
Glo::UnpackSnorm2x16 => Mf::Unpack2x16snorm,
Glo::FindILsb => Mf::FindLsb,
Glo::FindUMsb | Glo::FindSMsb => Mf::FindMsb,
_ => 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()?;
let lexp = self.lookup_expression.lookup(arg_id)?;
get_expr_handle!(arg_id, lexp)
};
let arg1 = if arg_count > 1 {
let arg_id = self.next()?;
let lexp = self.lookup_expression.lookup(arg_id)?;
Some(get_expr_handle!(arg_id, lexp))
} else {
None
};
let arg2 = if arg_count > 2 {
let arg_id = self.next()?;
let lexp = self.lookup_expression.lookup(arg_id)?;
Some(get_expr_handle!(arg_id, lexp))
} else {
None
};
let arg3 = if arg_count > 3 {
let arg_id = self.next()?;
let lexp = self.lookup_expression.lookup(arg_id)?;
Some(get_expr_handle!(arg_id, lexp))
} else {
None
};
None
};
let arg2 = if arg_count > 2 {
let arg_id = self.next()?;
let lexp = self.lookup_expression.lookup(arg_id)?;
Some(get_expr_handle!(arg_id, lexp))
} else {
None
};
let arg3 = if arg_count > 3 {
let arg_id = self.next()?;
let lexp = self.lookup_expression.lookup(arg_id)?;
Some(get_expr_handle!(arg_id, lexp))
} else {
None
};

let expr = crate::Expression::Math {
fun,
arg,
arg1,
arg2,
arg3,
};
self.lookup_expression.insert(
result_id,
LookupExpression {
handle: ctx.expressions.append(expr, span),
type_id: result_type_id,
block_id,
},
);
}
let expr = crate::Expression::Math {
fun,
arg,
arg1,
arg2,
arg3,
};
self.lookup_expression.insert(
result_id,
LookupExpression {
handle: ctx.expressions.append(expr, span),
type_id: result_type_id,
block_id,
},
);
}
// Relational and Logical Instructions
Op::LogicalNot => {
Expand Down
Loading