diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 19f07392d8..98d7b4c188 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -1447,33 +1447,54 @@ impl<'a, W: Write> Writer<'a, W> { // `Binary` we just write `left op right` // Once again we wrap everything in parantheses to avoid precedence issues Expression::Binary { op, left, right } => { - write!(self.out, "(")?; + // Holds `Some(function_name)` if the binary operation is + // implemented as a function call + let function = if let (TypeInner::Vector { .. }, TypeInner::Vector { .. }) = ( + ctx.typifier.get(left, &self.module.types), + ctx.typifier.get(right, &self.module.types), + ) { + match op { + BinaryOperator::Less => Some("lessThan"), + BinaryOperator::LessEqual => Some("lessThanEqual"), + BinaryOperator::Greater => Some("greaterThan"), + BinaryOperator::GreaterEqual => Some("greaterThanEqual"), + _ => None, + } + } else { + None + }; + + write!(self.out, "{}(", function.unwrap_or(""))?; self.write_expr(left, ctx)?; - write!( - self.out, - " {} ", - match op { - BinaryOperator::Add => "+", - BinaryOperator::Subtract => "-", - BinaryOperator::Multiply => "*", - BinaryOperator::Divide => "/", - BinaryOperator::Modulo => "%", - BinaryOperator::Equal => "==", - BinaryOperator::NotEqual => "!=", - BinaryOperator::Less => "<", - BinaryOperator::LessEqual => "<=", - BinaryOperator::Greater => ">", - BinaryOperator::GreaterEqual => ">=", - BinaryOperator::And => "&", - BinaryOperator::ExclusiveOr => "^", - BinaryOperator::InclusiveOr => "|", - BinaryOperator::LogicalAnd => "&&", - BinaryOperator::LogicalOr => "||", - BinaryOperator::ShiftLeft => "<<", - BinaryOperator::ShiftRight => ">>", - } - )?; + if function.is_some() { + write!(self.out, ",")? + } else { + write!( + self.out, + " {} ", + match op { + BinaryOperator::Add => "+", + BinaryOperator::Subtract => "-", + BinaryOperator::Multiply => "*", + BinaryOperator::Divide => "/", + BinaryOperator::Modulo => "%", + BinaryOperator::Equal => "==", + BinaryOperator::NotEqual => "!=", + BinaryOperator::Less => "<", + BinaryOperator::LessEqual => "<=", + BinaryOperator::Greater => ">", + BinaryOperator::GreaterEqual => ">=", + BinaryOperator::And => "&", + BinaryOperator::ExclusiveOr => "^", + BinaryOperator::InclusiveOr => "|", + BinaryOperator::LogicalAnd => "&&", + BinaryOperator::LogicalOr => "||", + BinaryOperator::ShiftLeft => "<<", + BinaryOperator::ShiftRight => ">>", + } + )?; + } self.write_expr(right, ctx)?; diff --git a/src/front/glsl/functions.rs b/src/front/glsl/functions.rs index 7ec4b4e11e..a9f45bad8d 100644 --- a/src/front/glsl/functions.rs +++ b/src/front/glsl/functions.rs @@ -1,6 +1,6 @@ use crate::{ proc::{ensure_block_returns, Typifier}, - Block, Expression, Function, MathFunction, SampleLevel, TypeInner, + BinaryOperator, Block, Expression, Function, MathFunction, SampleLevel, TypeInner, }; use super::{ast::*, error::ErrorKind}; @@ -123,6 +123,24 @@ impl Program { statements: fc.args.into_iter().flat_map(|a| a.statements).collect(), }) } + "lessThan" | "greaterThan" => { + if fc.args.len() != 2 { + return Err(ErrorKind::WrongNumberArgs(name, 2, fc.args.len())); + } + Ok(ExpressionRule { + expression: self.context.expressions.append(Expression::Binary { + op: match name.as_str() { + "lessThan" => BinaryOperator::Less, + "greaterThan" => BinaryOperator::Greater, + _ => unreachable!(), + }, + left: fc.args[0].expression, + right: fc.args[1].expression, + }), + sampler: None, + statements: fc.args.into_iter().flat_map(|a| a.statements).collect(), + }) + } func_name => { let function = *self.lookup_function.get(func_name).ok_or_else(|| { ErrorKind::SemanticError(