Skip to content

Commit 9c06280

Browse files
cwfitzgeraldFL33TW00DErichDonGubler
committed
Implement F16 Support
Co-authored-by: FL33TW00D <[email protected]> Co-authored-by: ErichDonGubler <[email protected]>
1 parent 473dd2f commit 9c06280

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+3746
-926
lines changed

Cargo.lock

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ flume = "0.11"
100100
futures-lite = "2"
101101
getrandom = "0.2"
102102
glam = "0.29"
103+
# TODO: Use `half` directly again after <https://github.com/starkat99/half-rs/pull/111> is released upstream.
104+
half = { package = "half-2", version = "2.4.1" }
103105
hashbrown = { version = "0.14.5", default-features = false, features = [
104106
"ahash",
105107
"inline-more",

naga/Cargo.toml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,17 @@ msl-out = []
4141
## If you want to enable MSL output it regardless of the target platform, use `naga/msl-out`.
4242
msl-out-if-target-apple = []
4343

44-
serialize = ["dep:serde", "bitflags/serde", "hashbrown/serde", "indexmap/serde"]
44+
serialize = [
45+
"dep:serde",
46+
"bitflags/serde",
47+
"half/serde",
48+
"hashbrown/serde",
49+
"indexmap/serde",
50+
]
4551
deserialize = [
4652
"dep:serde",
4753
"bitflags/serde",
54+
"half/serde",
4855
"hashbrown/serde",
4956
"indexmap/serde",
5057
]
@@ -84,9 +91,11 @@ termcolor = { version = "1.4.1" }
8491
# https://github.com/brendanzab/codespan/commit/e99c867339a877731437e7ee6a903a3d03b5439e
8592
codespan-reporting = { version = "0.11.0" }
8693
hashbrown.workspace = true
94+
half = { workspace = true, features = ["arbitrary", "num-traits"] }
8795
rustc-hash.workspace = true
8896
indexmap.workspace = true
8997
log = "0.4"
98+
num-traits = "0.2"
9099
strum = { workspace = true, optional = true }
91100
spirv = { version = "0.3", optional = true }
92101
thiserror.workspace = true

naga/src/back/glsl/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2669,6 +2669,9 @@ impl<'a, W: Write> Writer<'a, W> {
26692669
// decimal part even it's zero which is needed for a valid glsl float constant
26702670
crate::Literal::F64(value) => write!(self.out, "{value:?}LF")?,
26712671
crate::Literal::F32(value) => write!(self.out, "{value:?}")?,
2672+
crate::Literal::F16(_) => {
2673+
return Err(Error::Custom("GLSL has no 16-bit float type".into()));
2674+
}
26722675
// Unsigned integers need a `u` at the end
26732676
//
26742677
// While `core` doesn't necessarily need it, it's allowed and since `es` needs it we

naga/src/back/hlsl/writer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,6 +2634,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
26342634
// decimal part even it's zero
26352635
crate::Literal::F64(value) => write!(self.out, "{value:?}L")?,
26362636
crate::Literal::F32(value) => write!(self.out, "{value:?}")?,
2637+
crate::Literal::F16(value) => write!(self.out, "{value:?}h")?,
26372638
crate::Literal::U32(value) => write!(self.out, "{value}u")?,
26382639
// HLSL has no suffix for explicit i32 literals, but not using any suffix
26392640
// makes the type ambiguous which prevents overload resolution from

naga/src/back/msl/writer.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::{
55
proc::{self, index, ExpressionKindTracker, NameKey, TypeResolution},
66
valid, FastHashMap, FastHashSet,
77
};
8+
use half::f16;
9+
use num_traits::real::Real;
810
#[cfg(test)]
911
use std::ptr;
1012
use std::{
@@ -174,9 +176,11 @@ impl Display for TypeContext<'_> {
174176
write!(out, "{}::atomic_{}", NAMESPACE, scalar.to_msl_name())
175177
}
176178
crate::TypeInner::Vector { size, scalar } => put_numeric_type(out, scalar, &[size]),
177-
crate::TypeInner::Matrix { columns, rows, .. } => {
178-
put_numeric_type(out, crate::Scalar::F32, &[rows, columns])
179-
}
179+
crate::TypeInner::Matrix {
180+
columns,
181+
rows,
182+
scalar,
183+
} => put_numeric_type(out, scalar, &[rows, columns]),
180184
crate::TypeInner::Pointer { base, space } => {
181185
let sub = Self {
182186
handle: base,
@@ -413,8 +417,12 @@ impl crate::Scalar {
413417
match self {
414418
Self {
415419
kind: Sk::Float,
416-
width: _,
420+
width: 4,
417421
} => "float",
422+
Self {
423+
kind: Sk::Float,
424+
width: 2,
425+
} => "half",
418426
Self {
419427
kind: Sk::Sint,
420428
width: 4,
@@ -471,7 +479,7 @@ fn should_pack_struct_member(
471479
match *ty_inner {
472480
crate::TypeInner::Vector {
473481
size: crate::VectorSize::Tri,
474-
scalar: scalar @ crate::Scalar { width: 4, .. },
482+
scalar: scalar @ crate::Scalar { width: 4 | 2, .. },
475483
} if is_tight => Some(scalar),
476484
_ => None,
477485
}
@@ -1446,6 +1454,21 @@ impl<W: Write> Writer<W> {
14461454
crate::Literal::F64(_) => {
14471455
return Err(Error::CapabilityNotSupported(valid::Capabilities::FLOAT64))
14481456
}
1457+
crate::Literal::F16(value) => {
1458+
if value.is_infinite() {
1459+
let sign = if value.is_sign_negative() { "-" } else { "" };
1460+
write!(self.out, "{sign}INFINITY")?;
1461+
} else if value.is_nan() {
1462+
write!(self.out, "NAN")?;
1463+
} else {
1464+
let suffix = if value.fract() == f16::from_f32(0.0) {
1465+
".0h"
1466+
} else {
1467+
"h"
1468+
};
1469+
write!(self.out, "{value}{suffix}")?;
1470+
}
1471+
}
14491472
crate::Literal::F32(value) => {
14501473
if value.is_infinite() {
14511474
let sign = if value.is_sign_negative() { "-" } else { "" };

0 commit comments

Comments
 (0)