From ffdfaf94e2e9f3698377d919a684f2943c44e39e Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Wed, 24 May 2023 23:56:34 -0400 Subject: [PATCH 01/21] unsigned pack and unpack --- src/back/hlsl/writer.rs | 81 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 940f0ae373..f61ba10e69 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -126,7 +126,17 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { crate::MathFunction::Asinh | crate::MathFunction::Acosh | crate::MathFunction::Atanh - | crate::MathFunction::Unpack2x16float => { + | crate::MathFunction::Unpack2x16float + | crate::MathFunction::Unpack2x16snorm + | crate::MathFunction::Unpack2x16unorm + | crate::MathFunction::Unpack4x8snorm + | crate::MathFunction::Unpack4x8unorm + // TODO: These use multiple args, unsure how to bake them + | crate::MathFunction::Pack2x16float + | crate::MathFunction::Pack2x16snorm + | crate::MathFunction::Pack2x16unorm + | crate::MathFunction::Pack4x8snorm + | crate::MathFunction::Pack4x8unorm => { self.need_bake_expressions.insert(arg); } crate::MathFunction::CountLeadingZeros => { @@ -2590,7 +2600,10 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { enum Function { Asincosh { is_sin: bool }, Atanh, + Pack2x16float, + PackBits { signed: bool, dims: u32, scale: f32 }, Unpack2x16float, + UnpackBits { signed: bool, dims: u32, scale: f32 }, Regular(&'static str), MissingIntOverload(&'static str), MissingIntReturnType(&'static str), @@ -2664,7 +2677,18 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Mf::ReverseBits => Function::MissingIntOverload("reversebits"), Mf::FindLsb => Function::MissingIntReturnType("firstbitlow"), Mf::FindMsb => Function::MissingIntReturnType("firstbithigh"), + // Data Packing + Mf::Pack2x16float => Function::Pack2x16float, + // Mf::Pack2x16snorm => Function::PackBits { signed: true, dims: 2, scale: 32767.0 }, + Mf::Pack2x16unorm => Function::PackBits { signed: false, dims: 2, scale: 65535.0 }, + // Mf::Pack4x8snorm => Function::PackBits { signed: true, dims: 4, scale: 127.0 }, + Mf::Pack4x8unorm => Function::PackBits { signed: false, dims: 4, scale: 255.0 }, + // Data Unpacking Mf::Unpack2x16float => Function::Unpack2x16float, + // Mf::Unpack2x16snorm => Function::UnpackBits { signed: true, dims: 2, scale: 32767.0 }, + Mf::Unpack2x16unorm => Function::UnpackBits { signed: false, dims: 2, scale: 65535.0 }, + // Mf::Unpack4x8snorm => Function::UnpackBits { signed: true, dims: 4, scale: 127.0 }, + Mf::Unpack4x8unorm => Function::UnpackBits { signed: false, dims: 4, scale: 255.0 }, _ => return Err(Error::Unimplemented(format!("write_expr_math {fun:?}"))), }; @@ -2688,6 +2712,42 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!(self.out, "))")?; } + Function::Pack2x16float => { + write!(self.out, "f32tof16(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ") | (f32tof16(")?; + if let Some(arg) = arg1 { + self.write_expr(module, arg, func_ctx)?; + } + write!(self.out, ") << 16)")?; + } + Function::PackBits { signed, dims, scale } => { + if dims == 4 { + write!(self.out, "uint((f32(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ", 0, 1) * {scale}) + 0.5) | (f32(clamp(")?; + if let Some(arg) = arg1 { + self.write_expr(module, arg, func_ctx)?; + } + write!(self.out, ", 0, 1) * {scale}) + 0.5) << 8 | (f32(clamp(")?; + if let Some(arg) = arg2 { + self.write_expr(module, arg, func_ctx)?; + } + write!(self.out, ", 0, 1) * {scale}) + 0.5) << 16 | (f32(clamp(")?; + if let Some(arg) = arg3 { + self.write_expr(module, arg, func_ctx)?; + } + write!(self.out, ", 0, 1) * {scale}) + 0.5) << 24))")?; + } else if dims == 2 { + write!(self.out, "uint((f32(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ", 0, 1) * {scale}) + 0.5) | (f32(clamp(")?; + if let Some(arg) = arg1 { + self.write_expr(module, arg, func_ctx)?; + } + write!(self.out, ", 0, 1) * {scale}) + 0.5) << 16))")?; + } + } Function::Unpack2x16float => { write!(self.out, "float2(f16tof32(")?; self.write_expr(module, arg, func_ctx)?; @@ -2695,6 +2755,25 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!(self.out, ") >> 16))")?; } + Function::UnpackBits { signed, dims, scale } => { + if dims == 4 { + write!(self.out, "float4(float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "& 0xff) / {scale}, float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ">> 8 & 0xff) / {scale}, float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ">> 16 & 0xff) / {scale}, float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ">> 24) / {scale}))")?; + } else if dims == 2 { + write!(self.out, "float2(float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "& 0xffff) / {scale}, float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ">> 16) / {scale}))")?; + } + } Function::Regular(fun_name) => { write!(self.out, "{fun_name}(")?; self.write_expr(module, arg, func_ctx)?; From 1dfd7fa024734b5a28f94bb19bb363e222f927bb Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Mon, 29 May 2023 19:09:00 -0400 Subject: [PATCH 02/21] pack+unpack signed, fix unsigned pack+unpack --- src/back/hlsl/writer.rs | 186 ++++++++++++++++++++++++++++++---------- 1 file changed, 141 insertions(+), 45 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index f61ba10e69..044979fb8f 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2679,16 +2679,48 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Mf::FindMsb => Function::MissingIntReturnType("firstbithigh"), // Data Packing Mf::Pack2x16float => Function::Pack2x16float, - // Mf::Pack2x16snorm => Function::PackBits { signed: true, dims: 2, scale: 32767.0 }, - Mf::Pack2x16unorm => Function::PackBits { signed: false, dims: 2, scale: 65535.0 }, - // Mf::Pack4x8snorm => Function::PackBits { signed: true, dims: 4, scale: 127.0 }, - Mf::Pack4x8unorm => Function::PackBits { signed: false, dims: 4, scale: 255.0 }, + Mf::Pack2x16snorm => Function::PackBits { + signed: true, + dims: 2, + scale: 32767.0, + }, + Mf::Pack2x16unorm => Function::PackBits { + signed: false, + dims: 2, + scale: 65535.0, + }, + Mf::Pack4x8snorm => Function::PackBits { + signed: true, + dims: 4, + scale: 127.0, + }, + Mf::Pack4x8unorm => Function::PackBits { + signed: false, + dims: 4, + scale: 255.0, + }, // Data Unpacking Mf::Unpack2x16float => Function::Unpack2x16float, - // Mf::Unpack2x16snorm => Function::UnpackBits { signed: true, dims: 2, scale: 32767.0 }, - Mf::Unpack2x16unorm => Function::UnpackBits { signed: false, dims: 2, scale: 65535.0 }, - // Mf::Unpack4x8snorm => Function::UnpackBits { signed: true, dims: 4, scale: 127.0 }, - Mf::Unpack4x8unorm => Function::UnpackBits { signed: false, dims: 4, scale: 255.0 }, + Mf::Unpack2x16snorm => Function::UnpackBits { + signed: true, + dims: 2, + scale: 32767.0, + }, + Mf::Unpack2x16unorm => Function::UnpackBits { + signed: false, + dims: 2, + scale: 65535.0, + }, + Mf::Unpack4x8snorm => Function::UnpackBits { + signed: true, + dims: 4, + scale: 127.0, + }, + Mf::Unpack4x8unorm => Function::UnpackBits { + signed: false, + dims: 4, + scale: 255.0, + }, _ => return Err(Error::Unimplemented(format!("write_expr_math {fun:?}"))), }; @@ -2715,37 +2747,73 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Function::Pack2x16float => { write!(self.out, "f32tof16(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") | (f32tof16(")?; - if let Some(arg) = arg1 { - self.write_expr(module, arg, func_ctx)?; - } - write!(self.out, ") << 16)")?; + write!(self.out, "[0]) | (f32tof16(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[1]) << 16)")?; } - Function::PackBits { signed, dims, scale } => { + Function::PackBits { + signed, + dims, + scale, + } => { if dims == 4 { - write!(self.out, "uint((f32(clamp(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, ", 0, 1) * {scale}) + 0.5) | (f32(clamp(")?; - if let Some(arg) = arg1 { + if signed { + // pack4x8snorm + write!(self.out, "uint(int(float(clamp(")?; self.write_expr(module, arg, func_ctx)?; - } - write!(self.out, ", 0, 1) * {scale}) + 0.5) << 8 | (f32(clamp(")?; - if let Some(arg) = arg2 { + write!( + self.out, + "[0], -1, 1) * {scale}) + 0.5) & 0xFF) | ((int(float(clamp(" + )?; self.write_expr(module, arg, func_ctx)?; - } - write!(self.out, ", 0, 1) * {scale}) + 0.5) << 16 | (f32(clamp(")?; - if let Some(arg) = arg3 { + write!(self.out, "[1], -1, 1) * {scale}) + 0.5) & 0xFF) << 8) | ((int(float(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[2], -1, 1) * {scale}) + 0.5) & 0xFF) << 16) | ((int(float(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[3], -1, 1) * {scale}) + 0.5) << 24))",)?; + } else { + // pack4x8unorm + write!(self.out, "uint(uint(float(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[0], 0, 1) * {scale}) + 0.5) | uint(float(clamp(" + )?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[1], 0, 1) * {scale}) + 0.5) << 8 | uint(float(clamp(" + )?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[2], 0, 1) * {scale}) + 0.5) << 16 | uint(float(clamp(" + )?; self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[3], 0, 1) * {scale}) + 0.5) << 24)")?; } - write!(self.out, ", 0, 1) * {scale}) + 0.5) << 24))")?; } else if dims == 2 { - write!(self.out, "uint((f32(clamp(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, ", 0, 1) * {scale}) + 0.5) | (f32(clamp(")?; - if let Some(arg) = arg1 { + if signed { + // pack2x16snorm + write!(self.out, "uint(int(float(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[0], -1, 1) * {scale}) + 0.5) & 0xFF) | ((int(float(clamp(" + )?; self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[1], -1, 1) * {scale}) + 0.5) << 16))",)?; + } else { + // pack2x16unorm + write!(self.out, "uint(uint(float(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[0], 0, 1) * {scale}) + 0.5) | uint(float(clamp(" + )?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[1], 0, 1) * {scale}) + 0.5) << 16)")?; } - write!(self.out, ", 0, 1) * {scale}) + 0.5) << 16))")?; } } Function::Unpack2x16float => { @@ -2755,23 +2823,51 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!(self.out, ") >> 16))")?; } - Function::UnpackBits { signed, dims, scale } => { + Function::UnpackBits { + signed, + dims, + scale, + } => { if dims == 4 { - write!(self.out, "float4(float(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, "& 0xff) / {scale}, float(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, ">> 8 & 0xff) / {scale}, float(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, ">> 16 & 0xff) / {scale}, float(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, ">> 24) / {scale}))")?; + if signed { + // Unpack4x8snorm + write!(self.out, "float4(float(int(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ") & 0xff) / {scale}, float(int(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ") >> 8 & 0xff) / {scale}, float(int(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ") >> 16 & 0xff) / {scale}, float(int(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ") >> 24) / {scale})")?; + } else { + // Unpack4x8unorm + write!(self.out, "float4(float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " & 0xff) / {scale}, float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " >> 8 & 0xff) / {scale}, float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " >> 16 & 0xff) / {scale}, float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " >> 24) / {scale})")?; + } } else if dims == 2 { - write!(self.out, "float2(float(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, "& 0xffff) / {scale}, float(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, ">> 16) / {scale}))")?; + if signed { + // Unpack2x16snorm + write!(self.out, "float2(float(int(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ") & 0xffff) / {scale}, float(int(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ") >> 16) / {scale})")?; + } else { + // Unpack2x16unorm + write!(self.out, "float2(float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " & 0xffff) / {scale}, float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " >> 16) / {scale})")?; + } } } Function::Regular(fun_name) => { From ec070f56dce466aa3ae7b844d7e9961916763783 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Wed, 31 May 2023 18:51:09 -0400 Subject: [PATCH 03/21] fix snorm packing --- src/back/hlsl/writer.rs | 74 ++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 044979fb8f..676ee2b044 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2601,9 +2601,9 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Asincosh { is_sin: bool }, Atanh, Pack2x16float, - PackBits { signed: bool, dims: u32, scale: f32 }, + PackBits { signed: bool, dims: u32, scale: u32 }, Unpack2x16float, - UnpackBits { signed: bool, dims: u32, scale: f32 }, + UnpackBits { signed: bool, dims: u32, scale: u32 }, Regular(&'static str), MissingIntOverload(&'static str), MissingIntReturnType(&'static str), @@ -2682,44 +2682,44 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Mf::Pack2x16snorm => Function::PackBits { signed: true, dims: 2, - scale: 32767.0, + scale: 32767, }, Mf::Pack2x16unorm => Function::PackBits { signed: false, dims: 2, - scale: 65535.0, + scale: 65535, }, Mf::Pack4x8snorm => Function::PackBits { signed: true, dims: 4, - scale: 127.0, + scale: 127, }, Mf::Pack4x8unorm => Function::PackBits { signed: false, dims: 4, - scale: 255.0, + scale: 255, }, // Data Unpacking Mf::Unpack2x16float => Function::Unpack2x16float, Mf::Unpack2x16snorm => Function::UnpackBits { signed: true, dims: 2, - scale: 32767.0, + scale: 32767, }, Mf::Unpack2x16unorm => Function::UnpackBits { signed: false, dims: 2, - scale: 65535.0, + scale: 65535, }, Mf::Unpack4x8snorm => Function::UnpackBits { signed: true, dims: 4, - scale: 127.0, + scale: 127, }, Mf::Unpack4x8unorm => Function::UnpackBits { signed: false, dims: 4, - scale: 255.0, + scale: 255, }, _ => return Err(Error::Unimplemented(format!("write_expr_math {fun:?}"))), }; @@ -2759,60 +2759,60 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { if dims == 4 { if signed { // pack4x8snorm - write!(self.out, "uint(int(float(clamp(")?; + write!(self.out, "uint((int(round(clamp(")?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[0], -1, 1) * {scale}) + 0.5) & 0xFF) | ((int(float(clamp(" + "[0], -1.0, 1.0) * {scale}.0)) & 0xFF) | ((int(round(clamp(" )?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[1], -1, 1) * {scale}) + 0.5) & 0xFF) << 8) | ((int(float(clamp(")?; + write!(self.out, "[1], -1.0, 1.0) * {scale}.0)) & 0xFF) << 8) | ((int(round(clamp(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[2], -1, 1) * {scale}) + 0.5) & 0xFF) << 16) | ((int(float(clamp(")?; + write!(self.out, "[2], -1.0, 1.0) * {scale}.0)) & 0xFF) << 16) | ((int(round(clamp(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[3], -1, 1) * {scale}) + 0.5) << 24))",)?; + write!(self.out, "[3], -1.0, 1.0) * {scale}.0)) & 0xFF) << 24))",)?; } else { // pack4x8unorm - write!(self.out, "uint(uint(float(clamp(")?; + write!(self.out, "uint(uint(clamp(")?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[0], 0, 1) * {scale}) + 0.5) | uint(float(clamp(" + "[0], 0.0, 1.0) * {scale}.0 + 0.5) | uint(clamp(" )?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[1], 0, 1) * {scale}) + 0.5) << 8 | uint(float(clamp(" + "[1], 0.0, 1.0) * {scale}.0 + 0.5) << 8 | uint(clamp(" )?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[2], 0, 1) * {scale}) + 0.5) << 16 | uint(float(clamp(" + "[2], 0.0, 1.0) * {scale}.0 + 0.5) << 16 | uint(clamp(" )?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[3], 0, 1) * {scale}) + 0.5) << 24)")?; + write!(self.out, "[3], 0.0, 1.0) * {scale}.0 + 0.5) << 24)")?; } } else if dims == 2 { if signed { // pack2x16snorm - write!(self.out, "uint(int(float(clamp(")?; + write!(self.out, "uint((int(round(clamp(")?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[0], -1, 1) * {scale}) + 0.5) & 0xFF) | ((int(float(clamp(" + "[0], -1.0, 1.0) * {scale}.0 ))) & 0xFFFF) | (((int(round(clamp(" )?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[1], -1, 1) * {scale}) + 0.5) << 16))",)?; + write!(self.out, "[1], -1.0, 1.0) * {scale}.0)) & 0xFFFF) << 16))",)?; } else { // pack2x16unorm write!(self.out, "uint(uint(float(clamp(")?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[0], 0, 1) * {scale}) + 0.5) | uint(float(clamp(" + "[0], 0, 1) * {scale}.0) + 0.5) | uint(float(clamp(" )?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[1], 0, 1) * {scale}) + 0.5) << 16)")?; + write!(self.out, "[1], 0, 1) * {scale}.0) + 0.5) << 16)")?; } } } @@ -2833,40 +2833,40 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { // Unpack4x8snorm write!(self.out, "float4(float(int(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") & 0xff) / {scale}, float(int(")?; + write!(self.out, ") & 0xff) / {scale}.0, float(int(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 8 & 0xff) / {scale}, float(int(")?; + write!(self.out, ") >> 8 & 0xff) / {scale}.0, float(int(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 16 & 0xff) / {scale}, float(int(")?; + write!(self.out, ") >> 16 & 0xff) / {scale}.0, float(int(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 24) / {scale})")?; + write!(self.out, ") >> 24) / {scale}.0)")?; } else { // Unpack4x8unorm write!(self.out, "float4(float(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " & 0xff) / {scale}, float(")?; + write!(self.out, " & 0xff) / {scale}.0, float(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 8 & 0xff) / {scale}, float(")?; + write!(self.out, " >> 8 & 0xff) / {scale}.0, float(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 16 & 0xff) / {scale}, float(")?; + write!(self.out, " >> 16 & 0xff) / {scale}.0, float(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 24) / {scale})")?; + write!(self.out, " >> 24) / {scale}.0)")?; } } else if dims == 2 { if signed { // Unpack2x16snorm write!(self.out, "float2(float(int(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") & 0xffff) / {scale}, float(int(")?; + write!(self.out, ") & 0xffff) / {scale}.0, float(int(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 16) / {scale})")?; + write!(self.out, ") >> 16) / {scale}.0)")?; } else { // Unpack2x16unorm write!(self.out, "float2(float(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " & 0xffff) / {scale}, float(")?; + write!(self.out, " & 0xffff) / {scale}.0, float(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 16) / {scale})")?; + write!(self.out, " >> 16) / {scale}.0)")?; } } } From 0b9aa5b9f37251c3e94547e5d855f43779d6aa4d Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 1 Jun 2023 02:44:39 -0400 Subject: [PATCH 04/21] fix unpacking snorm --- src/back/hlsl/writer.rs | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 676ee2b044..7da86ca510 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2802,7 +2802,10 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { "[0], -1.0, 1.0) * {scale}.0 ))) & 0xFFFF) | (((int(round(clamp(" )?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[1], -1.0, 1.0) * {scale}.0)) & 0xFFFF) << 16))",)?; + write!( + self.out, + "[1], -1.0, 1.0) * {scale}.0)) & 0xFFFF) << 16))", + )?; } else { // pack2x16unorm write!(self.out, "uint(uint(float(clamp(")?; @@ -2831,42 +2834,42 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { if dims == 4 { if signed { // Unpack4x8snorm - write!(self.out, "float4(float(int(")?; + write!(self.out, "clamp(float4((int4(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") & 0xff) / {scale}.0, float(int(")?; + write!(self.out, "<< 24, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 8 & 0xff) / {scale}.0, float(int(")?; + write!(self.out, " << 16, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 16 & 0xff) / {scale}.0, float(int(")?; + write!(self.out, " << 8, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 24) / {scale}.0)")?; + write!(self.out, ") >> 24)) / {scale}.0, -1.0, 1.0)")?; } else { // Unpack4x8unorm - write!(self.out, "float4(float(")?; + write!(self.out, "clamp(float4(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " & 0xff) / {scale}.0, float(")?; + write!(self.out, " & 0xFF, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 8 & 0xff) / {scale}.0, float(")?; + write!(self.out, " >> 8 & 0xFF, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 16 & 0xff) / {scale}.0, float(")?; + write!(self.out, " >> 16 & 0xFF, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 24) / {scale}.0)")?; + write!(self.out, " >> 24 & 0xFF) / {scale}.0, 0.0, 1.0)")?; } } else if dims == 2 { if signed { // Unpack2x16snorm - write!(self.out, "float2(float(int(")?; + write!(self.out, "clamp(float2(int2(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") & 0xffff) / {scale}.0, float(int(")?; + write!(self.out, "<< 16, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 16) / {scale}.0)")?; + write!(self.out, ") >> 16) / {scale}.0, -1.0, 1.0)")?; } else { // Unpack2x16unorm - write!(self.out, "float2(float(")?; + write!(self.out, "clamp(float2(float(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " & 0xffff) / {scale}.0, float(")?; + write!(self.out, " & 0xFFFF), float(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 16) / {scale}.0)")?; + write!(self.out, " >> 16 & 0xFFFF)) / {scale}.0, 0.0, 1.0)")?; } } } From 4c30bcc29ac0116b7ed9fdb5ac54e088bd7972e5 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Tue, 6 Jun 2023 00:56:39 -0400 Subject: [PATCH 05/21] insertbits --- src/back/hlsl/writer.rs | 59 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 7da86ca510..58ea5a7e81 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2600,6 +2600,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { enum Function { Asincosh { is_sin: bool }, Atanh, + InsertBits, Pack2x16float, PackBits { signed: bool, dims: u32, scale: u32 }, Unpack2x16float, @@ -2677,6 +2678,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Mf::ReverseBits => Function::MissingIntOverload("reversebits"), Mf::FindLsb => Function::MissingIntReturnType("firstbitlow"), Mf::FindMsb => Function::MissingIntReturnType("firstbithigh"), + Mf::InsertBits => Function::InsertBits, // Data Packing Mf::Pack2x16float => Function::Pack2x16float, Mf::Pack2x16snorm => Function::PackBits { @@ -2744,6 +2746,63 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!(self.out, "))")?; } + // e: T, + // newbits: T, + // offset: u32, + // count: u32 + // returns T + // T is i32, u32, vecN, or vecN + Function::InsertBits => { + // ((S0.u & S1.u) | (~S0.u & S2.u)) + // TODO: what + if let (Some(newbits), Some(offset), Some(count)) = (arg1, arg2, arg3) { + // write!(self.out, "(")?; + // self.write_expr(module, arg, func_ctx)?; + // write!(self.out, " & ~")?; + // // mask + // write!(self.out, "((-1 >> (32 - ")?; + // self.write_expr(module, arg1, func_ctx)?; + // write!(self.out, ")) << ")?; + // self.write_expr(module, arg2, func_ctx)?; + // write!(self.out, ")")?; + // // End mask + // write!(self.out, ") | ((")?; + // self.write_expr(module, arg3, func_ctx)?; + // write!(self.out, " << ")?; + // self.write_expr(module, arg2, func_ctx)?; + // write!(self.out, ") & ")?; + // // mask + // write!(self.out, "((-1 >> (32 - ")?; + // self.write_expr(module, arg1, func_ctx)?; + // write!(self.out, ")) << ")?; + // self.write_expr(module, arg2, func_ctx)?; + // write!(self.out, "))")?; + write!(self.out, "(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " & ~")?; + // ((((1u << count) - 1u) << offset) & 0xffffffffu) + // mask + write!(self.out, "((((1u << ")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, ") - 1u) << ")?; + self.write_expr(module, offset, func_ctx)?; + write!(self.out, ") & 0xffffffffu)")?; + // end mask + write!(self.out, ") | ((")?; + self.write_expr(module, newbits, func_ctx)?; + write!(self.out, " << ")?; + self.write_expr(module, offset, func_ctx)?; + write!(self.out, ") & ")?; + // mask + write!(self.out, "((((1u << ")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, ") - 1u) << ")?; + self.write_expr(module, offset, func_ctx)?; + write!(self.out, ") & 0xffffffffu)")?; + // end mask + write!(self.out, ")")?; + } + } Function::Pack2x16float => { write!(self.out, "f32tof16(")?; self.write_expr(module, arg, func_ctx)?; From 4f40fe0d983101ee38a0d87e74868504d963fdc9 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Wed, 7 Jun 2023 04:07:28 -0400 Subject: [PATCH 06/21] fix insertbits --- src/back/hlsl/writer.rs | 47 +++++++++++++---------------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 58ea5a7e81..b9585f6124 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2753,54 +2753,37 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { // returns T // T is i32, u32, vecN, or vecN Function::InsertBits => { - // ((S0.u & S1.u) | (~S0.u & S2.u)) - // TODO: what + // mask = ((0xFFFFFFFFu >> (32 - count)) << offset) + // return (count == 0 ? e : ((e & ~mask) | ((newbits << offset) & mask))) if let (Some(newbits), Some(offset), Some(count)) = (arg1, arg2, arg3) { - // write!(self.out, "(")?; - // self.write_expr(module, arg, func_ctx)?; - // write!(self.out, " & ~")?; - // // mask - // write!(self.out, "((-1 >> (32 - ")?; - // self.write_expr(module, arg1, func_ctx)?; - // write!(self.out, ")) << ")?; - // self.write_expr(module, arg2, func_ctx)?; - // write!(self.out, ")")?; - // // End mask - // write!(self.out, ") | ((")?; - // self.write_expr(module, arg3, func_ctx)?; - // write!(self.out, " << ")?; - // self.write_expr(module, arg2, func_ctx)?; - // write!(self.out, ") & ")?; - // // mask - // write!(self.out, "((-1 >> (32 - ")?; - // self.write_expr(module, arg1, func_ctx)?; - // write!(self.out, ")) << ")?; - // self.write_expr(module, arg2, func_ctx)?; - // write!(self.out, "))")?; + write!(self.out, "(")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, " == 0 ? ")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " : ")?; write!(self.out, "(")?; self.write_expr(module, arg, func_ctx)?; write!(self.out, " & ~")?; - // ((((1u << count) - 1u) << offset) & 0xffffffffu) // mask - write!(self.out, "((((1u << ")?; + write!(self.out, "((0xFFFFFFFFu >> (32u - ")?; self.write_expr(module, count, func_ctx)?; - write!(self.out, ") - 1u) << ")?; + write!(self.out, ")) << ")?; self.write_expr(module, offset, func_ctx)?; - write!(self.out, ") & 0xffffffffu)")?; + write!(self.out, ")")?; // end mask write!(self.out, ") | ((")?; self.write_expr(module, newbits, func_ctx)?; write!(self.out, " << ")?; self.write_expr(module, offset, func_ctx)?; write!(self.out, ") & ")?; - // mask - write!(self.out, "((((1u << ")?; + // // mask + write!(self.out, "((0xFFFFFFFFu >> (32u - ")?; self.write_expr(module, count, func_ctx)?; - write!(self.out, ") - 1u) << ")?; + write!(self.out, ")) << ")?; self.write_expr(module, offset, func_ctx)?; - write!(self.out, ") & 0xffffffffu)")?; - // end mask write!(self.out, ")")?; + // // end mask + write!(self.out, "))")?; } } Function::Pack2x16float => { From dc0cb65346d4bccf8e7b574684bb2799a68f020a Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 8 Jun 2023 00:12:57 -0400 Subject: [PATCH 07/21] extractbits --- src/back/hlsl/writer.rs | 58 ++++++++++++++++++++++++++++++++++++----- src/proc/mod.rs | 11 ++++++++ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index b9585f6124..0c03eae735 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2600,6 +2600,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { enum Function { Asincosh { is_sin: bool }, Atanh, + ExtractBits, InsertBits, Pack2x16float, PackBits { signed: bool, dims: u32, scale: u32 }, @@ -2678,6 +2679,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Mf::ReverseBits => Function::MissingIntOverload("reversebits"), Mf::FindLsb => Function::MissingIntReturnType("firstbitlow"), Mf::FindMsb => Function::MissingIntReturnType("firstbithigh"), + Mf::ExtractBits => Function::ExtractBits, Mf::InsertBits => Function::InsertBits, // Data Packing Mf::Pack2x16float => Function::Pack2x16float, @@ -2746,12 +2748,56 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!(self.out, "))")?; } - // e: T, - // newbits: T, - // offset: u32, - // count: u32 - // returns T - // T is i32, u32, vecN, or vecN + Function::ExtractBits => { + // e: T, + // offset: u32, + // count: u32 + // T is u32 or i32 or vecN or vecN + if let (Some(offset), Some(count)) = (arg1, arg2) { + let inner = func_ctx.info[expr].ty.inner_with(&module.types); + let scalar_kind = inner.scalar_kind(); + let scalar_width = inner.scalar_width().unwrap_or(32); + let scalar_max: u32 = match scalar_width { + 8 => 0xff, + 16 => 0xffff, + 32 => 0xffffffff, + _ => { + return Err(Error::Unimplemented(format!( + "write_expr_math extract_bits for scalar_width {}", + scalar_width + ))) + } + }; + + if let Some(ScalarKind::Uint) = scalar_kind { + // Unsigned + // ((e >> offset) & (count == 32u ? 0xffffffffu : ((1 << count) - 1))) + write!(self.out, "((")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " >> ")?; + self.write_expr(module, offset, func_ctx)?; + write!(self.out, ") & (")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, " == {scalar_width}u ? {scalar_max}u : ((1 << ")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, ") - 1)))")?; + } else { + // Signed + // (count == 0 ? 0 : (e << (32 - count - offset)) >> (32 - count)) + write!(self.out, "(")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, " == 0 ? 0 : (")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " << ({scalar_width} - ")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, " - ")?; + self.write_expr(module, offset, func_ctx)?; + write!(self.out, ")) >> ({scalar_width} - ")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, "))")?; + } + } + } Function::InsertBits => { // mask = ((0xFFFFFFFFu >> (32 - count)) << offset) // return (count == 0 ? e : ((e & ~mask) | ((newbits << offset) & mask))) diff --git a/src/proc/mod.rs b/src/proc/mod.rs index ddcca263c8..c61fbdd932 100644 --- a/src/proc/mod.rs +++ b/src/proc/mod.rs @@ -190,6 +190,17 @@ impl super::TypeInner { } } + pub const fn scalar_width(&self) -> Option { + // Multiply by 8 to get the bit width + match *self { + super::TypeInner::Scalar { width, .. } | super::TypeInner::Vector { width, .. } => { + Some(width * 8) + } + super::TypeInner::Matrix { width, .. } => Some(width * 8), + _ => None, + } + } + pub const fn pointer_space(&self) -> Option { match *self { Self::Pointer { space, .. } => Some(space), From 101c31a57f3ae5c6edc98be4d29adedd0c3ff198 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 8 Jun 2023 00:15:46 -0400 Subject: [PATCH 08/21] make insert work with non-32bit types --- src/back/hlsl/writer.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 0c03eae735..4021eb69ea 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2799,9 +2799,29 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { } } Function::InsertBits => { - // mask = ((0xFFFFFFFFu >> (32 - count)) << offset) - // return (count == 0 ? e : ((e & ~mask) | ((newbits << offset) & mask))) + // e: T, + // newbits: T, + // offset: u32, + // count: u32 + // returns T + // T is i32, u32, vecN, or vecN if let (Some(newbits), Some(offset), Some(count)) = (arg1, arg2, arg3) { + let inner = func_ctx.info[expr].ty.inner_with(&module.types); + let scalar_width = inner.scalar_width().unwrap_or(32); + let scalar_max: u64 = match scalar_width { + 8 => 0xff, + 16 => 0xffff, + 32 => 0xffffffff, + 64 => 0xffffffffffffffff, + _ => { + return Err(Error::Unimplemented(format!( + "write_expr_math extract_bits for scalar_width {}", + scalar_width + ))) + } + }; + // mask = ((0xFFFFFFFFu >> (32 - count)) << offset) + // return (count == 0 ? e : ((e & ~mask) | ((newbits << offset) & mask))) write!(self.out, "(")?; self.write_expr(module, count, func_ctx)?; write!(self.out, " == 0 ? ")?; @@ -2811,7 +2831,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!(self.out, " & ~")?; // mask - write!(self.out, "((0xFFFFFFFFu >> (32u - ")?; + write!(self.out, "(({scalar_max}u >> ({scalar_width}u - ")?; self.write_expr(module, count, func_ctx)?; write!(self.out, ")) << ")?; self.write_expr(module, offset, func_ctx)?; @@ -2823,7 +2843,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, offset, func_ctx)?; write!(self.out, ") & ")?; // // mask - write!(self.out, "((0xFFFFFFFFu >> (32u - ")?; + write!(self.out, "(({scalar_max}u >> ({scalar_width}u - ")?; self.write_expr(module, count, func_ctx)?; write!(self.out, ")) << ")?; self.write_expr(module, offset, func_ctx)?; From 5b2b08e6e50965e15a920476822177e54182da79 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 8 Jun 2023 00:16:35 -0400 Subject: [PATCH 09/21] floor instead of round for pack snorm --- src/back/hlsl/writer.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 4021eb69ea..be4a3ffab7 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2867,21 +2867,21 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { if dims == 4 { if signed { // pack4x8snorm - write!(self.out, "uint((int(round(clamp(")?; + write!(self.out, "uint((int(floor(clamp(")?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[0], -1.0, 1.0) * {scale}.0)) & 0xFF) | ((int(round(clamp(" + "[0], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) | ((int(floor(clamp(" )?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[1], -1.0, 1.0) * {scale}.0)) & 0xFF) << 8) | ((int(round(clamp(")?; + write!(self.out, "[1], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 8) | ((int(floor(clamp(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[2], -1.0, 1.0) * {scale}.0)) & 0xFF) << 16) | ((int(round(clamp(")?; + write!(self.out, "[2], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 16) | ((int(floor(clamp(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[3], -1.0, 1.0) * {scale}.0)) & 0xFF) << 24))",)?; + write!(self.out, "[3], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 24))",)?; } else { // pack4x8unorm - write!(self.out, "uint(uint(clamp(")?; + write!(self.out, "(uint(clamp(")?; self.write_expr(module, arg, func_ctx)?; write!( self.out, @@ -2903,16 +2903,16 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { } else if dims == 2 { if signed { // pack2x16snorm - write!(self.out, "uint((int(round(clamp(")?; + write!(self.out, "uint((int(floor(clamp(")?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[0], -1.0, 1.0) * {scale}.0 ))) & 0xFFFF) | (((int(round(clamp(" + "[0], -1.0, 1.0) * {scale}.0 + 0.5))) & 0xFFFF) | (((int(floor(clamp(" )?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[1], -1.0, 1.0) * {scale}.0)) & 0xFFFF) << 16))", + "[1], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFFFF) << 16))", )?; } else { // pack2x16unorm From fa27104ac9ecb8b86ddb544cd26548086d3cb2d0 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 8 Jun 2023 00:26:21 -0400 Subject: [PATCH 10/21] tests --- tests/out/hlsl/bits.hlsl | 131 ++++++++++++++++++++++++++++++++ tests/out/hlsl/bits.hlsl.config | 3 + tests/snapshots.rs | 2 +- 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 tests/out/hlsl/bits.hlsl create mode 100644 tests/out/hlsl/bits.hlsl.config diff --git a/tests/out/hlsl/bits.hlsl b/tests/out/hlsl/bits.hlsl new file mode 100644 index 0000000000..f1b1ec6048 --- /dev/null +++ b/tests/out/hlsl/bits.hlsl @@ -0,0 +1,131 @@ + +[numthreads(1, 1, 1)] +void main() +{ + int i = (int)0; + int2 i2_ = (int2)0; + int3 i3_ = (int3)0; + int4 i4_ = (int4)0; + uint u = (uint)0; + uint2 u2_ = (uint2)0; + uint3 u3_ = (uint3)0; + uint4 u4_ = (uint4)0; + float2 f2_ = (float2)0; + float4 f4_ = (float4)0; + + i = 0; + i2_ = (0).xx; + i3_ = (0).xxx; + i4_ = (0).xxxx; + u = 0u; + u2_ = (0u).xx; + u3_ = (0u).xxx; + u4_ = (0u).xxxx; + f2_ = (0.0).xx; + f4_ = (0.0).xxxx; + float4 _expr28 = f4_; + u = uint((int(floor(clamp(_expr28[0], -1.0, 1.0) * 127.0 + 0.5)) & 0xFF) | ((int(floor(clamp(_expr28[1], -1.0, 1.0) * 127.0 + 0.5)) & 0xFF) << 8) | ((int(floor(clamp(_expr28[2], -1.0, 1.0) * 127.0 + 0.5)) & 0xFF) << 16) | ((int(floor(clamp(_expr28[3], -1.0, 1.0) * 127.0 + 0.5)) & 0xFF) << 24)); + float4 _expr30 = f4_; + u = (uint(clamp(_expr30[0], 0.0, 1.0) * 255.0 + 0.5) | uint(clamp(_expr30[1], 0.0, 1.0) * 255.0 + 0.5) << 8 | uint(clamp(_expr30[2], 0.0, 1.0) * 255.0 + 0.5) << 16 | uint(clamp(_expr30[3], 0.0, 1.0) * 255.0 + 0.5) << 24); + float2 _expr32 = f2_; + u = uint((int(floor(clamp(_expr32[0], -1.0, 1.0) * 32767.0 + 0.5))) & 0xFFFF) | (((int(floor(clamp(_expr32[1], -1.0, 1.0) * 32767.0 + 0.5)) & 0xFFFF) << 16)); + float2 _expr34 = f2_; + u = uint(uint(float(clamp(_expr34[0], 0, 1) * 65535.0) + 0.5) | uint(float(clamp(_expr34[1], 0, 1) * 65535.0) + 0.5) << 16); + float2 _expr36 = f2_; + u = f32tof16(_expr36[0]) | (f32tof16(_expr36[1]) << 16); + uint _expr38 = u; + f4_ = clamp(float4((int4(_expr38<< 24, _expr38 << 16, _expr38 << 8, _expr38) >> 24)) / 127.0, -1.0, 1.0); + uint _expr40 = u; + f4_ = clamp(float4(_expr40 & 0xFF, _expr40 >> 8 & 0xFF, _expr40 >> 16 & 0xFF, _expr40 >> 24 & 0xFF) / 255.0, 0.0, 1.0); + uint _expr42 = u; + f2_ = clamp(float2(int2(_expr42<< 16, _expr42) >> 16) / 32767.0, -1.0, 1.0); + uint _expr44 = u; + f2_ = clamp(float2(float(_expr44 & 0xFFFF), float(_expr44 >> 16 & 0xFFFF)) / 65535.0, 0.0, 1.0); + uint _expr46 = u; + f2_ = float2(f16tof32(_expr46), f16tof32((_expr46) >> 16)); + int _expr48 = i; + int _expr49 = i; + i = (10u == 0 ? _expr48 : (_expr48 & ~((4294967295u >> (32u - 10u)) << 5u)) | ((_expr49 << 5u) & ((4294967295u >> (32u - 10u)) << 5u))); + int2 _expr53 = i2_; + int2 _expr54 = i2_; + i2_ = (10u == 0 ? _expr53 : (_expr53 & ~((4294967295u >> (32u - 10u)) << 5u)) | ((_expr54 << 5u) & ((4294967295u >> (32u - 10u)) << 5u))); + int3 _expr58 = i3_; + int3 _expr59 = i3_; + i3_ = (10u == 0 ? _expr58 : (_expr58 & ~((4294967295u >> (32u - 10u)) << 5u)) | ((_expr59 << 5u) & ((4294967295u >> (32u - 10u)) << 5u))); + int4 _expr63 = i4_; + int4 _expr64 = i4_; + i4_ = (10u == 0 ? _expr63 : (_expr63 & ~((4294967295u >> (32u - 10u)) << 5u)) | ((_expr64 << 5u) & ((4294967295u >> (32u - 10u)) << 5u))); + uint _expr68 = u; + uint _expr69 = u; + u = (10u == 0 ? _expr68 : (_expr68 & ~((4294967295u >> (32u - 10u)) << 5u)) | ((_expr69 << 5u) & ((4294967295u >> (32u - 10u)) << 5u))); + uint2 _expr73 = u2_; + uint2 _expr74 = u2_; + u2_ = (10u == 0 ? _expr73 : (_expr73 & ~((4294967295u >> (32u - 10u)) << 5u)) | ((_expr74 << 5u) & ((4294967295u >> (32u - 10u)) << 5u))); + uint3 _expr78 = u3_; + uint3 _expr79 = u3_; + u3_ = (10u == 0 ? _expr78 : (_expr78 & ~((4294967295u >> (32u - 10u)) << 5u)) | ((_expr79 << 5u) & ((4294967295u >> (32u - 10u)) << 5u))); + uint4 _expr83 = u4_; + uint4 _expr84 = u4_; + u4_ = (10u == 0 ? _expr83 : (_expr83 & ~((4294967295u >> (32u - 10u)) << 5u)) | ((_expr84 << 5u) & ((4294967295u >> (32u - 10u)) << 5u))); + int _expr88 = i; + i = (10u == 0 ? 0 : (_expr88 << (32 - 10u - 5u)) >> (32 - 10u)); + int2 _expr92 = i2_; + i2_ = (10u == 0 ? 0 : (_expr92 << (32 - 10u - 5u)) >> (32 - 10u)); + int3 _expr96 = i3_; + i3_ = (10u == 0 ? 0 : (_expr96 << (32 - 10u - 5u)) >> (32 - 10u)); + int4 _expr100 = i4_; + i4_ = (10u == 0 ? 0 : (_expr100 << (32 - 10u - 5u)) >> (32 - 10u)); + uint _expr104 = u; + u = ((_expr104 >> 5u) & (10u == 32u ? 4294967295u : ((1u << 10u) - 1))); + uint2 _expr108 = u2_; + u2_ = ((_expr108 >> 5u) & (10u == 32u ? 4294967295u : ((1u << 10u) - 1))); + uint3 _expr112 = u3_; + u3_ = ((_expr112 >> 5u) & (10u == 32u ? 4294967295u : ((1u << 10u) - 1))); + uint4 _expr116 = u4_; + u4_ = ((_expr116 >> 5u) & (10u == 32u ? 4294967295u : ((1u << 10u) - 1))); + int _expr120 = i; + i = asint(firstbitlow(_expr120)); + uint2 _expr122 = u2_; + u2_ = firstbitlow(_expr122); + int3 _expr124 = i3_; + i3_ = asint(firstbithigh(_expr124)); + uint3 _expr126 = u3_; + u3_ = firstbithigh(_expr126); + int _expr128 = i; + i = asint(firstbithigh(_expr128)); + uint _expr130 = u; + u = firstbithigh(_expr130); + int _expr132 = i; + i = asint(countbits(asuint(_expr132))); + int2 _expr134 = i2_; + i2_ = asint(countbits(asuint(_expr134))); + int3 _expr136 = i3_; + i3_ = asint(countbits(asuint(_expr136))); + int4 _expr138 = i4_; + i4_ = asint(countbits(asuint(_expr138))); + uint _expr140 = u; + u = countbits(_expr140); + uint2 _expr142 = u2_; + u2_ = countbits(_expr142); + uint3 _expr144 = u3_; + u3_ = countbits(_expr144); + uint4 _expr146 = u4_; + u4_ = countbits(_expr146); + int _expr148 = i; + i = asint(reversebits(asuint(_expr148))); + int2 _expr150 = i2_; + i2_ = asint(reversebits(asuint(_expr150))); + int3 _expr152 = i3_; + i3_ = asint(reversebits(asuint(_expr152))); + int4 _expr154 = i4_; + i4_ = asint(reversebits(asuint(_expr154))); + uint _expr156 = u; + u = reversebits(_expr156); + uint2 _expr158 = u2_; + u2_ = reversebits(_expr158); + uint3 _expr160 = u3_; + u3_ = reversebits(_expr160); + uint4 _expr162 = u4_; + u4_ = reversebits(_expr162); + return; +} diff --git a/tests/out/hlsl/bits.hlsl.config b/tests/out/hlsl/bits.hlsl.config new file mode 100644 index 0000000000..246c485cf7 --- /dev/null +++ b/tests/out/hlsl/bits.hlsl.config @@ -0,0 +1,3 @@ +vertex=() +fragment=() +compute=(main:cs_5_1 ) diff --git a/tests/snapshots.rs b/tests/snapshots.rs index 1ea52b46ce..4a111f9b94 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -420,7 +420,7 @@ fn convert_wgsl() { ), ( "bits", - Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::WGSL, + Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL, ), ( "bitcast", From 33823e5825b862d2c61cf6691950a35c17a69da2 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 8 Jun 2023 00:27:04 -0400 Subject: [PATCH 11/21] typecast --- src/back/hlsl/writer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index be4a3ffab7..90bcd59347 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2778,7 +2778,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, offset, func_ctx)?; write!(self.out, ") & (")?; self.write_expr(module, count, func_ctx)?; - write!(self.out, " == {scalar_width}u ? {scalar_max}u : ((1 << ")?; + write!(self.out, " == {scalar_width}u ? {scalar_max}u : ((1u << ")?; self.write_expr(module, count, func_ctx)?; write!(self.out, ") - 1)))")?; } else { From fca553a5184b6eccbf1b1c41269c9ed2fe31f729 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Fri, 9 Jun 2023 00:21:26 -0400 Subject: [PATCH 12/21] fmt --- src/back/hlsl/writer.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 90bcd59347..8c9dd80974 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2878,7 +2878,10 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!(self.out, "[2], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 16) | ((int(floor(clamp(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[3], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 24))",)?; + write!( + self.out, + "[3], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 24))", + )?; } else { // pack4x8unorm write!(self.out, "(uint(clamp(")?; From 217b14bdbb9439ddd10e746a433bbfd9448f23be Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Fri, 9 Jun 2023 00:36:53 -0400 Subject: [PATCH 13/21] hlsl tests bits.ron --- tests/out/hlsl/bits.ron | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/out/hlsl/bits.ron diff --git a/tests/out/hlsl/bits.ron b/tests/out/hlsl/bits.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/bits.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) From 214b837c2ea74b27d26c62cd9fe8804a64bfd10f Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 15 Jun 2023 17:24:29 -0400 Subject: [PATCH 14/21] replace `PackBits` and `UnpackBits` with the inner function names (eg. `Unpack4x8snorm`) --- src/back/hlsl/writer.rs | 284 ++++++++++++++++++---------------------- 1 file changed, 125 insertions(+), 159 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 8c9dd80974..7cc5ab9727 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2603,9 +2603,15 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { ExtractBits, InsertBits, Pack2x16float, - PackBits { signed: bool, dims: u32, scale: u32 }, + Pack2x16snorm, + Pack2x16unorm, + Pack4x8snorm, + Pack4x8unorm, Unpack2x16float, - UnpackBits { signed: bool, dims: u32, scale: u32 }, + Unpack2x16snorm, + Unpack2x16unorm, + Unpack4x8snorm, + Unpack4x8unorm, Regular(&'static str), MissingIntOverload(&'static str), MissingIntReturnType(&'static str), @@ -2683,48 +2689,16 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Mf::InsertBits => Function::InsertBits, // Data Packing Mf::Pack2x16float => Function::Pack2x16float, - Mf::Pack2x16snorm => Function::PackBits { - signed: true, - dims: 2, - scale: 32767, - }, - Mf::Pack2x16unorm => Function::PackBits { - signed: false, - dims: 2, - scale: 65535, - }, - Mf::Pack4x8snorm => Function::PackBits { - signed: true, - dims: 4, - scale: 127, - }, - Mf::Pack4x8unorm => Function::PackBits { - signed: false, - dims: 4, - scale: 255, - }, + Mf::Pack2x16snorm => Function::Pack2x16snorm, + Mf::Pack2x16unorm => Function::Pack2x16unorm, + Mf::Pack4x8snorm => Function::Pack4x8snorm, + Mf::Pack4x8unorm => Function::Pack4x8unorm, // Data Unpacking Mf::Unpack2x16float => Function::Unpack2x16float, - Mf::Unpack2x16snorm => Function::UnpackBits { - signed: true, - dims: 2, - scale: 32767, - }, - Mf::Unpack2x16unorm => Function::UnpackBits { - signed: false, - dims: 2, - scale: 65535, - }, - Mf::Unpack4x8snorm => Function::UnpackBits { - signed: true, - dims: 4, - scale: 127, - }, - Mf::Unpack4x8unorm => Function::UnpackBits { - signed: false, - dims: 4, - scale: 255, - }, + Mf::Unpack2x16snorm => Function::Unpack2x16snorm, + Mf::Unpack2x16unorm => Function::Unpack2x16unorm, + Mf::Unpack4x8snorm => Function::Unpack4x8snorm, + Mf::Unpack4x8unorm => Function::Unpack4x8unorm, _ => return Err(Error::Unimplemented(format!("write_expr_math {fun:?}"))), }; @@ -2815,7 +2789,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { 64 => 0xffffffffffffffff, _ => { return Err(Error::Unimplemented(format!( - "write_expr_math extract_bits for scalar_width {}", + "write_expr_math insert_bits for scalar_width {}", scalar_width ))) } @@ -2859,77 +2833,72 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!(self.out, "[1]) << 16)")?; } - Function::PackBits { - signed, - dims, - scale, - } => { - if dims == 4 { - if signed { - // pack4x8snorm - write!(self.out, "uint((int(floor(clamp(")?; - self.write_expr(module, arg, func_ctx)?; - write!( - self.out, - "[0], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) | ((int(floor(clamp(" - )?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[1], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 8) | ((int(floor(clamp(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[2], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 16) | ((int(floor(clamp(")?; - self.write_expr(module, arg, func_ctx)?; - write!( - self.out, - "[3], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 24))", - )?; - } else { - // pack4x8unorm - write!(self.out, "(uint(clamp(")?; - self.write_expr(module, arg, func_ctx)?; - write!( - self.out, - "[0], 0.0, 1.0) * {scale}.0 + 0.5) | uint(clamp(" - )?; - self.write_expr(module, arg, func_ctx)?; - write!( - self.out, - "[1], 0.0, 1.0) * {scale}.0 + 0.5) << 8 | uint(clamp(" - )?; - self.write_expr(module, arg, func_ctx)?; - write!( - self.out, - "[2], 0.0, 1.0) * {scale}.0 + 0.5) << 16 | uint(clamp(" - )?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[3], 0.0, 1.0) * {scale}.0 + 0.5) << 24)")?; - } - } else if dims == 2 { - if signed { - // pack2x16snorm - write!(self.out, "uint((int(floor(clamp(")?; - self.write_expr(module, arg, func_ctx)?; - write!( - self.out, - "[0], -1.0, 1.0) * {scale}.0 + 0.5))) & 0xFFFF) | (((int(floor(clamp(" - )?; - self.write_expr(module, arg, func_ctx)?; - write!( - self.out, - "[1], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFFFF) << 16))", - )?; - } else { - // pack2x16unorm - write!(self.out, "uint(uint(float(clamp(")?; - self.write_expr(module, arg, func_ctx)?; - write!( - self.out, - "[0], 0, 1) * {scale}.0) + 0.5) | uint(float(clamp(" - )?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[1], 0, 1) * {scale}.0) + 0.5) << 16)")?; - } - } + Function::Pack2x16snorm => { + let scale = 32767; + + write!(self.out, "uint((int(floor(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[0], -1.0, 1.0) * {scale}.0 + 0.5))) & 0xFFFF) | (((int(floor(clamp(" + )?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[1], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFFFF) << 16))", + )?; } + Function::Pack2x16unorm => { + let scale = 65535; + + write!(self.out, "uint(uint(float(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[0], 0, 1) * {scale}.0) + 0.5) | uint(float(clamp(" + )?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[1], 0, 1) * {scale}.0) + 0.5) << 16)")?; + } + Function::Pack4x8snorm => { + let scale = 127; + + write!(self.out, "uint((int(floor(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[0], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) | ((int(floor(clamp(" + )?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[1], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 8) | ((int(floor(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[2], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 16) | ((int(floor(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[3], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 24))", + )?; + } + Function::Pack4x8unorm => { + let scale = 255; + + write!(self.out, "(uint(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[0], 0.0, 1.0) * {scale}.0 + 0.5) | uint(clamp(")?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[1], 0.0, 1.0) * {scale}.0 + 0.5) << 8 | uint(clamp(" + )?; + self.write_expr(module, arg, func_ctx)?; + write!( + self.out, + "[2], 0.0, 1.0) * {scale}.0 + 0.5) << 16 | uint(clamp(" + )?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[3], 0.0, 1.0) * {scale}.0 + 0.5) << 24)")?; + } + Function::Unpack2x16float => { write!(self.out, "float2(f16tof32(")?; self.write_expr(module, arg, func_ctx)?; @@ -2937,52 +2906,49 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!(self.out, ") >> 16))")?; } - Function::UnpackBits { - signed, - dims, - scale, - } => { - if dims == 4 { - if signed { - // Unpack4x8snorm - write!(self.out, "clamp(float4((int4(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, "<< 24, ")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, " << 16, ")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, " << 8, ")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 24)) / {scale}.0, -1.0, 1.0)")?; - } else { - // Unpack4x8unorm - write!(self.out, "clamp(float4(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, " & 0xFF, ")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 8 & 0xFF, ")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 16 & 0xFF, ")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 24 & 0xFF) / {scale}.0, 0.0, 1.0)")?; - } - } else if dims == 2 { - if signed { - // Unpack2x16snorm - write!(self.out, "clamp(float2(int2(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, "<< 16, ")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 16) / {scale}.0, -1.0, 1.0)")?; - } else { - // Unpack2x16unorm - write!(self.out, "clamp(float2(float(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, " & 0xFFFF), float(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 16 & 0xFFFF)) / {scale}.0, 0.0, 1.0)")?; - } - } + Function::Unpack2x16snorm => { + let scale = 32767; + + write!(self.out, "clamp(float2(int2(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "<< 16, ")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ") >> 16) / {scale}.0, -1.0, 1.0)")?; + } + Function::Unpack2x16unorm => { + let scale = 65535; + + write!(self.out, "clamp(float2(float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " & 0xFFFF), float(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " >> 16 & 0xFFFF)) / {scale}.0, 0.0, 1.0)")?; + } + Function::Unpack4x8snorm => { + let scale = 127; + + write!(self.out, "clamp(float4((int4(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "<< 24, ")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " << 16, ")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " << 8, ")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, ") >> 24)) / {scale}.0, -1.0, 1.0)")?; + } + Function::Unpack4x8unorm => { + let scale = 255; + + write!(self.out, "clamp(float4(")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " & 0xFF, ")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " >> 8 & 0xFF, ")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " >> 16 & 0xFF, ")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " >> 24 & 0xFF) / {scale}.0, 0.0, 1.0)")?; } Function::Regular(fun_name) => { write!(self.out, "{fun_name}(")?; From 3a74190d4e4353b9084a7e43da146a4339593304 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 15 Jun 2023 17:38:37 -0400 Subject: [PATCH 15/21] round instead of floor --- src/back/hlsl/writer.rs | 43 +++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 7cc5ab9727..cdf9c4dbf3 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2836,67 +2836,64 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Function::Pack2x16snorm => { let scale = 32767; - write!(self.out, "uint((int(floor(clamp(")?; + write!(self.out, "uint((int(round(clamp(")?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[0], -1.0, 1.0) * {scale}.0 + 0.5))) & 0xFFFF) | (((int(floor(clamp(" + "[0], -1.0, 1.0) * {scale}.0))) & 0xFFFF) | (((int(round(clamp(" )?; self.write_expr(module, arg, func_ctx)?; - write!( - self.out, - "[1], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFFFF) << 16))", - )?; + write!(self.out, "[1], -1.0, 1.0) * {scale}.0)) & 0xFFFF) << 16))",)?; } Function::Pack2x16unorm => { let scale = 65535; - write!(self.out, "uint(uint(float(clamp(")?; + write!(self.out, "(uint(round(clamp(")?; self.write_expr(module, arg, func_ctx)?; - write!( - self.out, - "[0], 0, 1) * {scale}.0) + 0.5) | uint(float(clamp(" - )?; + write!(self.out, "[0], 0.0, 1.0) * {scale}.0)) | uint(round(clamp(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[1], 0, 1) * {scale}.0) + 0.5) << 16)")?; + write!(self.out, "[1], 0.0, 1.0) * {scale}.0)) << 16)")?; } Function::Pack4x8snorm => { let scale = 127; - write!(self.out, "uint((int(floor(clamp(")?; + write!(self.out, "uint((int(round(clamp(")?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[0], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) | ((int(floor(clamp(" + "[0], -1.0, 1.0) * {scale}.0)) & 0xFF) | ((int(round(clamp(" )?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[1], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 8) | ((int(floor(clamp(")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[2], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 16) | ((int(floor(clamp(")?; + write!( + self.out, + "[1], -1.0, 1.0) * {scale}.0)) & 0xFF) << 8) | ((int(round(clamp(" + )?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[3], -1.0, 1.0) * {scale}.0 + 0.5)) & 0xFF) << 24))", + "[2], -1.0, 1.0) * {scale}.0)) & 0xFF) << 16) | ((int(round(clamp(" )?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, "[3], -1.0, 1.0) * {scale}.0)) & 0xFF) << 24))",)?; } Function::Pack4x8unorm => { let scale = 255; - write!(self.out, "(uint(clamp(")?; + write!(self.out, "(uint(round(clamp(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[0], 0.0, 1.0) * {scale}.0 + 0.5) | uint(clamp(")?; + write!(self.out, "[0], 0.0, 1.0) * {scale}.0)) | uint(round(clamp(")?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[1], 0.0, 1.0) * {scale}.0 + 0.5) << 8 | uint(clamp(" + "[1], 0.0, 1.0) * {scale}.0)) << 8 | uint(round(clamp(" )?; self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[2], 0.0, 1.0) * {scale}.0 + 0.5) << 16 | uint(clamp(" + "[2], 0.0, 1.0) * {scale}.0)) << 16 | uint(round(clamp(" )?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[3], 0.0, 1.0) * {scale}.0 + 0.5) << 24)")?; + write!(self.out, "[3], 0.0, 1.0) * {scale}.0)) << 24)")?; } Function::Unpack2x16float => { From ec2348aa0f93459d306bcfd1450c5463f933f80d Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 15 Jun 2023 17:39:54 -0400 Subject: [PATCH 16/21] update test --- tests/out/hlsl/bits.hlsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/out/hlsl/bits.hlsl b/tests/out/hlsl/bits.hlsl index f1b1ec6048..19d7ef0da6 100644 --- a/tests/out/hlsl/bits.hlsl +++ b/tests/out/hlsl/bits.hlsl @@ -24,13 +24,13 @@ void main() f2_ = (0.0).xx; f4_ = (0.0).xxxx; float4 _expr28 = f4_; - u = uint((int(floor(clamp(_expr28[0], -1.0, 1.0) * 127.0 + 0.5)) & 0xFF) | ((int(floor(clamp(_expr28[1], -1.0, 1.0) * 127.0 + 0.5)) & 0xFF) << 8) | ((int(floor(clamp(_expr28[2], -1.0, 1.0) * 127.0 + 0.5)) & 0xFF) << 16) | ((int(floor(clamp(_expr28[3], -1.0, 1.0) * 127.0 + 0.5)) & 0xFF) << 24)); + u = uint((int(round(clamp(_expr28[0], -1.0, 1.0) * 127.0)) & 0xFF) | ((int(round(clamp(_expr28[1], -1.0, 1.0) * 127.0)) & 0xFF) << 8) | ((int(round(clamp(_expr28[2], -1.0, 1.0) * 127.0)) & 0xFF) << 16) | ((int(round(clamp(_expr28[3], -1.0, 1.0) * 127.0)) & 0xFF) << 24)); float4 _expr30 = f4_; - u = (uint(clamp(_expr30[0], 0.0, 1.0) * 255.0 + 0.5) | uint(clamp(_expr30[1], 0.0, 1.0) * 255.0 + 0.5) << 8 | uint(clamp(_expr30[2], 0.0, 1.0) * 255.0 + 0.5) << 16 | uint(clamp(_expr30[3], 0.0, 1.0) * 255.0 + 0.5) << 24); + u = (uint(round(clamp(_expr30[0], 0.0, 1.0) * 255.0)) | uint(round(clamp(_expr30[1], 0.0, 1.0) * 255.0)) << 8 | uint(round(clamp(_expr30[2], 0.0, 1.0) * 255.0)) << 16 | uint(round(clamp(_expr30[3], 0.0, 1.0) * 255.0)) << 24); float2 _expr32 = f2_; - u = uint((int(floor(clamp(_expr32[0], -1.0, 1.0) * 32767.0 + 0.5))) & 0xFFFF) | (((int(floor(clamp(_expr32[1], -1.0, 1.0) * 32767.0 + 0.5)) & 0xFFFF) << 16)); + u = uint((int(round(clamp(_expr32[0], -1.0, 1.0) * 32767.0))) & 0xFFFF) | (((int(round(clamp(_expr32[1], -1.0, 1.0) * 32767.0)) & 0xFFFF) << 16)); float2 _expr34 = f2_; - u = uint(uint(float(clamp(_expr34[0], 0, 1) * 65535.0) + 0.5) | uint(float(clamp(_expr34[1], 0, 1) * 65535.0) + 0.5) << 16); + u = (uint(round(clamp(_expr34[0], 0.0, 1.0) * 65535.0)) | uint(round(clamp(_expr34[1], 0.0, 1.0) * 65535.0)) << 16); float2 _expr36 = f2_; u = f32tof16(_expr36[0]) | (f32tof16(_expr36[1]) << 16); uint _expr38 = u; From ff29d3274c9e1691e2799ebe4b767eb0811d1b19 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Tue, 20 Jun 2023 16:58:43 -0400 Subject: [PATCH 17/21] Fix brackets Co-authored-by: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> --- src/back/hlsl/writer.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index cdf9c4dbf3..feb1588b65 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2827,9 +2827,9 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { } } Function::Pack2x16float => { - write!(self.out, "f32tof16(")?; + write!(self.out, "(f32tof16(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "[0]) | (f32tof16(")?; + write!(self.out, "[0]) | f32tof16(")?; self.write_expr(module, arg, func_ctx)?; write!(self.out, "[1]) << 16)")?; } @@ -2840,7 +2840,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!( self.out, - "[0], -1.0, 1.0) * {scale}.0))) & 0xFFFF) | (((int(round(clamp(" + "[0], -1.0, 1.0) * {scale}.0)) & 0xFFFF) | ((int(round(clamp(" )?; self.write_expr(module, arg, func_ctx)?; write!(self.out, "[1], -1.0, 1.0) * {scale}.0)) & 0xFFFF) << 16))",)?; From e158ceec2869190ceb39fc9577a5fdf918b53745 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 22 Jun 2023 15:30:07 -0400 Subject: [PATCH 18/21] `need_bake_expressions` for `InsertBits` and `ExtractBits` --- src/back/hlsl/writer.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index feb1588b65..5964cf1129 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -121,7 +121,14 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.need_bake_expressions.insert(fun_handle); } - if let Expression::Math { fun, arg, .. } = *expr { + if let Expression::Math { + fun, + arg, + arg1, + arg2, + arg3, + } = *expr + { match fun { crate::MathFunction::Asinh | crate::MathFunction::Acosh @@ -131,7 +138,6 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { | crate::MathFunction::Unpack2x16unorm | crate::MathFunction::Unpack4x8snorm | crate::MathFunction::Unpack4x8unorm - // TODO: These use multiple args, unsure how to bake them | crate::MathFunction::Pack2x16float | crate::MathFunction::Pack2x16snorm | crate::MathFunction::Pack2x16unorm @@ -139,6 +145,17 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { | crate::MathFunction::Pack4x8unorm => { self.need_bake_expressions.insert(arg); } + crate::MathFunction::ExtractBits => { + self.need_bake_expressions.insert(arg); + self.need_bake_expressions.insert(arg1.unwrap()); + self.need_bake_expressions.insert(arg2.unwrap()); + } + crate::MathFunction::InsertBits => { + self.need_bake_expressions.insert(arg); + self.need_bake_expressions.insert(arg1.unwrap()); + self.need_bake_expressions.insert(arg2.unwrap()); + self.need_bake_expressions.insert(arg3.unwrap()); + } crate::MathFunction::CountLeadingZeros => { let inner = info[fun_handle].ty.inner_with(&module.types); if let Some(crate::ScalarKind::Sint) = inner.scalar_kind() { From 98b1183f2fb399989b3586eef32410a06dc12373 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 22 Jun 2023 15:39:23 -0400 Subject: [PATCH 19/21] use signed implementation for both signed and unsigned `ExtractBits` --- src/back/hlsl/writer.rs | 74 ++++++++++------------------------------- 1 file changed, 17 insertions(+), 57 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index 5964cf1129..da17e7b012 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2745,48 +2745,20 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { // count: u32 // T is u32 or i32 or vecN or vecN if let (Some(offset), Some(count)) = (arg1, arg2) { - let inner = func_ctx.info[expr].ty.inner_with(&module.types); - let scalar_kind = inner.scalar_kind(); - let scalar_width = inner.scalar_width().unwrap_or(32); - let scalar_max: u32 = match scalar_width { - 8 => 0xff, - 16 => 0xffff, - 32 => 0xffffffff, - _ => { - return Err(Error::Unimplemented(format!( - "write_expr_math extract_bits for scalar_width {}", - scalar_width - ))) - } - }; - - if let Some(ScalarKind::Uint) = scalar_kind { - // Unsigned - // ((e >> offset) & (count == 32u ? 0xffffffffu : ((1 << count) - 1))) - write!(self.out, "((")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> ")?; - self.write_expr(module, offset, func_ctx)?; - write!(self.out, ") & (")?; - self.write_expr(module, count, func_ctx)?; - write!(self.out, " == {scalar_width}u ? {scalar_max}u : ((1u << ")?; - self.write_expr(module, count, func_ctx)?; - write!(self.out, ") - 1)))")?; - } else { - // Signed - // (count == 0 ? 0 : (e << (32 - count - offset)) >> (32 - count)) - write!(self.out, "(")?; - self.write_expr(module, count, func_ctx)?; - write!(self.out, " == 0 ? 0 : (")?; - self.write_expr(module, arg, func_ctx)?; - write!(self.out, " << ({scalar_width} - ")?; - self.write_expr(module, count, func_ctx)?; - write!(self.out, " - ")?; - self.write_expr(module, offset, func_ctx)?; - write!(self.out, ")) >> ({scalar_width} - ")?; - self.write_expr(module, count, func_ctx)?; - write!(self.out, "))")?; - } + let scalar_width: u8 = 32; + // Works for signed and unsigned + // (count == 0 ? 0 : (e << (32 - count - offset)) >> (32 - count)) + write!(self.out, "(")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, " == 0 ? 0 : (")?; + self.write_expr(module, arg, func_ctx)?; + write!(self.out, " << ({scalar_width} - ")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, " - ")?; + self.write_expr(module, offset, func_ctx)?; + write!(self.out, ")) >> ({scalar_width} - ")?; + self.write_expr(module, count, func_ctx)?; + write!(self.out, "))")?; } } Function::InsertBits => { @@ -2797,22 +2769,10 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { // returns T // T is i32, u32, vecN, or vecN if let (Some(newbits), Some(offset), Some(count)) = (arg1, arg2, arg3) { - let inner = func_ctx.info[expr].ty.inner_with(&module.types); - let scalar_width = inner.scalar_width().unwrap_or(32); - let scalar_max: u64 = match scalar_width { - 8 => 0xff, - 16 => 0xffff, - 32 => 0xffffffff, - 64 => 0xffffffffffffffff, - _ => { - return Err(Error::Unimplemented(format!( - "write_expr_math insert_bits for scalar_width {}", - scalar_width - ))) - } - }; + let scalar_width: u8 = 32; + let scalar_max: u32 = 0xFFFFFFFF; // mask = ((0xFFFFFFFFu >> (32 - count)) << offset) - // return (count == 0 ? e : ((e & ~mask) | ((newbits << offset) & mask))) + // (count == 0 ? e : ((e & ~mask) | ((newbits << offset) & mask))) write!(self.out, "(")?; self.write_expr(module, count, func_ctx)?; write!(self.out, " == 0 ? ")?; From a45541926da1d6cd1df2b8976c4d1518400c6e2f Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 22 Jun 2023 15:42:14 -0400 Subject: [PATCH 20/21] remove some clamps on unpack functions Co-authored-by: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> --- src/back/hlsl/writer.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/back/hlsl/writer.rs b/src/back/hlsl/writer.rs index da17e7b012..7943d54954 100644 --- a/src/back/hlsl/writer.rs +++ b/src/back/hlsl/writer.rs @@ -2883,38 +2883,38 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Function::Unpack2x16snorm => { let scale = 32767; - write!(self.out, "clamp(float2(int2(")?; + write!(self.out, "(float2(int2(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "<< 16, ")?; + write!(self.out, " << 16, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 16) / {scale}.0, -1.0, 1.0)")?; + write!(self.out, ") >> 16) / {scale}.0)")?; } Function::Unpack2x16unorm => { let scale = 65535; - write!(self.out, "clamp(float2(float(")?; + write!(self.out, "(float2(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " & 0xFFFF), float(")?; + write!(self.out, " & 0xFFFF, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 16 & 0xFFFF)) / {scale}.0, 0.0, 1.0)")?; + write!(self.out, " >> 16) / {scale}.0)")?; } Function::Unpack4x8snorm => { let scale = 127; - write!(self.out, "clamp(float4((int4(")?; + write!(self.out, "(float4(int4(")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, "<< 24, ")?; + write!(self.out, " << 24, ")?; self.write_expr(module, arg, func_ctx)?; write!(self.out, " << 16, ")?; self.write_expr(module, arg, func_ctx)?; write!(self.out, " << 8, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, ") >> 24)) / {scale}.0, -1.0, 1.0)")?; + write!(self.out, ") >> 24) / {scale}.0)")?; } Function::Unpack4x8unorm => { let scale = 255; - write!(self.out, "clamp(float4(")?; + write!(self.out, "(float4(")?; self.write_expr(module, arg, func_ctx)?; write!(self.out, " & 0xFF, ")?; self.write_expr(module, arg, func_ctx)?; @@ -2922,7 +2922,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.write_expr(module, arg, func_ctx)?; write!(self.out, " >> 16 & 0xFF, ")?; self.write_expr(module, arg, func_ctx)?; - write!(self.out, " >> 24 & 0xFF) / {scale}.0, 0.0, 1.0)")?; + write!(self.out, " >> 24) / {scale}.0)")?; } Function::Regular(fun_name) => { write!(self.out, "{fun_name}(")?; From c4df873c82b34b7c44283090ed80b8303dbb5d20 Mon Sep 17 00:00:00 2001 From: Elabajaba Date: Thu, 22 Jun 2023 15:49:53 -0400 Subject: [PATCH 21/21] regenerate hlsl bits test --- tests/out/hlsl/bits.hlsl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/out/hlsl/bits.hlsl b/tests/out/hlsl/bits.hlsl index 19d7ef0da6..425738067c 100644 --- a/tests/out/hlsl/bits.hlsl +++ b/tests/out/hlsl/bits.hlsl @@ -28,19 +28,19 @@ void main() float4 _expr30 = f4_; u = (uint(round(clamp(_expr30[0], 0.0, 1.0) * 255.0)) | uint(round(clamp(_expr30[1], 0.0, 1.0) * 255.0)) << 8 | uint(round(clamp(_expr30[2], 0.0, 1.0) * 255.0)) << 16 | uint(round(clamp(_expr30[3], 0.0, 1.0) * 255.0)) << 24); float2 _expr32 = f2_; - u = uint((int(round(clamp(_expr32[0], -1.0, 1.0) * 32767.0))) & 0xFFFF) | (((int(round(clamp(_expr32[1], -1.0, 1.0) * 32767.0)) & 0xFFFF) << 16)); + u = uint((int(round(clamp(_expr32[0], -1.0, 1.0) * 32767.0)) & 0xFFFF) | ((int(round(clamp(_expr32[1], -1.0, 1.0) * 32767.0)) & 0xFFFF) << 16)); float2 _expr34 = f2_; u = (uint(round(clamp(_expr34[0], 0.0, 1.0) * 65535.0)) | uint(round(clamp(_expr34[1], 0.0, 1.0) * 65535.0)) << 16); float2 _expr36 = f2_; - u = f32tof16(_expr36[0]) | (f32tof16(_expr36[1]) << 16); + u = (f32tof16(_expr36[0]) | f32tof16(_expr36[1]) << 16); uint _expr38 = u; - f4_ = clamp(float4((int4(_expr38<< 24, _expr38 << 16, _expr38 << 8, _expr38) >> 24)) / 127.0, -1.0, 1.0); + f4_ = (float4(int4(_expr38 << 24, _expr38 << 16, _expr38 << 8, _expr38) >> 24) / 127.0); uint _expr40 = u; - f4_ = clamp(float4(_expr40 & 0xFF, _expr40 >> 8 & 0xFF, _expr40 >> 16 & 0xFF, _expr40 >> 24 & 0xFF) / 255.0, 0.0, 1.0); + f4_ = (float4(_expr40 & 0xFF, _expr40 >> 8 & 0xFF, _expr40 >> 16 & 0xFF, _expr40 >> 24) / 255.0); uint _expr42 = u; - f2_ = clamp(float2(int2(_expr42<< 16, _expr42) >> 16) / 32767.0, -1.0, 1.0); + f2_ = (float2(int2(_expr42 << 16, _expr42) >> 16) / 32767.0); uint _expr44 = u; - f2_ = clamp(float2(float(_expr44 & 0xFFFF), float(_expr44 >> 16 & 0xFFFF)) / 65535.0, 0.0, 1.0); + f2_ = (float2(_expr44 & 0xFFFF, _expr44 >> 16) / 65535.0); uint _expr46 = u; f2_ = float2(f16tof32(_expr46), f16tof32((_expr46) >> 16)); int _expr48 = i; @@ -76,13 +76,13 @@ void main() int4 _expr100 = i4_; i4_ = (10u == 0 ? 0 : (_expr100 << (32 - 10u - 5u)) >> (32 - 10u)); uint _expr104 = u; - u = ((_expr104 >> 5u) & (10u == 32u ? 4294967295u : ((1u << 10u) - 1))); + u = (10u == 0 ? 0 : (_expr104 << (32 - 10u - 5u)) >> (32 - 10u)); uint2 _expr108 = u2_; - u2_ = ((_expr108 >> 5u) & (10u == 32u ? 4294967295u : ((1u << 10u) - 1))); + u2_ = (10u == 0 ? 0 : (_expr108 << (32 - 10u - 5u)) >> (32 - 10u)); uint3 _expr112 = u3_; - u3_ = ((_expr112 >> 5u) & (10u == 32u ? 4294967295u : ((1u << 10u) - 1))); + u3_ = (10u == 0 ? 0 : (_expr112 << (32 - 10u - 5u)) >> (32 - 10u)); uint4 _expr116 = u4_; - u4_ = ((_expr116 >> 5u) & (10u == 32u ? 4294967295u : ((1u << 10u) - 1))); + u4_ = (10u == 0 ? 0 : (_expr116 << (32 - 10u - 5u)) >> (32 - 10u)); int _expr120 = i; i = asint(firstbitlow(_expr120)); uint2 _expr122 = u2_;