Skip to content

Commit

Permalink
glsl-out: Perform casts in int only math functions
Browse files Browse the repository at this point in the history
Some math functions in naga's IR support both signed and unsigned
integers as arguments but only signed integers in GLSL, this was
somewhat accounted for with casts of the result from int to uint.

But the arguments weren't being cast from uint to int, causing illegal
GLSL to be produced, this PR fixes it by also casting arguments.
  • Loading branch information
JCapucho committed Jun 7, 2022
1 parent 89bed99 commit 2fdc50b
Showing 1 changed file with 46 additions and 22 deletions.
68 changes: 46 additions & 22 deletions src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2798,32 +2798,56 @@ impl<'a, W: Write> Writer<'a, W> {
let extract_bits = fun == Mf::ExtractBits;
let insert_bits = fun == Mf::InsertBits;

// we might need to cast to unsigned integers since
// GLSL's findLSB / findMSB always return signed integers
let need_extra_paren = {
(fun == Mf::FindLsb || fun == Mf::FindMsb || fun == Mf::CountOneBits)
&& match *ctx.info[arg].ty.inner_with(&self.module.types) {
crate::TypeInner::Scalar {
kind: crate::ScalarKind::Uint,
..
} => {
write!(self.out, "uint(")?;
true
}
crate::TypeInner::Vector {
kind: crate::ScalarKind::Uint,
size,
..
} => {
write!(self.out, "uvec{}(", size as u8)?;
true
}
_ => false,
// Some GLSL functions only accept signed integers (like findMSB),
// so they need to be cast to and from int if the argument is an uint
let int_only_function =
matches!(fun, Mf::FindLsb | Mf::FindMsb | Mf::CountOneBits | Mf::Abs);

// The int conversion to be performed in case it's needed,
// is `Some` if the conversion is needed and stores an `Option<VectorSize>`
// with the vector size of the argument (`None` if it's a scalar)
//
// Writes the conversion from int already if that's the case
let int_conversion = if int_only_function {
match *ctx.info[arg].ty.inner_with(&self.module.types) {
crate::TypeInner::Scalar {
kind: crate::ScalarKind::Uint,
..
} => {
write!(self.out, "uint(")?;
Some(None)
}
crate::TypeInner::Vector {
kind: crate::ScalarKind::Uint,
size,
..
} => {
write!(self.out, "uvec{}(", size as u8)?;
Some(Some(size))
}
_ => None,
}
} else {
None
};

write!(self.out, "{}(", fun_name)?;

// Write the conversion to int if needed
if let Some(maybe_size) = int_conversion {
match maybe_size {
Some(size) => write!(self.out, "ivec{}(", size as u8)?,
None => write!(self.out, "int(")?,
}
}

self.write_expr(arg, ctx)?;

// Close the int conversion
if int_conversion.is_some() {
write!(self.out, ")")?
}

if let Some(arg) = arg1 {
write!(self.out, ", ")?;
if extract_bits {
Expand Down Expand Up @@ -2856,7 +2880,7 @@ impl<'a, W: Write> Writer<'a, W> {
}
write!(self.out, ")")?;

if need_extra_paren {
if int_conversion.is_some() {
write!(self.out, ")")?
}
}
Expand Down

0 comments on commit 2fdc50b

Please sign in to comment.