Skip to content

Commit c628679

Browse files
FL33TW00DcwfitzgeraldErichDonGubler
authored
feat: implement F16 support in shaders (#5701)
Co-authored-by: FL33TW00D <[email protected]> Co-authored-by: Connor Fitzgerald <[email protected]> Co-authored-by: ErichDonGubler <[email protected]>
1 parent b912232 commit c628679

Some content is hidden

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

62 files changed

+3741
-996
lines changed

Cargo.lock

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ fern = "0.7"
108108
flume = "0.11"
109109
futures-lite = "2"
110110
glam = "0.29"
111+
half = "2.5" # We require 2.5 to have `Arbitrary` support.
111112
hashbrown = { version = "0.14.5", default-features = false, features = [
112113
"ahash",
113114
"inline-more",

naga/Cargo.toml

+11-1
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,12 @@ 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+
# `half` requires 0.2.16 for `FromBytes` and `ToBytes`.
99+
num-traits = "0.2.16"
90100
strum = { workspace = true, optional = true }
91101
spirv = { version = "0.3", optional = true }
92102
thiserror.workspace = true

naga/src/back/glsl/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2703,6 +2703,9 @@ impl<'a, W: Write> Writer<'a, W> {
27032703
// decimal part even it's zero which is needed for a valid glsl float constant
27042704
crate::Literal::F64(value) => write!(self.out, "{value:?}LF")?,
27052705
crate::Literal::F32(value) => write!(self.out, "{value:?}")?,
2706+
crate::Literal::F16(_) => {
2707+
return Err(Error::Custom("GLSL has no 16-bit float type".into()));
2708+
}
27062709
// Unsigned integers need a `u` at the end
27072710
//
27082711
// While `core` doesn't necessarily need it, it's allowed and since `es` needs it we

naga/src/back/hlsl/writer.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2628,6 +2628,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
26282628
// decimal part even it's zero
26292629
crate::Literal::F64(value) => write!(self.out, "{value:?}L")?,
26302630
crate::Literal::F32(value) => write!(self.out, "{value:?}")?,
2631+
crate::Literal::F16(value) => write!(self.out, "{value:?}h")?,
26312632
crate::Literal::U32(value) => write!(self.out, "{value}u")?,
26322633
// HLSL has no suffix for explicit i32 literals, but not using any suffix
26332634
// makes the type ambiguous which prevents overload resolution from

naga/src/back/msl/writer.rs

+29-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ use core::{
88
fmt::{Display, Error as FmtError, Formatter, Write},
99
iter,
1010
};
11+
use num_traits::real::Real as _;
12+
13+
use half::f16;
1114

1215
use super::{sampler as sm, Error, LocationMode, Options, PipelineOptions, TranslationInfo};
1316
use crate::{
@@ -182,9 +185,11 @@ impl Display for TypeContext<'_> {
182185
write!(out, "{}::atomic_{}", NAMESPACE, scalar.to_msl_name())
183186
}
184187
crate::TypeInner::Vector { size, scalar } => put_numeric_type(out, scalar, &[size]),
185-
crate::TypeInner::Matrix { columns, rows, .. } => {
186-
put_numeric_type(out, crate::Scalar::F32, &[rows, columns])
187-
}
188+
crate::TypeInner::Matrix {
189+
columns,
190+
rows,
191+
scalar,
192+
} => put_numeric_type(out, scalar, &[rows, columns]),
188193
crate::TypeInner::Pointer { base, space } => {
189194
let sub = Self {
190195
handle: base,
@@ -425,8 +430,12 @@ impl crate::Scalar {
425430
match self {
426431
Self {
427432
kind: Sk::Float,
428-
width: _,
433+
width: 4,
429434
} => "float",
435+
Self {
436+
kind: Sk::Float,
437+
width: 2,
438+
} => "half",
430439
Self {
431440
kind: Sk::Sint,
432441
width: 4,
@@ -483,7 +492,7 @@ fn should_pack_struct_member(
483492
match *ty_inner {
484493
crate::TypeInner::Vector {
485494
size: crate::VectorSize::Tri,
486-
scalar: scalar @ crate::Scalar { width: 4, .. },
495+
scalar: scalar @ crate::Scalar { width: 4 | 2, .. },
487496
} if is_tight => Some(scalar),
488497
_ => None,
489498
}
@@ -1459,6 +1468,21 @@ impl<W: Write> Writer<W> {
14591468
crate::Literal::F64(_) => {
14601469
return Err(Error::CapabilityNotSupported(valid::Capabilities::FLOAT64))
14611470
}
1471+
crate::Literal::F16(value) => {
1472+
if value.is_infinite() {
1473+
let sign = if value.is_sign_negative() { "-" } else { "" };
1474+
write!(self.out, "{sign}INFINITY")?;
1475+
} else if value.is_nan() {
1476+
write!(self.out, "NAN")?;
1477+
} else {
1478+
let suffix = if value.fract() == f16::from_f32(0.0) {
1479+
".0h"
1480+
} else {
1481+
"h"
1482+
};
1483+
write!(self.out, "{value}{suffix}")?;
1484+
}
1485+
}
14621486
crate::Literal::F32(value) => {
14631487
if value.is_infinite() {
14641488
let sign = if value.is_sign_negative() { "-" } else { "" };

0 commit comments

Comments
 (0)