Skip to content

Commit 00456cf

Browse files
VlaDexateoxoy
authored andcommitted
Add parsing support for un/pack4xI/U8
1 parent 66d7387 commit 00456cf

File tree

19 files changed

+1129
-551
lines changed

19 files changed

+1129
-551
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ By @stefnotch in [#5410](https://github.com/gfx-rs/wgpu/pull/5410)
6868

6969
#### Naga
7070

71+
- Implement `WGSL`'s `unpack4xI8`,`unpack4xU8`,`pack4xI8` and `pack4xU8`. By @VlaDexa in [#5424](https://github.com/gfx-rs/wgpu/pull/5424)
72+
7173
### Changes
7274

7375
#### General

naga/src/back/glsl/mod.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ use crate::{
5353
use features::FeaturesManager;
5454
use std::{
5555
cmp::Ordering,
56-
fmt,
57-
fmt::{Error as FmtError, Write},
56+
fmt::{self, Error as FmtError, Write},
5857
mem,
5958
};
6059
use thiserror::Error;
@@ -1318,6 +1317,12 @@ impl<'a, W: Write> Writer<'a, W> {
13181317
}
13191318
}
13201319
}
1320+
crate::MathFunction::Pack4xI8
1321+
| crate::MathFunction::Pack4xU8
1322+
| crate::MathFunction::Unpack4xI8
1323+
| crate::MathFunction::Unpack4xU8 => {
1324+
self.need_bake_expressions.insert(arg);
1325+
}
13211326
crate::MathFunction::ExtractBits => {
13221327
// Only argument 1 is re-used.
13231328
self.need_bake_expressions.insert(arg1.unwrap());
@@ -3582,12 +3587,66 @@ impl<'a, W: Write> Writer<'a, W> {
35823587
Mf::Pack2x16snorm => "packSnorm2x16",
35833588
Mf::Pack2x16unorm => "packUnorm2x16",
35843589
Mf::Pack2x16float => "packHalf2x16",
3590+
fun @ (Mf::Pack4xI8 | Mf::Pack4xU8) => {
3591+
let was_signed = match fun {
3592+
Mf::Pack4xI8 => true,
3593+
Mf::Pack4xU8 => false,
3594+
_ => unreachable!(),
3595+
};
3596+
let const_suffix = if was_signed { "" } else { "u" };
3597+
if was_signed {
3598+
write!(self.out, "uint(")?;
3599+
}
3600+
write!(self.out, "(")?;
3601+
self.write_expr(arg, ctx)?;
3602+
write!(self.out, "[0] & 0xFF{const_suffix}) | ((")?;
3603+
self.write_expr(arg, ctx)?;
3604+
write!(self.out, "[1] & 0xFF{const_suffix}) << 8) | ((")?;
3605+
self.write_expr(arg, ctx)?;
3606+
write!(self.out, "[2] & 0xFF{const_suffix}) << 16) | ((")?;
3607+
self.write_expr(arg, ctx)?;
3608+
write!(self.out, "[3] & 0xFF{const_suffix}) << 24)")?;
3609+
if was_signed {
3610+
write!(self.out, ")")?;
3611+
}
3612+
3613+
return Ok(());
3614+
}
35853615
// data unpacking
35863616
Mf::Unpack4x8snorm => "unpackSnorm4x8",
35873617
Mf::Unpack4x8unorm => "unpackUnorm4x8",
35883618
Mf::Unpack2x16snorm => "unpackSnorm2x16",
35893619
Mf::Unpack2x16unorm => "unpackUnorm2x16",
35903620
Mf::Unpack2x16float => "unpackHalf2x16",
3621+
fun @ (Mf::Unpack4xI8 | Mf::Unpack4xU8) => {
3622+
let sign_prefix = match fun {
3623+
Mf::Unpack4xI8 => 'i',
3624+
Mf::Unpack4xU8 => 'u',
3625+
_ => unreachable!(),
3626+
};
3627+
write!(self.out, "{sign_prefix}vec4(")?;
3628+
for i in 0..4 {
3629+
write!(self.out, "bitfieldExtract(")?;
3630+
// Since bitfieldExtract only sign extends if the value is signed, this
3631+
// cast is needed
3632+
match fun {
3633+
Mf::Unpack4xI8 => {
3634+
write!(self.out, "int(")?;
3635+
self.write_expr(arg, ctx)?;
3636+
write!(self.out, ")")?;
3637+
}
3638+
Mf::Unpack4xU8 => self.write_expr(arg, ctx)?,
3639+
_ => unreachable!(),
3640+
};
3641+
write!(self.out, ", {}, 8)", i * 8)?;
3642+
if i != 3 {
3643+
write!(self.out, ", ")?;
3644+
}
3645+
}
3646+
write!(self.out, ")")?;
3647+
3648+
return Ok(());
3649+
}
35913650
};
35923651

35933652
let extract_bits = fun == Mf::ExtractBits;

naga/src/back/hlsl/writer.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,15 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
153153
| crate::MathFunction::Unpack2x16unorm
154154
| crate::MathFunction::Unpack4x8snorm
155155
| crate::MathFunction::Unpack4x8unorm
156+
| crate::MathFunction::Unpack4xI8
157+
| crate::MathFunction::Unpack4xU8
156158
| crate::MathFunction::Pack2x16float
157159
| crate::MathFunction::Pack2x16snorm
158160
| crate::MathFunction::Pack2x16unorm
159161
| crate::MathFunction::Pack4x8snorm
160-
| crate::MathFunction::Pack4x8unorm => {
162+
| crate::MathFunction::Pack4x8unorm
163+
| crate::MathFunction::Pack4xI8
164+
| crate::MathFunction::Pack4xU8 => {
161165
self.need_bake_expressions.insert(arg);
162166
}
163167
crate::MathFunction::CountLeadingZeros => {
@@ -2838,11 +2842,15 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
28382842
Pack2x16unorm,
28392843
Pack4x8snorm,
28402844
Pack4x8unorm,
2845+
Pack4xI8,
2846+
Pack4xU8,
28412847
Unpack2x16float,
28422848
Unpack2x16snorm,
28432849
Unpack2x16unorm,
28442850
Unpack4x8snorm,
28452851
Unpack4x8unorm,
2852+
Unpack4xI8,
2853+
Unpack4xU8,
28462854
Regular(&'static str),
28472855
MissingIntOverload(&'static str),
28482856
MissingIntReturnType(&'static str),
@@ -2924,12 +2932,16 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
29242932
Mf::Pack2x16unorm => Function::Pack2x16unorm,
29252933
Mf::Pack4x8snorm => Function::Pack4x8snorm,
29262934
Mf::Pack4x8unorm => Function::Pack4x8unorm,
2935+
Mf::Pack4xI8 => Function::Pack4xI8,
2936+
Mf::Pack4xU8 => Function::Pack4xU8,
29272937
// Data Unpacking
29282938
Mf::Unpack2x16float => Function::Unpack2x16float,
29292939
Mf::Unpack2x16snorm => Function::Unpack2x16snorm,
29302940
Mf::Unpack2x16unorm => Function::Unpack2x16unorm,
29312941
Mf::Unpack4x8snorm => Function::Unpack4x8snorm,
29322942
Mf::Unpack4x8unorm => Function::Unpack4x8unorm,
2943+
Mf::Unpack4xI8 => Function::Unpack4xI8,
2944+
Mf::Unpack4xU8 => Function::Unpack4xU8,
29332945
_ => return Err(Error::Unimplemented(format!("write_expr_math {fun:?}"))),
29342946
};
29352947

@@ -3022,6 +3034,24 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
30223034
self.write_expr(module, arg, func_ctx)?;
30233035
write!(self.out, "[3], 0.0, 1.0) * {scale}.0)) << 24)")?;
30243036
}
3037+
fun @ (Function::Pack4xI8 | Function::Pack4xU8) => {
3038+
let was_signed = matches!(fun, Function::Pack4xI8);
3039+
if was_signed {
3040+
write!(self.out, "uint(")?;
3041+
}
3042+
write!(self.out, "(")?;
3043+
self.write_expr(module, arg, func_ctx)?;
3044+
write!(self.out, "[0] & 0xFF) | ((")?;
3045+
self.write_expr(module, arg, func_ctx)?;
3046+
write!(self.out, "[1] & 0xFF) << 8) | ((")?;
3047+
self.write_expr(module, arg, func_ctx)?;
3048+
write!(self.out, "[2] & 0xFF) << 16) | ((")?;
3049+
self.write_expr(module, arg, func_ctx)?;
3050+
write!(self.out, "[3] & 0xFF) << 24)")?;
3051+
if was_signed {
3052+
write!(self.out, ")")?;
3053+
}
3054+
}
30253055

30263056
Function::Unpack2x16float => {
30273057
write!(self.out, "float2(f16tof32(")?;
@@ -3074,6 +3104,20 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
30743104
self.write_expr(module, arg, func_ctx)?;
30753105
write!(self.out, " >> 24) / {scale}.0)")?;
30763106
}
3107+
fun @ (Function::Unpack4xI8 | Function::Unpack4xU8) => {
3108+
if matches!(fun, Function::Unpack4xU8) {
3109+
write!(self.out, "u")?;
3110+
}
3111+
write!(self.out, "int4(")?;
3112+
self.write_expr(module, arg, func_ctx)?;
3113+
write!(self.out, ", ")?;
3114+
self.write_expr(module, arg, func_ctx)?;
3115+
write!(self.out, " >> 8, ")?;
3116+
self.write_expr(module, arg, func_ctx)?;
3117+
write!(self.out, " >> 16, ")?;
3118+
self.write_expr(module, arg, func_ctx)?;
3119+
write!(self.out, " >> 24) << 24 >> 24")?;
3120+
}
30773121
Function::Regular(fun_name) => {
30783122
write!(self.out, "{fun_name}(")?;
30793123
self.write_expr(module, arg, func_ctx)?;

naga/src/back/msl/writer.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1828,12 +1828,16 @@ impl<W: Write> Writer<W> {
18281828
Mf::Pack2x16snorm => "pack_float_to_snorm2x16",
18291829
Mf::Pack2x16unorm => "pack_float_to_unorm2x16",
18301830
Mf::Pack2x16float => "",
1831+
Mf::Pack4xI8 => "",
1832+
Mf::Pack4xU8 => "",
18311833
// data unpacking
18321834
Mf::Unpack4x8snorm => "unpack_snorm4x8_to_float",
18331835
Mf::Unpack4x8unorm => "unpack_unorm4x8_to_float",
18341836
Mf::Unpack2x16snorm => "unpack_snorm2x16_to_float",
18351837
Mf::Unpack2x16unorm => "unpack_unorm2x16_to_float",
18361838
Mf::Unpack2x16float => "",
1839+
Mf::Unpack4xI8 => "",
1840+
Mf::Unpack4xU8 => "",
18371841
};
18381842

18391843
match fun {
@@ -1985,6 +1989,38 @@ impl<W: Write> Writer<W> {
19851989
write!(self.out, "{fun_name}")?;
19861990
self.put_call_parameters(iter::once(arg), context)?;
19871991
}
1992+
fun @ (Mf::Pack4xI8 | Mf::Pack4xU8) => {
1993+
let was_signed = fun == Mf::Pack4xI8;
1994+
if was_signed {
1995+
write!(self.out, "uint(")?;
1996+
}
1997+
write!(self.out, "(")?;
1998+
self.put_expression(arg, context, true)?;
1999+
write!(self.out, "[0] & 0xFF) | ((")?;
2000+
self.put_expression(arg, context, true)?;
2001+
write!(self.out, "[1] & 0xFF) << 8) | ((")?;
2002+
self.put_expression(arg, context, true)?;
2003+
write!(self.out, "[2] & 0xFF) << 16) | ((")?;
2004+
self.put_expression(arg, context, true)?;
2005+
write!(self.out, "[3] & 0xFF) << 24)")?;
2006+
if was_signed {
2007+
write!(self.out, ")")?;
2008+
}
2009+
}
2010+
fun @ (Mf::Unpack4xI8 | Mf::Unpack4xU8) => {
2011+
if matches!(fun, Mf::Unpack4xU8) {
2012+
write!(self.out, "u")?;
2013+
}
2014+
write!(self.out, "int4(")?;
2015+
self.put_expression(arg, context, true)?;
2016+
write!(self.out, ", ")?;
2017+
self.put_expression(arg, context, true)?;
2018+
write!(self.out, " >> 8, ")?;
2019+
self.put_expression(arg, context, true)?;
2020+
write!(self.out, " >> 16, ")?;
2021+
self.put_expression(arg, context, true)?;
2022+
write!(self.out, " >> 24) << 24 >> 24")?;
2023+
}
19882024
_ => {
19892025
write!(self.out, "{NAMESPACE}::{fun_name}")?;
19902026
self.put_call_parameters(
@@ -2611,7 +2647,11 @@ impl<W: Write> Writer<W> {
26112647
}
26122648
}
26132649
}
2614-
crate::MathFunction::FindMsb => {
2650+
crate::MathFunction::FindMsb
2651+
| crate::MathFunction::Pack4xI8
2652+
| crate::MathFunction::Pack4xU8
2653+
| crate::MathFunction::Unpack4xI8
2654+
| crate::MathFunction::Unpack4xU8 => {
26152655
self.need_bake_expressions.insert(arg);
26162656
}
26172657
crate::MathFunction::ExtractBits => {

0 commit comments

Comments
 (0)