Skip to content

Commit

Permalink
Add 1-component ({s,u}{int,norm}{8,16}, float16) and `unorm8x4-bg…
Browse files Browse the repository at this point in the history
…ra` vertex formats (#6632)

* feat: add missing 8/16-bit vertex formats (and 8-bit bgra) #6614

* add tests for 1-component vertex formats (and bgra)

* metal: unpacking function for 1-component vertex formats

* test: use proper alignment for float16 vertex format

* changelog: new vertex formats
  • Loading branch information
nolanderc authored Dec 16, 2024
1 parent bcc9626 commit 21ff968
Show file tree
Hide file tree
Showing 13 changed files with 439 additions and 78 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ By @ErichDonGubler in [#6456](https://github.com/gfx-rs/wgpu/pull/6456), [#6148]
- Implement `quantizeToF16()` for WGSL frontend, and WGSL, SPIR-V, HLSL, MSL, and GLSL backends. By @jamienicol in [#6519](https://github.com/gfx-rs/wgpu/pull/6519).
- Add support for GLSL `usampler*` and `isampler*`. By @DavidPeicho in [#6513](https://github.com/gfx-rs/wgpu/pull/6513).
- Expose Ray Query flags as constants in WGSL. Implement candidate intersections. By @kvark in [#5429](https://github.com/gfx-rs/wgpu/pull/5429)
- Add new vertex formats (`{U,S}{int,norm}{8,16}`, `Float16` and `Unorm8x4Bgra`). By @nolanderc in [#6632](https://github.com/gfx-rs/wgpu/pull/6632)
- Allow for override-expressions in `workgroup_size`. By @KentSlaney in [#6635](https://github.com/gfx-rs/wgpu/pull/6635).
- Add support for OpAtomicCompareExchange in SPIR-V frontend. By @schell in [#6590](https://github.com/gfx-rs/wgpu/pull/6590).
- Implement type inference for abstract arguments to user-defined functions. By @jamienicol in [#6577](https://github.com/gfx-rs/wgpu/pull/6577).
Expand Down
88 changes: 53 additions & 35 deletions naga/src/back/msl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,72 +238,90 @@ impl Default for Options {
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
pub enum VertexFormat {
/// One unsigned byte (u8). `u32` in shaders.
Uint8 = 0,
/// Two unsigned bytes (u8). `vec2<u32>` in shaders.
Uint8x2 = 0,
Uint8x2 = 1,
/// Four unsigned bytes (u8). `vec4<u32>` in shaders.
Uint8x4 = 1,
Uint8x4 = 2,
/// One signed byte (i8). `i32` in shaders.
Sint8 = 3,
/// Two signed bytes (i8). `vec2<i32>` in shaders.
Sint8x2 = 2,
Sint8x2 = 4,
/// Four signed bytes (i8). `vec4<i32>` in shaders.
Sint8x4 = 3,
Sint8x4 = 5,
/// One unsigned byte (u8). [0, 255] converted to float [0, 1] `f32` in shaders.
Unorm8 = 6,
/// Two unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec2<f32>` in shaders.
Unorm8x2 = 4,
Unorm8x2 = 7,
/// Four unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec4<f32>` in shaders.
Unorm8x4 = 5,
Unorm8x4 = 8,
/// One signed byte (i8). [-127, 127] converted to float [-1, 1] `f32` in shaders.
Snorm8 = 9,
/// Two signed bytes (i8). [-127, 127] converted to float [-1, 1] `vec2<f32>` in shaders.
Snorm8x2 = 6,
Snorm8x2 = 10,
/// Four signed bytes (i8). [-127, 127] converted to float [-1, 1] `vec4<f32>` in shaders.
Snorm8x4 = 7,
Snorm8x4 = 11,
/// One unsigned short (u16). `u32` in shaders.
Uint16 = 12,
/// Two unsigned shorts (u16). `vec2<u32>` in shaders.
Uint16x2 = 8,
Uint16x2 = 13,
/// Four unsigned shorts (u16). `vec4<u32>` in shaders.
Uint16x4 = 9,
Uint16x4 = 14,
/// One signed short (u16). `i32` in shaders.
Sint16 = 15,
/// Two signed shorts (i16). `vec2<i32>` in shaders.
Sint16x2 = 10,
Sint16x2 = 16,
/// Four signed shorts (i16). `vec4<i32>` in shaders.
Sint16x4 = 11,
Sint16x4 = 17,
/// One unsigned short (u16). [0, 65535] converted to float [0, 1] `f32` in shaders.
Unorm16 = 18,
/// Two unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec2<f32>` in shaders.
Unorm16x2 = 12,
Unorm16x2 = 19,
/// Four unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec4<f32>` in shaders.
Unorm16x4 = 13,
Unorm16x4 = 20,
/// One signed short (i16). [-32767, 32767] converted to float [-1, 1] `f32` in shaders.
Snorm16 = 21,
/// Two signed shorts (i16). [-32767, 32767] converted to float [-1, 1] `vec2<f32>` in shaders.
Snorm16x2 = 14,
Snorm16x2 = 22,
/// Four signed shorts (i16). [-32767, 32767] converted to float [-1, 1] `vec4<f32>` in shaders.
Snorm16x4 = 15,
Snorm16x4 = 23,
/// One half-precision float (no Rust equiv). `f32` in shaders.
Float16 = 24,
/// Two half-precision floats (no Rust equiv). `vec2<f32>` in shaders.
Float16x2 = 16,
Float16x2 = 25,
/// Four half-precision floats (no Rust equiv). `vec4<f32>` in shaders.
Float16x4 = 17,
Float16x4 = 26,
/// One single-precision float (f32). `f32` in shaders.
Float32 = 18,
Float32 = 27,
/// Two single-precision floats (f32). `vec2<f32>` in shaders.
Float32x2 = 19,
Float32x2 = 28,
/// Three single-precision floats (f32). `vec3<f32>` in shaders.
Float32x3 = 20,
Float32x3 = 29,
/// Four single-precision floats (f32). `vec4<f32>` in shaders.
Float32x4 = 21,
Float32x4 = 30,
/// One unsigned int (u32). `u32` in shaders.
Uint32 = 22,
Uint32 = 31,
/// Two unsigned ints (u32). `vec2<u32>` in shaders.
Uint32x2 = 23,
Uint32x2 = 32,
/// Three unsigned ints (u32). `vec3<u32>` in shaders.
Uint32x3 = 24,
Uint32x3 = 33,
/// Four unsigned ints (u32). `vec4<u32>` in shaders.
Uint32x4 = 25,
Uint32x4 = 34,
/// One signed int (i32). `i32` in shaders.
Sint32 = 26,
Sint32 = 35,
/// Two signed ints (i32). `vec2<i32>` in shaders.
Sint32x2 = 27,
Sint32x2 = 36,
/// Three signed ints (i32). `vec3<i32>` in shaders.
Sint32x3 = 28,
Sint32x3 = 37,
/// Four signed ints (i32). `vec4<i32>` in shaders.
Sint32x4 = 29,
Sint32x4 = 38,
/// Three unsigned 10-bit integers and one 2-bit integer, packed into a 32-bit integer (u32). [0, 1024] converted to float [0, 1] `vec4<f32>` in shaders.
#[cfg_attr(
any(feature = "serialize", feature = "deserialize"),
serde(rename = "unorm10-10-10-2")
)]
Unorm10_10_10_2 = 34,
#[cfg_attr(feature = "serde", serde(rename = "unorm10-10-10-2"))]
Unorm10_10_10_2 = 43,
/// Four unsigned 8-bit integers, packed into a 32-bit integer (u32). [0, 255] converted to float [0, 1] `vec4<f32>` in shaders.
#[cfg_attr(feature = "serde", serde(rename = "unorm8x4-bgra"))]
Unorm8x4Bgra = 44,
}

/// A mapping of vertex buffers and their attributes to shader
Expand Down
131 changes: 131 additions & 0 deletions naga/src/back/msl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4014,6 +4014,13 @@ template <typename A>
) -> Result<(String, u32, u32), Error> {
use back::msl::VertexFormat::*;
match format {
Uint8 => {
let name = self.namer.call("unpackUint8");
writeln!(self.out, "uint {name}(metal::uchar b0) {{")?;
writeln!(self.out, "{}return uint(b0);", back::INDENT)?;
writeln!(self.out, "}}")?;
Ok((name, 1, 1))
}
Uint8x2 => {
let name = self.namer.call("unpackUint8x2");
writeln!(
Expand Down Expand Up @@ -4042,6 +4049,13 @@ template <typename A>
writeln!(self.out, "}}")?;
Ok((name, 4, 4))
}
Sint8 => {
let name = self.namer.call("unpackSint8");
writeln!(self.out, "int {name}(metal::uchar b0) {{")?;
writeln!(self.out, "{}return int(as_type<char>(b0));", back::INDENT)?;
writeln!(self.out, "}}")?;
Ok((name, 1, 1))
}
Sint8x2 => {
let name = self.namer.call("unpackSint8x2");
writeln!(
Expand Down Expand Up @@ -4078,6 +4092,17 @@ template <typename A>
writeln!(self.out, "}}")?;
Ok((name, 4, 4))
}
Unorm8 => {
let name = self.namer.call("unpackUnorm8");
writeln!(self.out, "float {name}(metal::uchar b0) {{")?;
writeln!(
self.out,
"{}return float(float(b0) / 255.0f);",
back::INDENT
)?;
writeln!(self.out, "}}")?;
Ok((name, 1, 1))
}
Unorm8x2 => {
let name = self.namer.call("unpackUnorm8x2");
writeln!(
Expand Down Expand Up @@ -4114,6 +4139,17 @@ template <typename A>
writeln!(self.out, "}}")?;
Ok((name, 4, 4))
}
Snorm8 => {
let name = self.namer.call("unpackSnorm8");
writeln!(self.out, "float {name}(metal::uchar b0) {{")?;
writeln!(
self.out,
"{}return float(metal::max(-1.0f, as_type<char>(b0) / 127.0f));",
back::INDENT
)?;
writeln!(self.out, "}}")?;
Ok((name, 1, 1))
}
Snorm8x2 => {
let name = self.namer.call("unpackSnorm8x2");
writeln!(
Expand Down Expand Up @@ -4150,6 +4186,21 @@ template <typename A>
writeln!(self.out, "}}")?;
Ok((name, 4, 4))
}
Uint16 => {
let name = self.namer.call("unpackUint16");
writeln!(
self.out,
"metal::uint {name}(metal::uint b0, \
metal::uint b1) {{"
)?;
writeln!(
self.out,
"{}return metal::uint(b1 << 8 | b0);",
back::INDENT
)?;
writeln!(self.out, "}}")?;
Ok((name, 2, 1))
}
Uint16x2 => {
let name = self.namer.call("unpackUint16x2");
writeln!(
Expand Down Expand Up @@ -4192,6 +4243,21 @@ template <typename A>
writeln!(self.out, "}}")?;
Ok((name, 8, 4))
}
Sint16 => {
let name = self.namer.call("unpackSint16");
writeln!(
self.out,
"int {name}(metal::ushort b0, \
metal::ushort b1) {{"
)?;
writeln!(
self.out,
"{}return int(as_type<short>(metal::ushort(b1 << 8 | b0)));",
back::INDENT
)?;
writeln!(self.out, "}}")?;
Ok((name, 2, 1))
}
Sint16x2 => {
let name = self.namer.call("unpackSint16x2");
writeln!(
Expand Down Expand Up @@ -4234,6 +4300,21 @@ template <typename A>
writeln!(self.out, "}}")?;
Ok((name, 8, 4))
}
Unorm16 => {
let name = self.namer.call("unpackUnorm16");
writeln!(
self.out,
"float {name}(metal::ushort b0, \
metal::ushort b1) {{"
)?;
writeln!(
self.out,
"{}return float(float(b1 << 8 | b0) / 65535.0f);",
back::INDENT
)?;
writeln!(self.out, "}}")?;
Ok((name, 2, 1))
}
Unorm16x2 => {
let name = self.namer.call("unpackUnorm16x2");
writeln!(
Expand Down Expand Up @@ -4276,6 +4357,21 @@ template <typename A>
writeln!(self.out, "}}")?;
Ok((name, 8, 4))
}
Snorm16 => {
let name = self.namer.call("unpackSnorm16");
writeln!(
self.out,
"float {name}(metal::ushort b0, \
metal::ushort b1) {{"
)?;
writeln!(
self.out,
"{}return metal::unpack_snorm2x16_to_float(b1 << 8 | b0).x;",
back::INDENT
)?;
writeln!(self.out, "}}")?;
Ok((name, 2, 1))
}
Snorm16x2 => {
let name = self.namer.call("unpackSnorm16x2");
writeln!(
Expand Down Expand Up @@ -4315,6 +4411,21 @@ template <typename A>
writeln!(self.out, "}}")?;
Ok((name, 8, 4))
}
Float16 => {
let name = self.namer.call("unpackFloat16");
writeln!(
self.out,
"float {name}(metal::ushort b0, \
metal::ushort b1) {{"
)?;
writeln!(
self.out,
"{}return float(as_type<half>(metal::ushort(b1 << 8 | b0)));",
back::INDENT
)?;
writeln!(self.out, "}}")?;
Ok((name, 2, 1))
}
Float16x2 => {
let name = self.namer.call("unpackFloat16x2");
writeln!(
Expand Down Expand Up @@ -4679,6 +4790,26 @@ template <typename A>
writeln!(self.out, "}}")?;
Ok((name, 4, 4))
}
Unorm8x4Bgra => {
let name = self.namer.call("unpackUnorm8x4Bgra");
writeln!(
self.out,
"metal::float4 {name}(metal::uchar b0, \
metal::uchar b1, \
metal::uchar b2, \
metal::uchar b3) {{"
)?;
writeln!(
self.out,
"{}return metal::float4(float(b2) / 255.0f, \
float(b1) / 255.0f, \
float(b0) / 255.0f, \
float(b3) / 255.0f);",
back::INDENT
)?;
writeln!(self.out, "}}")?;
Ok((name, 4, 4))
}
}
}

Expand Down
Loading

0 comments on commit 21ff968

Please sign in to comment.