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 1-component ({s,u}{int,norm}{8,16}, float16) and unorm8x4-bgra vertex formats #6632

Open
wants to merge 5 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -114,6 +114,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 @@ -234,72 +234,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,
Comment on lines -296 to +320
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: @gfx-rs/naga: This code has a 5-slot gap for texture indices here. Is there a reason that this gap should continue to exist, given these changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed the gap in the previous code corresponded to the missing Float64 formats. I suppose having the enum discriminant values be a 1:1 mapping between those in wpgu_types and msl could be yield more efficient conversions between the two, or similar, so I just left it as is.

}

/// 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 @@ -4010,6 +4010,13 @@ template <typename A>
) -> Result<(String, u32, u32), Error> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: @gfx-rs/naga: Why do we not re-use the output of wgpu_core::VertexFormat::size here? 🤔 I feel like it should be the same in all cases, but I admittedly haven't analyzed for divergences.

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 @@ -4038,6 +4045,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 @@ -4074,6 +4088,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 @@ -4110,6 +4135,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 @@ -4146,6 +4182,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 @@ -4188,6 +4239,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 @@ -4230,6 +4296,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 @@ -4272,6 +4353,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 @@ -4311,6 +4407,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 @@ -4675,6 +4786,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
Loading