Skip to content

Commit

Permalink
glsl-in: Perform casts in int only math functions
Browse files Browse the repository at this point in the history
Some functions like abs only accept signed integers while naga's IR
accepts both signed and unsigned integers, this wasn't accounted for in
the glsl backend causing it to produce code that wouldn't type check.

This commit addresses it by performing casts from uint to int of the
function argument and then back from int to uint for the function
return.
  • Loading branch information
JCapucho committed Jun 7, 2022
1 parent 89bed99 commit 850cb13
Showing 1 changed file with 51 additions and 23 deletions.
74 changes: 51 additions & 23 deletions src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2798,32 +2798,59 @@ 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 always return signed integers (like findMSB),
// so they need to be cast to uint if the argument is also an uint.
let needs_int_to_uint =
matches!(fun, Mf::FindLsb | Mf::FindMsb | Mf::CountOneBits | Mf::Abs);

// Some GLSL functions only accept signed integers (like abs),
// so they need their argument cast from uint to int.
let needs_uint_to_int = matches!(fun, Mf::Abs);

// Check if the argument is an unsigned integer and return the vector size
// in case it's a vector
let maybe_uint_size = match *ctx.info[arg].ty.inner_with(&self.module.types) {
crate::TypeInner::Scalar {
kind: crate::ScalarKind::Uint,
..
} => Some(None),
crate::TypeInner::Vector {
kind: crate::ScalarKind::Uint,
size,
..
} => Some(Some(size)),
_ => None,
};

if let Some(maybe_size) = maybe_uint_size {
// Cast to uint if the function needs it
if needs_int_to_uint {
match maybe_size {
Some(size) => write!(self.out, "uvec{}(", size as u8)?,
None => write!(self.out, "uint(")?,
}
}
}

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

if let Some(maybe_size) = maybe_uint_size {
// Cast to int if the function needs it
if needs_uint_to_int {
match maybe_size {
Some(size) => write!(self.out, "ivec{}(", size as u8)?,
None => write!(self.out, "int(")?,
}
}
}

self.write_expr(arg, ctx)?;

// Close the cast from uint to int
if needs_uint_to_int && maybe_uint_size.is_some() {
write!(self.out, ")")?
}

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

if need_extra_paren {
// Close the cast from int to uint
if needs_int_to_uint && maybe_uint_size.is_some() {
write!(self.out, ")")?
}
}
Expand Down

0 comments on commit 850cb13

Please sign in to comment.