From 7f4e07e5cd4dbc534e91cba894b90495c01d1de4 Mon Sep 17 00:00:00 2001 From: teoxoy <28601907+teoxoy@users.noreply.github.com> Date: Wed, 13 Apr 2022 15:05:22 +0200 Subject: [PATCH] [glsl-out] add support for boolean vector `~`, `|` and `&` ops --- src/back/glsl/mod.rs | 94 ++++++++++++++-------- tests/out/glsl/operators.main.Compute.glsl | 6 +- 2 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index 95d8046894..a0cb077fb6 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -356,6 +356,8 @@ pub enum Error { enum BinaryOperation { /// Vector comparison should use the function like `greaterThan()`, etc. VectorCompare, + /// Vector component wise operation; used to polyfill unsupported ops like `|` and `&` for `bvecN`'s + VectorComponentWise, /// GLSL `%` is SPIR-V `OpUMod/OpSMod` and `mod()` is `OpFMod`, but [`BinaryOperator::Modulo`](crate::BinaryOperator::Modulo) is `OpFRem`. Modulo, /// Any plain operation. No additional logic required. @@ -2452,26 +2454,30 @@ impl<'a, W: Write> Writer<'a, W> { Expression::Unary { op, expr } => { use crate::{ScalarKind as Sk, UnaryOperator as Uo}; - write!( - self.out, - "({} ", - match op { - Uo::Negate => "-", - Uo::Not => match ctx.info[expr] - .ty - .inner_with(&self.module.types) - .scalar_kind() - { - Some(Sk::Sint) | Some(Sk::Uint) => "~", - Some(Sk::Bool) => "!", - ref other => - return Err(Error::Custom(format!( - "Cannot apply not to type {:?}", - other - ))), - }, + let ty = ctx.info[expr].ty.inner_with(&self.module.types); + + match *ty { + TypeInner::Vector { kind: Sk::Bool, .. } => { + write!(self.out, "not(")?; } - )?; + _ => { + let operator = match op { + Uo::Negate => "-", + Uo::Not => match ty.scalar_kind() { + Some(Sk::Sint) | Some(Sk::Uint) => "~", + Some(Sk::Bool) => "!", + ref other => { + return Err(Error::Custom(format!( + "Cannot apply not to type {:?}", + other + ))) + } + }, + }; + + write!(self.out, "({} ", operator)?; + } + } self.write_expr(expr, ctx)?; @@ -2494,27 +2500,22 @@ impl<'a, W: Write> Writer<'a, W> { let right_inner = ctx.info[right].ty.inner_with(&self.module.types); let function = match (left_inner, right_inner) { - ( - &Ti::Vector { - kind: left_kind, .. - }, - &Ti::Vector { - kind: right_kind, .. - }, - ) => match op { + (&Ti::Vector { kind, .. }, &Ti::Vector { .. }) => match op { Bo::Less | Bo::LessEqual | Bo::Greater | Bo::GreaterEqual | Bo::Equal | Bo::NotEqual => BinaryOperation::VectorCompare, - Bo::Modulo => match (left_kind, right_kind) { - (Sk::Float, _) | (_, Sk::Float) => match op { - Bo::Modulo => BinaryOperation::Modulo, - _ => BinaryOperation::Other, - }, - _ => BinaryOperation::Other, - }, + Bo::Modulo if kind == Sk::Float => BinaryOperation::Modulo, + Bo::And if kind == Sk::Bool => { + op = crate::BinaryOperator::LogicalAnd; + BinaryOperation::VectorComponentWise + } + Bo::InclusiveOr if kind == Sk::Bool => { + op = crate::BinaryOperator::LogicalOr; + BinaryOperation::VectorComponentWise + } _ => BinaryOperation::Other, }, _ => match (left_inner.scalar_kind(), right_inner.scalar_kind()) { @@ -2554,6 +2555,31 @@ impl<'a, W: Write> Writer<'a, W> { self.write_expr(right, ctx)?; write!(self.out, ")")?; } + BinaryOperation::VectorComponentWise => { + self.write_value_type(left_inner)?; + write!(self.out, "(")?; + + let size = match *left_inner { + Ti::Vector { size, .. } => size, + _ => unreachable!(), + }; + + for i in 0..size as usize { + if i != 0 { + write!(self.out, ", ")?; + } + + self.write_expr(left, ctx)?; + write!(self.out, ".{}", back::COMPONENTS[i])?; + + write!(self.out, " {} ", back::binary_operation_str(op))?; + + self.write_expr(right, ctx)?; + write!(self.out, ".{}", back::COMPONENTS[i])?; + } + + write!(self.out, ")")?; + } BinaryOperation::Modulo => { write!(self.out, "(")?; diff --git a/tests/out/glsl/operators.main.Compute.glsl b/tests/out/glsl/operators.main.Compute.glsl index 464dc97769..0000a28283 100644 --- a/tests/out/glsl/operators.main.Compute.glsl +++ b/tests/out/glsl/operators.main.Compute.glsl @@ -58,13 +58,13 @@ float constructors() { void logical() { bool unnamed_11 = (! true); - bvec2 unnamed_12 = (! bvec2(true)); + bvec2 unnamed_12 = not(bvec2(true)); bool unnamed_13 = (true || false); bool unnamed_14 = (true && false); bool unnamed_15 = (true || false); - bvec3 unnamed_16 = (bvec3(true) | bvec3(false)); + bvec3 unnamed_16 = bvec3(bvec3(true).x || bvec3(false).x, bvec3(true).y || bvec3(false).y, bvec3(true).z || bvec3(false).z); bool unnamed_17 = (true && false); - bvec4 unnamed_18 = (bvec4(true) & bvec4(false)); + bvec4 unnamed_18 = bvec4(bvec4(true).x && bvec4(false).x, bvec4(true).y && bvec4(false).y, bvec4(true).z && bvec4(false).z, bvec4(true).w && bvec4(false).w); } void arithmetic() {