Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add shader I64 and U64 support #5154

Merged
merged 52 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
b9d62be
Add shader i64 and u64 support
atlv24 Jan 27, 2024
f6cc003
Merge branch 'trunk' into i64
atlv24 Jan 28, 2024
f6a1e67
Fix writer
atlv24 Jan 28, 2024
4e4fcaf
Merge branch 'i64' of github.com:rodolphito/wgpu into i64
atlv24 Jan 28, 2024
fc9e721
Fixed test output
atlv24 Jan 28, 2024
b1826e2
Merge branch 'trunk' into i64
atlv24 Jan 28, 2024
cb52ee7
Merge branch 'trunk' into i64
atlv24 Feb 13, 2024
dfc88ac
Fix HLSL uint64_t support and add tests
atlv24 Feb 17, 2024
00bbd5d
Merge branch 'trunk' into i64
atlv24 Feb 17, 2024
9eb24e4
Require SM_6_0
atlv24 Feb 17, 2024
8511f2b
Comments
atlv24 Feb 17, 2024
3efae60
Rename SHADER_I64 to SHADER_INT64
atlv24 Feb 17, 2024
73e34f8
Fix hlsl codegen
atlv24 Feb 19, 2024
1710779
Merge branch 'trunk' into i64
atlv24 Feb 19, 2024
37f3193
Various tweaks, commented out struct test cus something is wrong with it
atlv24 Feb 19, 2024
133afa7
Rename naga test, remove unused error variant, fix tests
atlv24 Feb 19, 2024
50c24c3
remove useless glsl entry in ron
atlv24 Feb 19, 2024
3358041
Merge branch 'trunk' into i64
atlv24 Feb 19, 2024
d23686f
Improve i64 Tests
cwfitzgerald Feb 19, 2024
2c421d4
Add validation test
atlv24 Feb 19, 2024
5c0c152
Cleanup
atlv24 Feb 20, 2024
b3e5103
Metal working
cwfitzgerald Feb 20, 2024
f2535b1
Add tests for math functions
cwfitzgerald Feb 20, 2024
14bdfd3
Clarify arguments
cwfitzgerald Feb 20, 2024
e9b9dc6
Fix SPV OpBitcast long issue
atlv24 Feb 20, 2024
b5f9da1
fix var name
atlv24 Feb 20, 2024
2a77976
Add polyfills for spirv
atlv24 Feb 20, 2024
75cdada
Add polyfill tests and fix polyfill a bit. Also remove nonsensical sc…
atlv24 Feb 20, 2024
6732b46
temper expectations
atlv24 Feb 20, 2024
00b765e
Fixes
atlv24 Feb 20, 2024
2c75864
Add more tests
atlv24 Feb 20, 2024
520b586
Test spirv capabilities
cwfitzgerald Feb 20, 2024
45d5985
Validate out 64 bit int instructions #5276
atlv24 Feb 21, 2024
085b420
Fix tests
atlv24 Feb 21, 2024
8b29c6b
unused import
atlv24 Feb 21, 2024
07e2796
Merge branch 'trunk' into i64
atlv24 Feb 21, 2024
5031011
Merge branch 'trunk' into i64
atlv24 Feb 21, 2024
d3e8802
Merge branch 'trunk' into i64
atlv24 Feb 21, 2024
6577d8d
Merge branch 'trunk' into i64
atlv24 Feb 24, 2024
153d467
Merge branch 'trunk' into i64
atlv24 Feb 26, 2024
a67a210
Merge branch 'trunk' into i64
atlv24 Feb 26, 2024
35537d2
Regen spvasm
atlv24 Feb 27, 2024
803b47d
Merge branch 'trunk' into i64
atlv24 Feb 27, 2024
d030e4d
Update CHANGELOG.md
cwfitzgerald Feb 27, 2024
67a04ae
Merge branch 'trunk' into i64
atlv24 Mar 6, 2024
6cddc92
Remove dysfunctional polyfills
atlv24 Mar 6, 2024
2bbca7a
Add clippy ignore
atlv24 Mar 6, 2024
2570ad1
Validate out 64bit CountTrailingZeros
atlv24 Mar 9, 2024
9cf17d1
Merge branch 'trunk' into i64
atlv24 Mar 9, 2024
f089363
Comment out countTrailingZeros in int64.wgsl
atlv24 Mar 9, 2024
3ce7233
Merge branch 'trunk' into i64
atlv24 Mar 9, 2024
363e5ec
Merge branch 'trunk' into i64
atlv24 Mar 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ Bottom level categories:
- As with other instance flags, this flag can be changed in calls to `InstanceFlags::with_env` with the new `WGPU_GPU_BASED_VALIDATION` environment variable.

By @ErichDonGubler in [#5146](https://github.com/gfx-rs/wgpu/pull/5146), [#5046](https://github.com/gfx-rs/wgpu/pull/5046).
- Signed and unsigned 64 bit integer support in shaders. By @rodolphito in [#5154](https://github.com/gfx-rs/wgpu/pull/5154)
cwfitzgerald marked this conversation as resolved.
Show resolved Hide resolved
- `wgpu::Instance` can now report which `wgpu::Backends` are available based on the build configuration. By @wumpf [#5167](https://github.com/gfx-rs/wgpu/pull/5167)
```diff
-wgpu::Instance::any_backend_feature_enabled()
Expand Down
3 changes: 3 additions & 0 deletions naga/src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2441,6 +2441,9 @@ impl<'a, W: Write> Writer<'a, W> {
crate::Literal::I64(_) => {
return Err(Error::Custom("GLSL has no 64-bit integer type".into()));
}
crate::Literal::U64(_) => {
return Err(Error::Custom("GLSL has no 64-bit integer type".into()));
}
crate::Literal::AbstractInt(_) | crate::Literal::AbstractFloat(_) => {
return Err(Error::Custom(
"Abstract types should not appear in IR presented to backends".into(),
Expand Down
12 changes: 10 additions & 2 deletions naga/src/back/hlsl/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,16 @@ impl crate::Scalar {
/// <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-scalar>
pub(super) const fn to_hlsl_str(self) -> Result<&'static str, Error> {
match self.kind {
crate::ScalarKind::Sint => Ok("int"),
crate::ScalarKind::Uint => Ok("uint"),
crate::ScalarKind::Sint => match self.width {
4 => Ok("int"),
8 => Ok("int64_t"),
_ => Err(Error::UnsupportedScalar(self)),
},
crate::ScalarKind::Uint => match self.width {
4 => Ok("uint"),
8 => Ok("uint64_t"),
_ => Err(Error::UnsupportedScalar(self)),
},
crate::ScalarKind::Float => match self.width {
2 => Ok("half"),
4 => Ok("float"),
Expand Down
6 changes: 6 additions & 0 deletions naga/src/back/hlsl/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ pub const RESERVED: &[&str] = &[
"inout",
"InputPatch",
"int",
"int16_t",
"int32_t",
"int64_t",
"interface",
"line",
"lineadj",
Expand Down Expand Up @@ -130,6 +133,9 @@ pub const RESERVED: &[&str] = &[
"triangleadj",
"TriangleStream",
"uint",
"uint16_t",
"uint32_t",
"uint64_t",
"uniform",
"unorm",
"unsigned",
Expand Down
1 change: 1 addition & 0 deletions naga/src/back/hlsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2038,6 +2038,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
crate::Literal::F32(value) => write!(self.out, "{value:?}")?,
crate::Literal::U32(value) => write!(self.out, "{}u", value)?,
crate::Literal::I32(value) => write!(self.out, "{}", value)?,
crate::Literal::U64(value) => write!(self.out, "{}uL", value)?,
crate::Literal::I64(value) => write!(self.out, "{}L", value)?,
crate::Literal::Bool(value) => write!(self.out, "{}", value)?,
crate::Literal::AbstractInt(_) | crate::Literal::AbstractFloat(_) => {
Expand Down
3 changes: 3 additions & 0 deletions naga/src/back/msl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,9 @@ impl<W: Write> Writer<W> {
crate::Literal::I32(value) => {
write!(self.out, "{value}")?;
}
crate::Literal::U64(value) => {
write!(self.out, "{value}uL")?;
}
crate::Literal::I64(value) => {
write!(self.out, "{value}L")?;
}
Expand Down
3 changes: 3 additions & 0 deletions naga/src/back/spv/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,9 @@ impl Writer {
crate::Literal::F32(value) => Instruction::constant_32bit(type_id, id, value.to_bits()),
crate::Literal::U32(value) => Instruction::constant_32bit(type_id, id, value),
crate::Literal::I32(value) => Instruction::constant_32bit(type_id, id, value as u32),
crate::Literal::U64(value) => {
Instruction::constant_64bit(type_id, id, value as u32, (value >> 32) as u32)
}
crate::Literal::I64(value) => {
Instruction::constant_64bit(type_id, id, value as u32, (value >> 32) as u32)
}
Expand Down
22 changes: 19 additions & 3 deletions naga/src/back/wgsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1095,16 +1095,24 @@ impl<W: Write> Writer<W> {
// value can only be expressed in WGSL using AbstractInt and
// a unary negation operator.
if value == i32::MIN {
write!(self.out, "i32(-2147483648)")?;
write!(self.out, "i32({})", value)?;
} else {
write!(self.out, "{}i", value)?;
}
}
crate::Literal::Bool(value) => write!(self.out, "{}", value)?,
crate::Literal::F64(value) => write!(self.out, "{:?}lf", value)?,
crate::Literal::I64(_) => {
return Err(Error::Custom("unsupported i64 literal".to_string()));
crate::Literal::I64(value) => {
// `-9223372036854775808li` is not valid WGSL. The most negative `i64`
// value can only be expressed in WGSL using AbstractInt and
// a unary negation operator.
if value == i64::MIN {
write!(self.out, "i64({})", value)?;
} else {
write!(self.out, "{}li", value)?;
}
}
crate::Literal::U64(value) => write!(self.out, "{:?}lu", value)?,
crate::Literal::AbstractInt(_) | crate::Literal::AbstractFloat(_) => {
return Err(Error::Custom(
"Abstract types should not appear in IR presented to backends".into(),
Expand Down Expand Up @@ -1827,6 +1835,14 @@ const fn scalar_kind_str(scalar: crate::Scalar) -> &'static str {
kind: Sk::Uint,
width: 4,
} => "u32",
Scalar {
kind: Sk::Sint,
width: 8,
} => "i64",
Scalar {
kind: Sk::Uint,
width: 8,
} => "u64",
Scalar {
kind: Sk::Bool,
width: 1,
Expand Down
5 changes: 5 additions & 0 deletions naga/src/front/spv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4876,6 +4876,11 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
let low = self.next()?;
match width {
4 => crate::Literal::U32(low),
8 => {
inst.expect(5)?;
atlv24 marked this conversation as resolved.
Show resolved Hide resolved
let high = self.next()?;
crate::Literal::U64(u64::from(high) << 32 | u64::from(low))
}
_ => return Err(Error::InvalidTypeWidth(width as u32)),
}
}
Expand Down
2 changes: 2 additions & 0 deletions naga/src/front/wgsl/lower/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1530,6 +1530,8 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
ast::Literal::Number(Number::F32(f)) => crate::Literal::F32(f),
ast::Literal::Number(Number::I32(i)) => crate::Literal::I32(i),
ast::Literal::Number(Number::U32(u)) => crate::Literal::U32(u),
ast::Literal::Number(Number::I64(i)) => crate::Literal::I64(i),
ast::Literal::Number(Number::U64(u)) => crate::Literal::U64(u),
ast::Literal::Number(Number::F64(f)) => crate::Literal::F64(f),
ast::Literal::Number(Number::AbstractInt(i)) => crate::Literal::AbstractInt(i),
ast::Literal::Number(Number::AbstractFloat(f)) => {
Expand Down
8 changes: 8 additions & 0 deletions naga/src/front/wgsl/parse/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ pub fn get_scalar_type(word: &str) -> Option<Scalar> {
kind: Sk::Uint,
width: 4,
}),
"i64" => Some(Scalar {
kind: Sk::Sint,
width: 8,
}),
"u64" => Some(Scalar {
kind: Sk::Uint,
width: 8,
}),
"bool" => Some(Scalar {
kind: Sk::Bool,
width: crate::BOOL_WIDTH,
Expand Down
16 changes: 16 additions & 0 deletions naga/src/front/wgsl/parse/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ pub enum Number {
I32(i32),
/// Concrete u32
U32(u32),
/// Concrete i64
I64(i64),
/// Concrete u64
U64(u64),
/// Concrete f32
F32(f32),
/// Concrete f64
Expand All @@ -31,6 +35,8 @@ enum Kind {
enum IntKind {
I32,
U32,
I64,
U64,
}

#[derive(Debug)]
Expand Down Expand Up @@ -270,6 +276,8 @@ fn parse(input: &str) -> (Result<Number, NumberError>, &str) {
let kind = consume_map!(bytes, [
b'i' => Kind::Int(IntKind::I32),
b'u' => Kind::Int(IntKind::U32),
b'l', b'i' => Kind::Int(IntKind::I64),
b'l', b'u' => Kind::Int(IntKind::U64),
b'h' => Kind::Float(FloatKind::F16),
b'f' => Kind::Float(FloatKind::F32),
b'l', b'f' => Kind::Float(FloatKind::F64),
Expand Down Expand Up @@ -416,5 +424,13 @@ fn parse_int(input: &str, kind: Option<IntKind>, radix: u32) -> Result<Number, N
Ok(num) => Ok(Number::U32(num)),
Err(e) => Err(map_err(e)),
},
Some(IntKind::I64) => match i64::from_str_radix(input, radix) {
Ok(num) => Ok(Number::I64(num)),
Err(e) => Err(map_err(e)),
},
Some(IntKind::U64) => match u64::from_str_radix(input, radix) {
Ok(num) => Ok(Number::U64(num)),
Err(e) => Err(map_err(e)),
},
}
}
1 change: 1 addition & 0 deletions naga/src/front/wgsl/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ fn parse_comment() {
#[test]
fn parse_types() {
parse_str("const a : i32 = 2;").unwrap();
parse_str("const a : u64 = 2lu;").unwrap();
assert!(parse_str("const a : x32 = 2;").is_err());
parse_str("var t: texture_2d<f32>;").unwrap();
parse_str("var t: texture_cube_array<i32>;").unwrap();
Expand Down
2 changes: 2 additions & 0 deletions naga/src/keywords/wgsl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub const RESERVED: &[&str] = &[
"f32",
"f16",
"i32",
"i64",
"mat2x2",
"mat2x3",
"mat2x4",
Expand Down Expand Up @@ -43,6 +44,7 @@ pub const RESERVED: &[&str] = &[
"texture_depth_cube_array",
"texture_depth_multisampled_2d",
"u32",
"u64",
"vec2",
"vec3",
"vec4",
Expand Down
1 change: 1 addition & 0 deletions naga/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,7 @@ pub enum Literal {
F32(f32),
U32(u32),
I32(i32),
U64(u64),
I64(i64),
Bool(bool),
AbstractInt(i64),
Expand Down
62 changes: 58 additions & 4 deletions naga/src/proc/constant_evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ gen_component_wise_extractor! {
AbstractInt => AbstractInt: i64,
U32 => U32: u32,
I32 => I32: i32,
U64 => U64: u64,
I64 => I64: i64,
],
scalar_kinds: [
Float,
Expand Down Expand Up @@ -847,6 +849,8 @@ impl<'a> ConstantEvaluator<'a> {
Scalar::AbstractInt([e]) => Ok(Scalar::AbstractInt([e.abs()])),
Scalar::I32([e]) => Ok(Scalar::I32([e.wrapping_abs()])),
Scalar::U32([e]) => Ok(Scalar::U32([e])), // TODO: just re-use the expression, ezpz
Scalar::I64([e]) => Ok(Scalar::I64([e.wrapping_abs()])),
Scalar::U64([e]) => Ok(Scalar::U64([e])),
})
}
crate::MathFunction::Min => {
Expand Down Expand Up @@ -1280,7 +1284,7 @@ impl<'a> ConstantEvaluator<'a> {
Literal::U32(v) => v as i32,
Literal::F32(v) => v as i32,
Literal::Bool(v) => v as i32,
Literal::F64(_) | Literal::I64(_) => {
Literal::F64(_) | Literal::I64(_) | Literal::U64(_) => {
return make_error();
}
Literal::AbstractInt(v) => i32::try_from_abstract(v)?,
Expand All @@ -1291,18 +1295,40 @@ impl<'a> ConstantEvaluator<'a> {
Literal::U32(v) => v,
Literal::F32(v) => v as u32,
Literal::Bool(v) => v as u32,
Literal::F64(_) | Literal::I64(_) => {
Literal::F64(_) | Literal::I64(_) | Literal::U64(_) => {
return make_error();
}
Literal::AbstractInt(v) => u32::try_from_abstract(v)?,
Literal::AbstractFloat(v) => u32::try_from_abstract(v)?,
}),
Sc::I64 => Literal::I64(match literal {
Literal::I32(v) => v as i64,
Literal::U32(v) => v as i64,
Literal::F32(v) => v as i64,
Literal::Bool(v) => v as i64,
Literal::F64(v) => v as i64,
Literal::I64(v) => v,
Literal::U64(v) => v as i64,
Literal::AbstractInt(v) => i64::try_from_abstract(v)?,
Literal::AbstractFloat(v) => i64::try_from_abstract(v)?,
}),
Sc::U64 => Literal::U64(match literal {
Literal::I32(v) => v as u64,
Literal::U32(v) => v as u64,
Literal::F32(v) => v as u64,
Literal::Bool(v) => v as u64,
Literal::F64(v) => v as u64,
Literal::I64(v) => v as u64,
Literal::U64(v) => v,
Literal::AbstractInt(v) => u64::try_from_abstract(v)?,
Literal::AbstractFloat(v) => u64::try_from_abstract(v)?,
}),
Sc::F32 => Literal::F32(match literal {
Literal::I32(v) => v as f32,
Literal::U32(v) => v as f32,
Literal::F32(v) => v,
Literal::Bool(v) => v as u32 as f32,
Literal::F64(_) | Literal::I64(_) => {
Literal::F64(_) | Literal::I64(_) | Literal::U64(_) => {
return make_error();
}
Literal::AbstractInt(v) => f32::try_from_abstract(v)?,
Expand All @@ -1314,7 +1340,7 @@ impl<'a> ConstantEvaluator<'a> {
Literal::F32(v) => v as f64,
Literal::F64(v) => v,
Literal::Bool(v) => v as u32 as f64,
Literal::I64(_) => return make_error(),
Literal::I64(_) | Literal::U64(_) => return make_error(),
Literal::AbstractInt(v) => f64::try_from_abstract(v)?,
Literal::AbstractFloat(v) => f64::try_from_abstract(v)?,
}),
Expand All @@ -1325,6 +1351,7 @@ impl<'a> ConstantEvaluator<'a> {
Literal::Bool(v) => v,
Literal::F64(_)
| Literal::I64(_)
| Literal::U64(_)
| Literal::AbstractInt(_)
| Literal::AbstractFloat(_) => {
return make_error();
Expand Down Expand Up @@ -2423,6 +2450,21 @@ impl TryFromAbstract<i64> for u32 {
}
}

impl TryFromAbstract<i64> for u64 {
fn try_from_abstract(value: i64) -> Result<u64, ConstantEvaluatorError> {
u64::try_from(value).map_err(|_| ConstantEvaluatorError::AutomaticConversionLossy {
value: format!("{value:?}"),
to_type: "u64",
})
}
}

impl TryFromAbstract<i64> for i64 {
fn try_from_abstract(value: i64) -> Result<i64, ConstantEvaluatorError> {
Ok(value)
}
}

impl TryFromAbstract<i64> for f32 {
fn try_from_abstract(value: i64) -> Result<Self, ConstantEvaluatorError> {
let f = value as f32;
Expand Down Expand Up @@ -2473,3 +2515,15 @@ impl TryFromAbstract<f64> for u32 {
Err(ConstantEvaluatorError::AutomaticConversionFloatToInt { to_type: "u32" })
}
}

impl TryFromAbstract<f64> for i64 {
fn try_from_abstract(_: f64) -> Result<Self, ConstantEvaluatorError> {
Err(ConstantEvaluatorError::AutomaticConversionFloatToInt { to_type: "i64" })
}
}

impl TryFromAbstract<f64> for u64 {
fn try_from_abstract(_: f64) -> Result<Self, ConstantEvaluatorError> {
Err(ConstantEvaluatorError::AutomaticConversionFloatToInt { to_type: "u64" })
}
}
Loading
Loading